【发布时间】:2020-01-22 17:29:50
【问题描述】:
我试图弄清楚如何通过 .net 核心中的依赖注入来使用具有泛型的基类的多个实现。
我的基类使用泛型,因此我可以在响应 Dto 中使用不同类型的 List。
在不涉及泛型的情况下,我已经成功使用了许多接口和基类实现。
到目前为止我已经尝试过。
基类
public abstract class GeneratorBase<T>
{
public abstract ProcessorResponse<T> Process();
}
响应 dto
public class ProcessorResponse<T>
{
public ProcessorResponse()
{
Data = new List<T>();
}
public List<T> Data { get; set; }
}
实施编号 1
public class ConfigurationGenerator : GeneratorBase<ConfigurationModel>
{
public override ProcessorResponse<ConfigurationModel> Process()
{
return new ProcessorResponse<ConfigurationModel>();
}
}
实施编号 2。
public class ApplicationGenerator : GeneratorBase<ApplicationModel>
{
public override ProcessorResponse<ApplicationModel> Process()
{
return new ProcessorResponse<ApplicationModel>();
}
}
型号
public class ConfigurationModel
{
public int Count { get; set; }
}
public class ApplicationModel
{
public string Title { get; set; }
}
我的依赖注入来添加实现。
public static void AddGenerators(this IServiceCollection services)
{
// add our generators
services.AddScoped<GeneratorBase<ConfigurationModel>, ConfigurationGenerator>();
services.AddScoped<GeneratorBase<ApplicationModel>, ApplicationGenerator>();
}
主应用程序这是我发生错误的地方。
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();
}
}
更新 IFoo 示例 有效的 IFoo 示例。
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";
}
依赖注入来添加实现。
public static void AddGenerators(this IServiceCollection services)
{
// add our Foo's
services.AddTransient<IFoo, Foo1>();
services.AddTransient<IFoo, Foo2>();
}
主应用
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);
}
}
}
控制台输出
我是 Foo 1
我是 Foo 2
我是 Foo 1
【问题讨论】:
-
对不起,修剪完成了我的代码,我错过了,它已更新。无论如何,我仍然有这个问题。
-
我更新了代码,使其更加清晰。 AddGenerators 将添加两个不同的实例。
-
当您想通过传入您要使用的具体类的实际类名来决定使用哪个生成器时,您误用了依赖注入的概念。您能否解释一下为什么您认为应该使用 di 以及为什么您认为使用具体的类名来选择生成器是个好主意。这两件事实际上是相互矛盾的
-
在 DI 中,我们可以有许多接口甚至基类的实现。我有很多这些生成器的实现,我不知道用户会使用哪一个,直到他们选择一个。我正在寻找建议。这一切都有效,直到我决定在基类中实现泛型。
-
@KC。 “在 DI 中,我们可以有许多接口甚至基类的实现。” - 是的,但是这些不同的实现是在启动时(或范围初始化)而不是在运行时或交互时选择的。不同的实现旨在用于测试与开发,或用于 A/B 研究/测试等。听起来您只需要工厂模式。
标签: c# .net-core dependency-injection