1

是否可以让 Unity 按需将依赖对象注入父对象,而不是在父对象初始化时?

4

2 回答 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 回答