首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用ServiceStack Funq IoC解析类型

如何使用ServiceStack Funq IoC解析类型
EN

Stack Overflow用户
提问于 2015-04-21 21:57:05
回答 3查看 2.1K关注 0票数 2

我正在尝试使用ServiceStack IoC为HangFire编写一个JobActivator,但在从类型解析时遇到了问题。我相信对于那些有更多泛型经验的人来说,这将是一个简单的答案。

我传入的容器来自HostContext.Container

代码语言:javascript
复制
using Hangfire;
using System;
using System.Collections.Generic;
using System.Linq;
using ServiceStack;

namespace Common.Hangfire
{

    public class FunqJobActivator : JobActivator
    {

        private Funq.Container _container;

        public FunqJobActivator(Funq.Container container)
        {
            if (container == null)
            {
                throw new ArgumentNullException("container");
            }
            _container = container;
        }

        public override object ActivateJob(Type type)
        {
            return _container.Resolve<type>();  //** this doesn't compile
        }
    }
}
EN

回答 3

Stack Overflow用户

发布于 2015-04-21 22:58:07

虽然Funq是一个带有泛型API的类型化IOC,但您可以添加一个helper扩展方法来支持使用运行时类型解析实例,例如:

代码语言:javascript
复制
public static class ContainerExtensions
{
    public static object TryResolve(this Container container, Type type)
    {
        var mi = typeof(Container).GetMethods(BindingFlags.Public | BindingFlags.Instance)
            .First(x => x.Name == "TryResolve" &&
                   x.GetGenericArguments().Length == 1 &&
                   x.GetParameters().Length == 0);

        var genericMi = mi.MakeGenericMethod(type);
        var instance = genericMi.Invoke(container, new object[0]);
        return instance;
    }
}

这将允许您使用运行时类型解析已注册的依赖项,例如:

代码语言:javascript
复制
var container = new Container();
container.Register(c => new Foo());

var instance = container.TryResolve(typeof(Foo));
票数 3
EN

Stack Overflow用户

发布于 2015-04-21 22:24:21

我建议使用不同的IoC框架,因为Funq不支持接受Type参数的resolve方法,即它没有方法

代码语言:javascript
复制
object Container.Resolve(Type theType);

因此,与Hangfire的结合是困难的,因为Hangfire不提供重载,您可以将其用作:

代码语言:javascript
复制
virtual T ActivateJob<T>() where T : class

如果你坚持使用Funq,这可以像这样(低效地)解决:

代码语言:javascript
复制
public class FunqJobActivator : JobActivator
{
    private const BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
    private static readonly _activateMethod = 
        typeof(FunqJobActivator).GetMethod("InternalActivateJob", flags);

    private Funq.Container _container;

    public FunqJobActivator(Funq.Container container)
    {
        if (container == null)
        {
            throw new ArgumentNullException("container");
        }
        _container = container;
    }

    public override object ActivateJob(Type type)
    {
        // this will allow calling InternalActivateJob<T> with typeof(T) == type.
        var method = _activateMethod.MakeGenericMethod(new [] { type });
        return method.Invoke(this, null);
    }

    private object InternalActivateJob<T>() where T : class
    {
        return _container.Resolve<T>();
    }
}
票数 2
EN

Stack Overflow用户

发布于 2015-04-21 22:03:52

我认为您希望获得一个T并返回一个T

代码语言:javascript
复制
public T ActivateJob<T>() where T : class
{
    return _container.Resolve<T>();  
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29774352

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档