Options for automatically posting IoC in a domain-managed project

In my last ASP.NET MVC 2 application, I try to implement the concepts of Domain Driven Design (DDD) , Single Responsibility Principle (SRP) , Inversion of Management (IoC) and Test Driven Development (TDD) . As an example of architecture, I follow Jeffrey Palermo's Onion Architecture , which is greatly expanded in ASP.NET MVC 2 in action .

Onion architecture diagram

While I began to successfully apply most (some?) Of these principles, I miss the key element of the puzzle. I had problems determining the best mechanism for automatically connecting a service level to my domain objects.

As an example: each domain object that needs to send an email should depend on the IEmailService interface. From my reading, it would be best practice to identify this dependency using a constructor injection. In my user interface layer, I am doing a similar injection to implement the repository interface using StructureMapControllerFactory from ASP.NET MVC Contrib .

Where am I confused, is the best mechanism for automatically posting the injection of necessary services to domain objects? Should domain objects be entered this way? How can I use IEmailService if I do not enter it in the domain entity?

Additional questions that are great links DDD, SRP, IoC, TDD:

  • IoC containers and domain-driven design
  • Avoiding the creation of very large objects using Driven Design .
+7
c # inversion-of-control ioc-container domain-driven-design autowired
source share
1 answer

If I do not understand your intention, and instead I decided to focus on semantics, I am going to analyze this statement. For example: each domain object that needs to send an email must depend on the IEmailService interface. "

I would have to argue that this in itself is the extreme bastardization of DDD. Why does a domain company need to depend on an email service? IMO this should not. There is no reason for this.

However, there are business transactions in conjunction with a domain object for which you will need to send emails. You should have your IEmailService dependency contained in this class, not a domain object. This class is likely to fall into one of several almost synonymous names: Model, Service or Controller, depending on which architecture / layer you are on.

At this point, your StructureMapControllerFactory will correctly automatically connect everything that IEmailService will use.

Although I might be secondary in generalizing, this is pretty standard practice for domain objects to be POCOs or almost POCOs (to avoid SRP violation), but often SRP is broken in domains for serialization and verification. Choosing an SRP violation for these types of cross-linking problems is more a personal belief position than a β€œright” or β€œwrong” decision.

As a final decision, if your question concerns a part of the code that really works in an autonomous service, whether based on a network or OS and how to connect dependencies to it, the normal decision will be to take care of the service at the basic level and apply the same IOC to it in a manner similar to StructureMapControllerFactory in MVC. How to achieve this will depend entirely on the infrastructure you work with.

Answer:

Suppose you have an IOrderConfirmService that has an EmailOrderConfirmation(Order order) method. You would get something like this:

 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); } } 

Then you will have an OrderController class that will look like

 public class OrderController : Controller { private readonly IOrderConfirmService _service; public OrderController(IOrderConfirmService service) { _service= service; } public ActionResult Confirm() { _service.EmailOrderConfirmation(some order); return View(); } } 

StrucutreMap will essentially create an entire architecture chain when you use constructor injection correctly. This is the fundamental difference between hard coupling and inversion of control. So when StructureMapFactory is about to create your controller, the first thing it sees is that it needs an IOrderConfirmService. At this point, he checks if he can directly connect the IOrderConfirmService, which he cannot, because he needs an IEmailService. Therefore, it checks to see if it can connect to IEmailService, and for arguments, say what it can. So, at this point, he will create an EmailService, which will then create MyOrderConfirmService and connect the EmailService, and then finally create an OrderController and connect MyOrderConfirmService. This is where the term "control inversion" comes from. StructureMap will first create an EmailService in the entire dependency chain and end last with the controller. In a closely related setup, it will be the other way around when the controller is built first and will have to create a business service and then build an email service. The tightly coupled design is very fragile compared to the IOC.

+4
source share

All Articles