我可以使用IoC容器来创建需要运行时值的依赖项吗?

时间:2010-02-15 23:36:35

标签: .net castle-windsor ioc-container

我是IoC的新手,所以我想知道它是否是我想做的工作的正确工具。

我正在编写一个多租户应用程序,有几个地方我们可能希望根据当前登录用户所属的组织使用不同的接口实现。

比方说,例如,当一个组织的用户创建工作订单时,需要向该用户的主管发送电子邮件。但对于所有其他组织,不需要发送该电子邮件。经典战略模式的一种东西。

我的问题是,我可以以某种方式指示IoC容器查看某个运行时值(在这种情况下是登录用户的OrganizationId)以确定要注入的IWorkOrderProcessor的哪个实现进入需要它的对象的构造函数?

我目前正在使用Windsor,但使用其他容器的示例会很好。

4 个答案:

答案 0 :(得分:3)

Windsor有一个扩展点,非常适合多租户应用:IHandlerSelector。

这使您可以将应用程序编码为不是多租户。多租户逻辑被移动 out 您的业务逻辑。

答案 1 :(得分:1)

大多数优秀的IOC容器都支持这种用法。

我对Windsor不熟悉,我选择的IOC是StructureMap。在StructureMap流畅的界面中,您可以使用许多选项来设置对象的运行时注入参数,具体取决于您可以在代码中表达的任何内容。我相信温莎会提供同样的产品。

对于像这样使用IOC我唯一要说的是,有时它会让解决方案难以理解。

在你的例子中,如果你真的有一个战略模式的真实用例你将实现这种行为即使你没有使用IOC作为注入策略对象(使用一些工厂方法)然后我会说,是的,去提前实施IOC。

但是如果你真的不需要注入一个完整的对象抽象来表达某些用户是否收到电子邮件的逻辑,那么也许这就是模式的模式。

答案 2 :(得分:0)

我认为你可以,因为IoC容器可以使用不同类型的注入:

  1. 构造函数注入,
  2. 一个二传手注射,
  3. 界面注入(方法注入)
  4. 构造函数注入提供完全初始化的对象,但是在创建对象之前必须知道您注入的类型和值(例如,可能从配置文件加载)。

    方法(或设定者)注射是灵活的 - 您可以延迟注射直到您需要的类型或值。这种方法的缺点是您在创建对象时没有完全初始化的对象。

    一切都取决于您的容器的实施方式。

    顺便提一下:问了类似的问题:IoC: Existing runtime objects rather than container-initialised prerequisites for components

答案 3 :(得分:0)

这是DI的常见挑战,答案始终是创建并注入抽象工厂。在您的情况下,您可以定义如下界面:

public interface IWorkerProcessorFactory
{
    IWorkerProcessor Create(int organizationId);
}

在您拥有组织ID且需要IWorkerProcessor实例的所有类中,您依赖IWorkerProcessorFactory并调用其Create方法。

此模式适用于穷人的DI 或您想要使用的任何DI容器。

以下是一个更完整的示例:Can't combine Factory / DI