如何在Unity中覆盖命名依赖项

时间:2012-07-19 12:15:01

标签: dependency-injection inversion-of-control override unity-container

请建议我如何解决以下问题:

我有一个班级:

public class Module
{
   public Module(Uri param1, Uri param2)
   {
   }
}

此类型已在The Unity Container中注册:

container.RegisterInstance<Uri>("uri1", new Uri("http://sample-1.com"));
container.RegisterInstance<Uri>("uri2", new Uri("http://sample-2.com"));

container.RegisterType<Module>(
       new InjectionConstructor(
             new ResolvedParameter<Uri>("uri1"), 
             new ResolvedParameter<Uri>("uri2")));

通过这种方式,我建立了对不同Uri实例的不同构造函数参数的依赖。

我希望在解析Module的实例时覆盖这些值。

我可以按类型覆盖:

container.Resolve<Module>(
             new DependencyOverride(typeof(Uri), new Uri("http://overriden.com")))

我也可以通过custructor参数覆盖。

container.Resolve<Module>(
   new ParameterOverride("param1", new Uri("http://param1.org"))
   new ParameterOverride("param2", new Uri("http://param2.com")))

但是:我不知道如何根据类型注册的名称按类型覆盖。 因此,DependencyOverride没有任何其他参数来覆盖并非所有类型,也不能使用命名注册。

因此,我希望得到以下内容:

container.Resolve<Module>(
    new DependencyOverride("uri1", typeof(Uri), new Uri("http://overriden-1.com")),
    new DependencyOverride("uri2", typeof(Uri), new Uri("http://overriden-2.com")));

第一个参数(uri1&amp; uri2)是在初始注册时使用ResolvedParameter(“uri1”)和ResolvedParameter(“uri2”)注册类型时用于构建依赖关系的名称。

请建议我,如何在不定义构造函数参数名称的情况下从容器中解析Module时如何覆盖。

P.S。我为什么要这样走? 因为我不希望依赖于参数的名称,所以有人可以重命名它们并且依赖树将被破坏。另外,我不希望依赖于Module如何注册,如果Module有多个构造函数,则选择了什么类型的构造函数。

UPD:我找到了临时解决方案,但它只是解决方法,因为它打破了终身管理器,例如PerResolveLifetimeManager,因为我们分别从控制器解析Module1和Module2,它们依赖于Module1和Module2。

        var m1 = _container.Resolve<IModule1>(
            new DependencyOverride(typeof(HttpControllerContext), context),
            new DependencyOverride(typeof(Uri), new Uri("http://module-1.com/")));

        var m2 = _container.Resolve<IModule2>(
            new DependencyOverride(typeof(HttpControllerContext), context),
            new DependencyOverride(typeof(Uri), new Uri("http://m-2.com/")));

        var dependency = new ResolverOverride[] 
        {
            new DependencyOverride(typeof(HttpControllerContext), context),
            new DependencyOverride(typeof(IModule1), m1),
            new DependencyOverride(typeof(IModule2), m2)
        };

        var controller = _container.Resolve(controllerType, dependency) as IHttpController;
        return controller;

1 个答案:

答案 0 :(得分:0)

您是否尝试过儿童容器?而不是

container.Resolve<Module>(
    new DependencyOverride("uri1", typeof(Uri), new Uri("http://overriden-1.com")),
    new DependencyOverride("uri2", typeof(Uri), new Uri("http://overriden-2.com")));

您可以使用您的URI创建子容器,并让它来解析您的模块:

container.CreateChildContainer()
    .RegisterInstance<Uri>("uri1", new Uri("http://overriden-1.com"))
    .RegisterInstance<Uri>("uri2", new Uri("http://overriden-2.com"))
    .Resolve<Module>();