C# 在统一中有条件地解析命名实现

C# 在统一中有条件地解析命名实现,c#,unity-container,C#,Unity Container,Unity允许您命名同一接口的不同实现,然后按名称解析它们: var container = new UnityContainer(); // register container.Register<IFish, OneFish>("One"); container.Register<IFish, TwoFish>("Two"); // resolve var twoFish = container.Resolve("Two"); 如何解析Itak并指定要获取哪个I

Unity允许您命名同一接口的不同实现,然后按名称解析它们:

var container = new UnityContainer();

// register
container.Register<IFish, OneFish>("One");
container.Register<IFish, TwoFish>("Two");

// resolve
var twoFish = container.Resolve("Two");
如何解析Itak并指定要获取哪个IFish实现

这不起作用:

container.Register<ITank, Tank>();

var tank = container.Resolve<ITank>("One");
container.Register();
var储罐=容器。解析(“一”);
这项工作:

var fish = container.Resolve<IFish>("One");

var tank = container.Resolve<Tank>(new DependencyOverride(typeof(IFish), fish);
var fish=container.Resolve(“一”);
var tank=container.Resolve(新的DependencyOverride(typeof(IFish),fish);
但它只处理简单的情况(如本例中),而不是一般情况下可能有许多名为“一”的实现。我希望能够告诉Unity:

在解析名为“One”的使用实现时,如果未注册此类实现,则返回到未命名的实现


是否有一个自定义解析器可以通过此行为插入Unity?

您可以使用Unity的InjectionFactory注入一个命名实例

var container = new UnityContainer();

// register
container.Register<IFish, OneFish>("One");
container.Register<IFish, TwoFish>("Two");

container.RegisterType<ITank,Tank>(new InjectionFactory(c=>c.Resolve<IFish>("One")));
var container=newunitycontainer();
//登记册
集装箱登记册(“一”);
集装箱登记册(“两份”);
RegisterType(新注入工厂(c=>c.Resolve(“一”));
如果您现在解析Tank类型的实例,则OneFish的实例将被注入到您的坦克中

要处理您希望注入IFish的默认实现的情况,可以将InjectionFactory更改为以下内容

new InjectionFactory(c=>{
  if (c.IsRegistered<IFish>("One")) {
    c.Resolve<IFish>("One");
  }
  else {
    c.Resolve<IFish>("Two");
  }
})
新注入工厂(c=>{
如果(c.已登记(“一”)){
c、 决议(“一”);
}
否则{
c、 决议(“两”);
}
})

感谢您的回答,但我们的想法不是使用严格的注册配置。考虑一个具有多种模式的系统,大多数类的实例化方式相同,但在不同的模式下有一些不同:在“生产”模式下,数据是从主数据库I/Oed的,错误会被记录,并且“临时”模式模式数据是从XML文件中I/Oed的,不会发生日志记录。我希望能够告诉Unity:解析“生产”或解析“临时”同时在运行时,我希望共享通用注册。我希望有人知道用于此的现有Unity插件。我认为这对我来说可能是一个可行的解决方案,但它在尝试将IFish转换到Itak时抛出异常?您在这里得到了您的查询的答案吗?我面临类似的问题陈述。不,抱歉。最终我可能会为Unity编写一个扩展,但我概述的简单解决方案现在就足以满足我的需要。如果我这样做,我会更新。
new InjectionFactory(c=>{
  if (c.IsRegistered<IFish>("One")) {
    c.Resolve<IFish>("One");
  }
  else {
    c.Resolve<IFish>("Two");
  }
})