具有多个容器的.NET反射依赖注入

时间:2010-10-26 08:10:42

标签: c# .net reflection dependency-injection

我对依赖注入相对较新,所以我可能在某种程度上屠杀这个概念。但是,我正在尝试实现以下类似的功能,但我不确定它是否可行:

假设我有两个容器,每个容器包含相同类型依赖关系的不同实例。例如,每个包含MyApplicationContextMyRequestContext的不同实例。

现在假设我有几个依赖于这些实例中的一个(或两个)的类。他们不应该关心他们使用的两个容器中的哪一个;他们只需要一个依赖实例来完成工作。

在一个理想的世界中,这些可靠类中的每一个都在其构造函数中进行静态调用,这反过来又从一个适当的容器中注入依赖...

public class MyDependableClass{
  protected MyApplicationContext Application {get; set;}
  protected MyRequestContext Request {get; set;}
  public MyDependableClass() {
    Dependencies.Inject(this);
  }
}

然而,AFAIK没有确定适当的容器的实用方法。我已经考虑过针对特定容器(例如container.Register(obj);)注册每个对象,但是如果构造函数中需要依赖项,这将是费力的并且不起作用。或者,您可以分析调用堆栈以从已注册的顶级对象推断容器...不适用于异步调用等

有什么想法吗?

示例:我可能有几个可以依赖代理实例的类;我们称之为ILogicProxy。此代理可以将调用转发到另一台计算机上的本地逻辑或远程逻辑。此外,应用程序可以与多个远程机器建立连接。所以...我们可能有多个ILogicProxy个实例需要注入几个类......但哪个实例在哪里?像这样的解决方案可以使用简单的“setter属性注入”,但是当需要更多依赖项时,这不会扩展,因为它会导致“连线”过程变得混乱/冗长。

2 个答案:

答案 0 :(得分:1)

这不是多个容器的情况。使用容器配置来连接。如果您在ILogicProxy界面下注册了大量组件,那么是的,您将需要进行更多的手动连接。但问问自己这些组件是否应该在同一界面下真正注册。

关于代码示例:

  

在一个理想的世界中,这些可靠类中的每一个都在其构造函数中进行静态调用,而这反过来又会从适当的容器中注入依赖项...

public class MyDependableClass{
  protected MyApplicationContext Application {get; set;}
  protected MyRequestContext Request {get; set;}
  public MyDependableClass() {
    Dependencies.Inject(this);
  }
}

这是服务地点,而不是依赖注入。始终更喜欢依赖注入到服务位置。尽量不要依赖组件中的Resolve()或Inject()方法。

答案 1 :(得分:0)

在我看来,您不需要多个容器,但您必须创建一个知道如何路由的ILogicProxy实现。您可以将该类型实现为其他ILogicProxy实现的包装器,如下所示:

public class LogicProxyRouter : ILogicProxy
{
    private readonly ILogicProxy local;
    private readonly ILogicProxy remote;

    public LogicProxyRouter(ILogicProxy local, ILogicProxy remote)
    {
        this.local = local;
        this.remote = remote;
    }

    public void Method(params)
    {
        if (someCondition)
        {
            this.local.Method(params);
        }
        else
        {
            this.remote.Method(params);
        }
    }
}

这样你可以像这样连接一个实例:

ILogicProxy proxy =
    new LogicProxyRouter(new LocalLogicProxy(), new RemoteLogicProxy());

// Register that instance in your favorite IoC framework
container.RegisterSingle<ILogicProxy>(proxy);

我希望这会有所帮助。