繁体   English   中英

Unity Property Setter注入按需

[英]Unity Property setter injection on demand

是否可以使Unity根据需要将依赖对象注入到父对象中,而不是在初始化父对象时注入?

是的,让Unity注入Lazy<T>而不是T 这是一篇有关该主题的文章: http : //www.tomdupont.net/2012/07/lazy-unity-injection.html

如果您确实需要“按需”, Lazy<T>并没有真正的帮助。 Lazy<T>实际上仅在需要延迟解析时才有效。 但是,在初步解决之后,可以使用相同的参考。

我通过使用Castle.DynamicProxy解决了这个问题。 我需要将某些依赖项注入“按需”,这意味着它们需要在使用时解决(每次都需要新解决),而不是在“ Depender”建立时解决。

为此,我像这样配置容器:

 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。 从属对象实际上持有对代理对象的引用,而不是对象本身。

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;
    }
}

OnDemandInterceptor:

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);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM