【问题标题】:How to override named dependency in Unity如何在 Unity 中覆盖命名依赖项
【发布时间】:2012-07-19 12:15:00
【问题描述】:

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

我有一堂课:

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

此类型在 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 不同实例的不同构造函数参数的依赖。

我想在解析模块实例时覆盖这个值。

我可以按类型覆盖:

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 & uri2) 是在初始注册时使用 ResolvedParameter("uri1") 和 ResolvedParameter("uri2") 注册类型时用于构建依赖项的名称。

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

附:我为什么要走这条路? 因为我不想依赖参数的名称,所以有人可以重命名他们的依赖关系树。另外,我不想依赖 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;

【问题讨论】:

  • 如何更改配置中的值或“uri1”而不是使用ResolverOverride 的派生词?
  • 当然可以,但它不能帮助我解决如何在不依赖于构造函数参数名称的情况下覆盖构造函数参数的问题。我只想按类型覆盖。但是你建议我用另一种方法来解决这个问题。如果有帮助,我会写回复我是如何做到的。
  • 老实说,我什至建议您不要在应用程序代码中的任何地方调用容器,而不是在组合根目录之外...您是否介意分享一些代码来显示您的方式和位置按照你上面描述的方式调用容器?
  • 我更感兴趣的是这个 sn-p 的位置,而不是实际的解决方法。您从哪里获得Uri 的各种实例?
  • 我在使用 DependencyOverride 解析 IModule1 和 Module2 时替换了 Uri 类型

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


【解决方案1】:

您尝试过子容器吗?而不是

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

【讨论】:

    猜你喜欢
    • 2014-03-18
    • 1970-01-01
    • 2015-11-21
    • 1970-01-01
    • 2020-04-12
    • 2021-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多