Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 域驱动设计中IoC自动布线的选项_C#_Domain Driven Design_Inversion Of Control_Ioc Container_Autowired - Fatal编程技术网

C# 域驱动设计中IoC自动布线的选项

C# 域驱动设计中IoC自动布线的选项,c#,domain-driven-design,inversion-of-control,ioc-container,autowired,C#,Domain Driven Design,Inversion Of Control,Ioc Container,Autowired,在我最新的ASP.NET MVC 2应用程序中,我一直在尝试将、和的概念付诸实践。作为一个架构示例,我一直遵循Jeffery Palermo的“”,它在中得到了极大的扩展 虽然,我已经开始成功地应用这些原则中的大部分(部分?),但我却错过了其中的一个关键部分。我很难确定将服务层自动连接到域实体的最佳机制 例如:需要能够发送电子邮件的每个域实体都应该依赖于IEmailService接口。根据我的阅读,揭示这种依赖性的最佳实践是使用构造函数注入。在我的UI层中,我使用来自的StructureMap

在我最新的ASP.NET MVC 2应用程序中,我一直在尝试将、和的概念付诸实践。作为一个架构示例,我一直遵循Jeffery Palermo的“”,它在中得到了极大的扩展

虽然,我已经开始成功地应用这些原则中的大部分(部分?),但我却错过了其中的一个关键部分。我很难确定将服务层自动连接到域实体的最佳机制

例如:需要能够发送电子邮件的每个域实体都应该依赖于
IEmailService
接口。根据我的阅读,揭示这种依赖性的最佳实践是使用构造函数注入。在我的UI层中,我使用来自的
StructureMapControllerFactory
为存储库接口实现执行类似的注入

我感到困惑的是,自动将必要的服务注入域实体的最佳机制是什么?域实体是否应该以这种方式注入?如果我不将
IEmailService
注入域实体,我将如何使用它

附加的堆栈溢出问题是非常好的DDD、SRP、IoC、TDD参考:


除非我误解了您的意图,而是选择了关注语义,否则我将剖析此语句“作为示例:需要发送电子邮件的每个域实体都应该依赖于IEmailService接口。”

我不得不说,这本身就是对DDD的一种极端卑劣化。为什么域实体需要依赖电子邮件服务?我认为不应该。这是没有道理的

但是,与域实体一起进行的业务运营需要发送电子邮件。在此类中应该包含您的
IEmailService
依赖项,而不是域实体。这个类很可能属于几个几乎同义的名称之一:模型、服务或控制器,取决于您所处的体系结构/层

此时,您的
StructureMapControllerFactory
将正确地自动连接使用
IEmailService
的所有内容

虽然我可能有点过于笼统,但让域实体成为POCO或接近POCO(以避免违反SRP)几乎是标准做法,但为了序列化和验证,域实体中经常违反SRP。选择违反SRP来解决这些类型的交叉问题更像是个人的信仰立场,而不是“正确”或“错误”的决定

如果您的问题是关于在独立服务中真正运行的代码部分(无论是基于web还是基于OS的),以及如何从中连接依赖项,那么作为最后的跟进,通常的解决方案是在基本级别接管服务,并以与MVC中的
StructureMapControllerFactory
相同的方式对其应用IOC。如何实现这一点完全取决于您使用的基础设施

响应:

假设您有
IOrderConfirmService
,它有一个方法
EmailOrderConfirmation(订单)
。你会得到这样的结果:

public class MyOrderConfirmService : IOrderConfirmService
{    
    private readonly IEmailService _mailer;

    public MyOrderConfirmService(IEmailService mailer)
    {        
        _mailer = mailer;        
    }

    public void EmailOrderConfirmation(Order order)
    {        
        var msg = ConvertOrderToMessage(order); //good extension method candidite
        _mailer.Send(msg);        
    }    
}
然后,您的
OrderController

public class OrderController : Controller
{    
    private readonly IOrderConfirmService _service;

    public OrderController(IOrderConfirmService service)
    {        
        _service= service;        
    }

    public ActionResult Confirm()
    {      
            _service.EmailOrderConfirmation(some order);

            return View();
    }    
}

当您正确使用构造函数注入时,StructureMap将内在地构建您的整个体系结构链。这是紧耦合和控制反转之间的根本区别。因此,当StructureMapFactory构建控制器时,它将看到的第一件事是它需要IOrderConfirmService。此时,它将检查是否可以直接插入IOrderConfirmService,因为它需要IEmailService,所以不能直接插入IOrderConfirmService。因此,它将检查它是否可以插入IEmailService,为了论证起见,让我们说它可以。因此,在这一点上,它将构建EmailService,然后构建MyOrderConfigService并插入EmailService,最后构建OrderController并插入MyOrderConfigService。这就是“控制反转”一词的由来。StructureMap将在整个依赖链中首先构建EmailService,最后构建控制器。在紧密耦合的设置中,这将是相反的,首先构建控制器,然后构建业务服务,然后构建电子邮件服务。与IOC相比,紧密耦合的设计非常脆弱。

Chris,你死定了。我觉得我把
IEmailService
注入域实体是违反了什么。假设它是一个核心服务,我如何/在哪里连接需要使用
IEmailService
的各种实体?我想我很难想象它是如何工作的。所以这肯定说明了
IEmailService
是如何连接的。这又引出了几个问题。
IValidationService
的布线是否与
IEmailService
类似?我可以设想一个控制器,它将注入
irespoothry
IEmailService
、和
IValidationService
。在什么情况下我违反了任何具有3个以上依赖项的类都应该被询问是否违反SRP的准则?把我的控制器分解成更小的部分是一个简单的答案吗?像“3个以上的依赖项”这样的语句只是一条指导线。真的没有一个有限的数字会自动变坏。随着依赖项列表的增长,需要注意的主要事项是确保代码保持干燥。当您开始看到具有多个依赖项的重复或类似代码的模式出现时,应该将其中一些组合到特定的服务中。然而,如果没有出现任何模式,那么您的代码将非常简单。但是