依赖注入中的可选性(StructureMap)

时间:2013-02-05 09:51:24

标签: dependency-injection structuremap

我知道在管理正确的工作和行为所需的依赖关系时,应该应用构造函数的注入。

即便如此,我想公开这个例子。我们假设一个MailServer类:

public class MailServer : IMailServer
{
    public MailServer(ServerData serverData)
    {
        _serverData = serverData;
    }

    public void SendMail(MailData mailData)
    {
        //Work with mailData instance and send mail
        ...
        smtp.Send(mail);
    }
}

ServerData包含了解如何发送邮件所需的信息,例如:服务器IP地址,FROM源地址,FROM密码。 MailData包含所需的正文以及您要发送邮件的地址。

两者都是必需的依赖项。 困扰我和我不知道如何解决的问题是ServerData可能在应用程序的不同位置有所不同。如果在发票系统中使用了IMailServer,邮件应该来自'invoices@domain.com',但是,如果在其他地区使用它,则应该来自'notifications@domain.com'。

我不知道这是管理它的正确方法。至于与依赖注入相关的所有内容,我想知道与功能相关的良好实践。这段代码几乎总是出现在每个应用程序中,知道如何完成它会很棒。

非常感谢!

1 个答案:

答案 0 :(得分:1)

为什么不使用适当的源地址等设置注册MailServer类的不同实例,并将它们注入应用程序的相应组件? IMailService的消费者不需要知道这个细节。


<强>更新

我不是StructureMap配置引擎的专家,但是如果你使用这样的东西

var registry = new Registry();
registry.For<IMailServer>().Use<MailServer>();
registry.For<ServerData>().ConditionallyUse(x =>
{
  x.If(c => c.Root.RequestedType == typeof(Consumer1)).ThenIt.IsThis(new ServerData("1"));
  x.If(c => c.Root.RequestedType == typeof(Consumer2)).ThenIt.IsThis(new ServerData("2"));
});
var container = new Container(registry);
var consumer1 = container.GetInstance<Consumer1>();
Assert.AreEqual("1", consumer1.Server.ServerData.Foo);
var consumer2 = container.GetInstance<Consumer2>();
Assert.AreEqual("2", consumer2.Server.ServerData.Foo);

您应该能够将非常具体的ServerData对象注入到各种消费者的每个实例中。