【问题标题】:How to inject different dependencies that depends on argument name using Windsor如何使用 Windsor 注入取决于参数名称的不同依赖项
【发布时间】:2015-02-06 09:03:45
【问题描述】:

我有这样的结构:

public class Processor<T>
{
    public Processor(IManager<T> xmlManager, IManager<T> memoryManager)
    {

    }
}

public interface IManager<T>
{

}

public class Manager<T> : IManager<T>
{
    private readonly IProvider _provider;

    public Manager(IProvider provider)
    {
        _provider = provider;
    }
}

public interface IProvider  {   }

public class XmlProvider : IProvider {  }

public class MemoryProvider : IProvider {   }

我需要向处理器类注入 Manager 类的两个实例,但注入不同。我需要这么硬编码:

var p = new Processor<T>(new Manager<T>(new XmlProvider()) , new Manager<T>(new MemoryProvider()))

我还需要使用开放的泛型类型 T 来解决这个问题。

我不知道如何配置容器来管理它。我知道有.DependsOn(Property.ForKey("xmlManager").Eq() 指令。但我无法理解在Eq() 中要写什么,除非是硬编码的实现。提供者有自己的依赖关系。所以写.Eq(new Manager&lt;T&gt;(new XmlProvide(new OtherInjection(new AnotherOne()))))并不聪明。而且我不能使用开放的泛型。

UPD 1 NightOwl先生888。关于逻辑。一种提供程序用于将数据存储在内存缓存中。第二个提供程序用于存储数据,将数据存储在 xml 文件中。某种2级缓存模型。如果我交换两个参数(如 Steven 所说),它不会中断,但它不会像设计的那样工作(因为检索信息的速度不同)。

【问题讨论】:

  • 如果不小心交换了两个参数会怎样?你的Processor 会坏掉吗?如果是这样,您就违反了 Liskov 替换原则,您可能需要重新考虑您的设计。
  • 我同意@Steven。制作抽象(接口)的全部意义在于,您可以在 Processor 不知道您正在处理的 IManager&lt;T&gt; 的具体类型的情况下交换实现。在您的设计中,Processor 知道这些细节,如果稍后引入第 3 个IManager&lt;T&gt; 类型,那将是对Processor 的重大更改。 Processor 是否需要多个 IManager&lt;T&gt; 才能执行,还是根据条件选择一个Processor 包含此逻辑违反了单一职责原则。设计中的逻辑也不清楚。
  • 我认为@Steven 和@NightOwl888 是对的。我更新了有关逻辑的信息。同样在与@DragonFire 讨论之后,我发现架构很糟糕。经理应该实现 1 个接口,因为它们具有相同的方法和目的。但在我的上下文中它们也不同。所以我需要通过另一个界面来区分它们。例如IXmlCachManagerIInMemoryCacheManager。而不是通过这个接口解决它们
  • @Rit,感谢您的链接。使用新界面(我之前的评论)和this 链接一切都解决了。哇哈哈哈。谢谢大家

标签: c# .net dependency-injection castle-windsor


【解决方案1】:

我没有与 Windsor 合作,但常见的解决方案看起来像

public class ManagerFactory // register it in container
{
   public IManager<T> Create<T>(IProvider provider) { return ... }
}

public class Processor<T>
{
    public Processor(ManagerFactory factory, IEnumerable<IProvider> providers)
    {
       myManagers = providers.Select(provider => factory.Create<T>(provider).ToList();
    }
}

通常,您可以注册某些接口的许多实现(在您的情况下为 IProvider),因此容器可以将它们全部注入

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多