[英]How to resolve type using ServiceStack Funq IoC
我正在嘗試使用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
}
}
}
雖然Funq是具有通用API的類型化IOC,但是您可以添加一個輔助程序擴展方法,以啟用使用運行時類型的實例解析,例如:
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));
我建議使用其他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>();
}
}
我認為您想獲得T
並返回T
public T ActivateJob<T>() where T : class
{
return _container.Resolve<T>();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.