我正在尝试使用ServiceStack IoC为HangFire编写一个JobActivator,但在从类型解析时遇到了问题。我相信对于那些有更多泛型经验的人来说,这将是一个简单的答案。
我传入的容器来自HostContext.Container
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
}
}
}发布于 2015-04-21 22:58:07
虽然Funq是一个带有泛型API的类型化IOC,但您可以添加一个helper扩展方法来支持使用运行时类型解析实例,例如:
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;
}
}这将允许您使用运行时类型解析已注册的依赖项,例如:
var container = new Container();
container.Register(c => new Foo());
var instance = container.TryResolve(typeof(Foo));发布于 2015-04-21 22:24:21
我建议使用不同的IoC框架,因为Funq不支持接受Type参数的resolve方法,即它没有方法
object Container.Resolve(Type theType);因此,与Hangfire的结合是困难的,因为Hangfire不提供重载,您可以将其用作:
virtual T ActivateJob<T>() where T : class如果你坚持使用Funq,这可以像这样(低效地)解决:
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>();
}
}发布于 2015-04-21 22:03:52
我认为您希望获得一个T并返回一个T
public T ActivateJob<T>() where T : class
{
return _container.Resolve<T>();
}https://stackoverflow.com/questions/29774352
复制相似问题