Greg
Greg

Reputation: 11480

Dependency Injection coupled with a Generic

I've become quite familiar with Dependency Injection and the power of loosely-coupled components. When I sought to enhance or build on that for educational purposes I stumbled across a problem:

public interface IReader<TParameter, TOutput>
{
     TOutput Read(TParameter parameter);
}

public class Customer : IReader<int, CustomerModel>
{
     public CustomerModel Read(int parameter)
     {      
          // Implementation...
     }
}

The problem comes when you attempt to use Dependency Injection. I attempted:

public class Reader<TParameter, TOutput>
{
     private IReader<TParameter, TOutput> reader;
     public Reader(IReader<TParameter, TOutput> reader)
     {
          // Link through Constructor... 
     }
}

That doesn't work, but at this stage how can you implement and perform Dependency Injection when a generic is involved at this level? Is it even possible?

Upvotes: 2

Views: 650

Answers (1)

Jason W
Jason W

Reputation: 13179

I agree with some of the comments that without an IOC framework or a fair bit of custom reflection, you're not going to get much out of DI with simple .NET for generics like this situation. The pattern you seem to be describing is a Proxy pattern with the last Reader class that encapsulates the interface.

By renaming the last class ReaderProxy for clarity, I tried to take your code a step farther hoping to show how the dependency injection can be carried through without the framework or custom initialization of the generic objects that could simplify the actual initialization lines.

The code below would show how dependency injection could be used (See fiddle: https://dotnetfiddle.net/cfNCyl).

var reader = new ReaderProxy<int, CustomerModel>(new Customer());
var model = reader.Read(5);
Console.WriteLine(model.Id);

And here are the classes and interfaces required for the above code (including a simple CustomerModel):

public interface IReader<TParameter, TOutput>
{
     TOutput Read(TParameter parameter);
}

public class Customer : IReader<int, CustomerModel>
{
     public CustomerModel Read(int parameter)
     {      
         return new CustomerModel() { Id = parameter };
     }
}

public class CustomerModel
{
    public int Id { get; set; }
}

public class ReaderProxy<TParameter, TOutput>
    : IReader<TParameter, TOutput>
{
    private IReader<TParameter, TOutput> reader;
    public ReaderProxy(IReader<TParameter, TOutput> reader)
    {
          this.reader = reader;
    }
    public TOutput Read(TParameter parameter)
    {
        return this.reader.Read(parameter);
    }
}

Upvotes: 1

Related Questions