[英]How to inject specific interface implementation using DI in ASP NET Core
I have the following problem.我有以下问题。 I have an interface that is implemented by 2 classes.我有一个由 2 个类实现的接口。 One of these classes does the real work while the other uses the first one mentioned.其中一个类执行实际工作,而另一个使用提到的第一个类。 How can I tell the framework to use a specific implementation of an interface when instantiating a type of object?在实例化 object 类型时,如何告诉框架使用接口的特定实现? I want the controller to get the facade implementation and not the real one:我希望 controller 获得外观实现,而不是真正的实现:
public interface IDependency
{
void Method();
}
public class Real : IDependency
{
public void Method()
{
}
}
public class Facade : IDependency
{
private IDependency dependency;
Facade(IDependency dependency) //I want a Real here
{
this.dependency=dependency;
}
public void Method()=>dependency.Method();
}
public MyController : Controller
{
private IDependency dependency;
MyController(IDependency dependency) //I want the `Facade` here not the `Real`
{
this.dependency=dependency;
}
[HttpGet]
[Route("[some route]")]
public async Task CallMethod()
{
await this.dependency.Method();
}
}
As you can see in the above example, I need a Real
type of IDependency
injected inside my Facade
one, while I need a Facade
type of IDependency
injected in my MyController
.正如您在上面的示例中看到的,我需要在我的Facade
中注入一种Real
类型的IDependency
,而我需要在MyController
中注入一种Facade
类型的IDependency
。 How could that be done?怎么可能做到这一点?
Microsoft.Extensions.DependencyInjection doesn't have any means to do this. Microsoft.Extensions.DependencyInjection 没有任何方法可以做到这一点。 All you can do is inject all implementations, ie via List<IDependency>
.您所能做的就是注入所有实现,即通过List<IDependency>
。 Then, you can implement whatever manual logic you'd like to pick and choose from the available options there.然后,您可以从那里的可用选项中实现您想要选择的任何手动逻辑。
If you have any control over these classes, it would be better to simply implement a different interface, to distinguish the two.如果您对这些类有任何控制权,最好简单地实现一个不同的接口,以区分两者。 For example, you could create an IFacadeDependency
interface that inherits from IDependency
, and then have your Facade
class implement that instead.例如,您可以创建一个从IDependency
继承的IFacadeDependency
接口,然后让您的Facade
class 实现它。 Then, you can inject IFacadeDependency
and get exactly what you want.然后,您可以注入IFacadeDependency
并得到您想要的。
Register your dependency as follows:按如下方式注册您的依赖项:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddTransient<IDependency>(_ => new Facade(new Real()));
}
If you have other controllers that need a different implementation of IDependency, you'll want to register your controllers as services, allowing the registrations to be overwritten.如果您有其他控制器需要不同的 IDependency 实现,您需要将控制器注册为服务,从而允许覆盖注册。 For example, if you want most controllers to resolve with IDependency as Real, but only MyController to resolve IDependency as Facade, you could do this:例如,如果您希望大多数控制器将 IDependency 解析为 Real,但只有 MyController 将 IDependency 解析为 Facade,您可以这样做:
public void ConfigureServices(IServiceCollection services)
{
// Adds controllers as services, allowing their registrations to be overwritten.
services.AddMvc().AddControllersAsServices();
//services.AddControllers(); REMOVE THIS
// Makes Real the default implementation of IDependency
services.AddTransient<IDependency, Real>();
// Overwrite the default registration of MyController to instantiate using Facade.
services.AddTransient<MyController>(sp =>
new MyController(new Facade(sp.GetService<IDependency>())));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.