mercredi 22 août 2018

Does it make sense to use generic parameters to select which service implementation will be injected?

I have a class called ReportWorkflow<TReport> that calls some objects to generate a report of a specific type, the object are always called in the same sequence and the only true difference is the actual implementation of each object.

The constructor of this class looks like:

public ReportWorkflow(... , IFileNameProvider<TReport> fileNameProvider)

The ReportWorkflow<TReport> is constructed using dependency injection. There are multiple ReportWorkflow<TReport> registered at the same time in the DI Container, like:

services.AddSingleton<IReportWorkflow, ReportWorkflow<HrReport>();
services.AddSingleton<IReportWorkflow, ReportWorkflow<AccountingReport>();
//More ReportWorkflows registrations...

To make sure that I get the correct file name provider for every ReportWorkflow<TReport> I've added the generic parameter TReport to the interface IFileNameProvider<TReport> but this interface never uses the generic parameter and it is only there to 'mark' and distinguish an implementation from another.

The interface definition is as follows

public interface IFileNameProvider<TReport> {
    string GetFileName();
}

An implementation simply fills the generic parameter with the report type and it will be registered like:

services.AddSingleton<IFileNameProvider<HrReport>, HrFileNameProvider>();
services.AddSingleton<IFileNameProvider<AccountingReport>, AccountingFileNameProvider>();

This will ensure that when I will try to resolve ReportWorkflow<HrReport> I will get HrFileNameProvider and when I will try to resolve ReportWorkflow<AccountingReport> I will get AccountingFileNameProvider.

The 'type markers' HrReport or AccountingReport are actual classes used and returned by other objects and do contain some information.

Does it make sense to have interfaces that use generic parameters just as a sort of 'marker' to distinguish one implementation from another ? And if yes, does this pattern have a name ?

Aucun commentaire:

Enregistrer un commentaire