[英]C# Dependency Injection - injecting interface that takes the same interface as a parameter
I've run into a bit of trouble trying to use dependency injection and need help.我在尝试使用依赖注入时遇到了一些麻烦,需要帮助。
I have a service IService
that is implemented a few different ways in my application.我有一个服务IService
,它在我的应用程序中以几种不同的方式实现。
ServiceA : IService { public ServiceA(IDependencyA A, IDependency B) {...} }
ServiceB : IService { public ServiceB(IDependencyA A, IDependency B) {...} }
ServiceC : IService { public ServiceC(IService serviceA, IService serviceB) {...} }
In my startup.cs
file, I will pick which one to use based on a parameter in my configuration file.在我的startup.cs
文件中,我将根据我的配置文件中的参数选择使用哪个。 Something like this:像这样:
var service = Configuration["AppConfig:Service:ID"];
switch(service) {
case "A":
services.AddTransient<IService, ServiceA>();
case "B":
services.AddTransient<IService, ServiceB>();
case "C":
// ??
}
I am able to create and use service A and service B very easily.我能够非常轻松地创建和使用服务 A 和服务 B。 I inject their dependencies A and B before hand and they get created just fine.我事先注入了它们的依赖项 A 和 B,它们创建得很好。 The problem is with the third service.问题出在第三个服务上。 I need to inject the two other services into it.我需要将另外两个服务注入其中。 My question is: what is the best to do this?我的问题是:最好的做法是什么?
Is there a way I can create concrete implementations of service A and B but somehow use the injected dependency A and B in their constructor?有没有一种方法可以创建服务 A 和 B 的具体实现,但以某种方式在其构造函数中使用注入的依赖项 A 和 B? Do I have to mess around with the interfaces to get this to work?我是否必须弄乱接口才能让它工作? Maybe I have to change the constructor of ServiceC to take in concrete implementations of A & B?也许我必须更改 ServiceC 的构造函数以接受 A 和 B 的具体实现?
Updated: don't know if it's the best solution, but I ended up doing the following to get it to work.更新:不知道这是否是最佳解决方案,但我最终执行了以下操作以使其正常工作。
...
case "C":
services.AddTransient<ServiceA>();
services.AddTransient<ServiceB>();
services.AddTransient<IService>(s =>
new ServiceC(
s.GetService<ServiceA>(),
s.GetService<ServiceB>()
));
Another alternative.另一种选择。 Introduce another interface, so you can register the both ServiceC
and it's dependencies at the same time, without any ambiguity or circular references.引入另一个接口,这样您就可以同时注册ServiceC
及其依赖项,而不会出现任何歧义或循环引用。
interface IService {}
interface IServiceImpl : IService {}
ServiceA : IServiceImpl { public ServiceA(IDependencyA A, IDependency B) {...} }
ServiceB : IServiceImpl { public ServiceB(IDependencyA A, IDependency B) {...} }
ServiceC : IService { public ServiceC(IEnumerable<IServiceImpl> services) {...} }
services.AddTransient<IServiceImpl, ServiceA>();
services.AddTransient<IServiceImpl, ServiceB>();
services.AddTransient<IService, ServiceC>();
There must be a better explanation for having such dependencies.对于这种依赖关系必须有更好的解释。
Microsoft.Extensions.DependencyInjection does not provide named registrations like other IoC containers ie Castle.Windsor. Microsoft.Extensions.DependencyInjection 不像其他 IoC 容器(即 Castle.Windsor)那样提供命名注册。
There is a way you can still register ServiceC with instances of A and B有一种方法你仍然可以用 A 和 B 的实例注册 ServiceC
services.AddTransient<ServiceA>();
services.AddTransient<ServiceB>();
services.AddTransient<IService>(serviceProvider => {
return new ServiceC((IService)serviceProvider.GetRequiredService(typeof(ServiceA)), (IService)serviceProvider.GetRequiredService(typeof(ServiceB)));
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.