I'm trying to figure out how to use multiple implementation of a base class with generics via dependency injection in .net core.
My base class is using generics so I can have different types of List in my response Dto.
I have successfully used many interface and base class implementations when there are no generics involved.
What I've tried so far.
Base class
public abstract class GeneratorBase<T>
{
public abstract ProcessorResponse<T> Process();
}
Response dto
public class ProcessorResponse<T>
{
public ProcessorResponse()
{
Data = new List<T>();
}
public List<T> Data { get; set; }
}
Implementation number 1
public class ConfigurationGenerator : GeneratorBase<ConfigurationModel>
{
public override ProcessorResponse<ConfigurationModel> Process()
{
return new ProcessorResponse<ConfigurationModel>();
}
}
Implementation number 2.
public class ApplicationGenerator : GeneratorBase<ApplicationModel>
{
public override ProcessorResponse<ApplicationModel> Process()
{
return new ProcessorResponse<ApplicationModel>();
}
}
Models
public class ConfigurationModel
{
public int Count { get; set; }
}
public class ApplicationModel
{
public string Title { get; set; }
}
My dependency injection to add the implementations.
public static void AddGenerators(this IServiceCollection services)
{
// add our generators
services.AddScoped<GeneratorBase<ConfigurationModel>, ConfigurationGenerator>();
services.AddScoped<GeneratorBase<ApplicationModel>, ApplicationGenerator>();
}
Main App this is where my error is happening.
public class GeneratorApp
{
// error because T is not implemented
private readonly IEnumerable<GeneratorBase> _generators;
// error because T is not implemented
public GeneratorApp(IEnumerable<GeneratorBase> generators)
{
_generators = generators ?? throw new ArgumentException(nameof(generators));
}
public void RunGenerator(string name)
{
// get the generator by name and run process
var generator = _generators.FirstOrDefault(c => c.GetType().Name == name);
var results = generator.Process();
}
}
Update IFoo Example IFoo example that works.
public interface IFoo
{
string Name { get; }
}
public class Foo1 : IFoo
{
public string Name => "I'm Foo 1";
}
public class Foo2 : IFoo
{
public string Name => "I'm Foo 2";
}
Dependency injection to add the implementations.
public static void AddGenerators(this IServiceCollection services)
{
// add our Foo's
services.AddTransient<IFoo, Foo1>();
services.AddTransient<IFoo, Foo2>();
}
Main App
public class GeneratorApp
{
private IEnumerable<IFoo> _foos;
public GeneratorApp(IEnumerable<IFoo> foos)
{
_foos = foos;
RunGenerator("Foo1");
}
public void RunGenerator(string name)
{
foreach (var foo in _foos)
{
Console.WriteLine(foo.Name);
}
var foundFoo = _foos.FirstOrDefault(c => c.GetType().Name == name);
if (foundFoo != null)
{
Console.WriteLine(foundFoo.Name);
}
}
}
Console output
I'm Foo 1
I'm Foo 2
I'm Foo 1