How to enter the correct dependency based on the name of the constructor parameter

I have this interface that is used by several specific types such as EmailFormatter , TextMessageFormatter , etc.

 public interface IFormatter<T> { T Format(CompletedItem completedItem); } 

The problem I am facing is that with my EmailNotificationService I want to insert an EmailFormatter . The constructor signatures for this service are public EmailNotificationService(IFormatter<string> emailFormatter) .

I'm sure I saw this before, but how do I register this with Windsor so that it EmailFormatter if the name of the parameter is the EmailFormatter constructor?

Here is my Windsor registration code.

 container.Register(Component.For<IFormatter<string>>().ImplementedBy<EmailFormatter>()); 
+6
source share
2 answers

Service Code:

 public EmailNotificationService(IFormatter<string> emailFormatter){...} 

Dependency Registration Code:

 container.Register( Component.For<IFormatter<string>().ImplementedBy<TextMessageFormatter>().Named("TextMessageFormatter"), Component.For<IFormatter<string>().ImplementedBy<EmailFormatter>().Named("EmailFormatter"), Component.For<INotificationService>().ImplementedBy<EmailNotificationService>().ServiceOverrrides( ServiceOverride.ForKey("emailFormatter").Eq("EmailFormatter")) ); 
+6
source

Do not try to solve this problem in a DI configuration. Instead, solve it in the design of the application. It seems to me that you have defined several different things with the same interface. Your requirements make this pretty obvious as you say:

I want to add EmailFormatter

You do not want to enter a formatter; You want to enter an email formatter. In other words, you violate the Liskov Principle of Replacement . Fix this problem in the application. Define the IEmailFormatter interface and let EmailNotificationService depend on this:

 public interface IEmailFormatter { string Format(CompletedItem completedItem); } public class EmailNotificationService { public EmailNotificationService(IEmailFormatter formatter) { } } 

This has two important advantages:

  • This makes the code more convenient, since it is now clear which dependency EmailNotificationService really has.
  • This makes the DI configuration much easier and more convenient to maintain. Just look at the registration of the dependencies of Zach's answer, and you will understand what I'm talking about.
+9
source

Source: https://habr.com/ru/post/894488/


All Articles