是否可以让 Unity 按需将依赖对象注入父对象,而不是在父对象初始化时?
问问题
901 次
2 回答
1
是的,让 Unity 注入 aLazy<T>
而不是 a T
。这是关于该主题的一篇文章:http ://www.tomdupont.net/2012/07/lazy-unity-injection.html
于 2013-08-22T10:20:47.907 回答
0
Lazy<T>
如果您真的需要“随需应变”,这并没有真正的帮助。Lazy<T>
只有在您需要延迟解决时才真正起作用。但是在最初的解决之后,可以有相同的参考。
我通过使用 Castle.DynamicProxy 解决了这个问题。我需要“按需”注入某些依赖项,这意味着它们需要在使用时解决(每次都新解析),而不是在“依赖项”构建时解决。
为此,我像这样配置我的容器:
private void UnityRegister(IUnityContainer container)
{
container.RegisterType<HttpContextBase>(new OnDemandInjectionFactory<HttpContextBase>(c => new HttpContextWrapper(HttpContext.Current)));
container.RegisterType<HttpRequestBase>(new OnDemandInjectionFactory<HttpRequestBase>(c => new HttpRequestWrapper(HttpContext.Current.Request)));
container.RegisterType<HttpSessionStateBase>(new OnDemandInjectionFactory<HttpSessionStateBase>(c => new HttpSessionStateWrapper(HttpContext.Current.Session)));
container.RegisterType<HttpServerUtilityBase>(new OnDemandInjectionFactory<HttpServerUtilityBase>(c => new HttpServerUtilityWrapper(HttpContext.Current.Server)));
}
我的想法是我提供了一种“按需”检索实例的方法。每当使用实例的任何方法时都会调用 lambda。Dependent 对象实际上持有对代理对象的引用,而不是对象本身。
OnDemandInjectionFactory:
internal class OnDemandInjectionFactory<T> : InjectionFactory
{
public OnDemandInjectionFactory(Func<IUnityContainer, T> proxiedObjectFactory) : base((container, type, name) => FactoryFunction(container, type, name, proxiedObjectFactory))
{
}
private static object FactoryFunction(IUnityContainer container, Type type, string name, Func<IUnityContainer, T> proxiedObjectFactory)
{
var interceptor = new OnDemandInterceptor<T>(container, proxiedObjectFactory);
var proxyGenerator = new ProxyGenerator();
var proxy = proxyGenerator.CreateClassProxy(type, interceptor);
return proxy;
}
}
按需拦截器:
internal class OnDemandInterceptor<T> : IInterceptor
{
private readonly Func<IUnityContainer, T> _proxiedInstanceFactory;
private readonly IUnityContainer _container;
public OnDemandInterceptor(IUnityContainer container, Func<IUnityContainer, T> proxiedInstanceFactory)
{
_proxiedInstanceFactory = proxiedInstanceFactory;
_container = container;
}
public void Intercept(IInvocation invocation)
{
var proxiedInstance = _proxiedInstanceFactory.Invoke(_container);
var types = invocation.Arguments.Select(arg => arg.GetType()).ToArray();
var method = typeof(T).GetMethod(invocation.Method.Name, types);
invocation.ReturnValue = method.Invoke(proxiedInstance, invocation.Arguments);
}
}
于 2015-03-31T14:32:15.317 回答