Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inject proper dependency based on constructor parameter name

I have this interface that is being used by a handful of concrete types, such as EmailFormatter, TextMessageFormatter etc.

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

The issue I'm having is that with my EmailNotificationService is that I want to inject EmailFormatter. The constructor signature for this service is public EmailNotificationService(IFormatter<string> emailFormatter).

I'm pretty sure I've seen this done before but how do I register this with Windsor so that it injects EmailFormatter if the constructor parameter name is emailFormatter?

Here is my Windsor registration code.

container.Register(Component.For<IFormatter<string>>().ImplementedBy<EmailFormatter>());
like image 510
User Avatar asked Aug 07 '11 15:08

User


1 Answers

Don't try to solve this problem in the DI configuration. Instead, solve it in the design of the application. It seems to me that you have defined several distinct things with the same interface. Your requirements makes it pretty obvious, since you say:

I want to inject EmailFormatter

You don't want to inject a formatter; you want to inject an e-mail formatter. In other words, you are violating the Liskov Substitution Principle. Fix this issue in the application. Define an IEmailFormatter interface and let the EmailNotificationService depend on this:

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

public class EmailNotificationService
{
    public EmailNotificationService(IEmailFormatter formatter)
    {
    }
}

This has two important advantages:

  1. It makes the code more maintainable, since now it is clear what kind of dependency EmailNotificationService really has.
  2. It makes the DI configuration much easier and more maintainable. Just look at the dependency registration of Zach's answer, and you'll understand what I'm talking about.
like image 129
Steven Avatar answered Sep 22 '22 01:09

Steven