繁体   English   中英

如何在 ASP NET Core 中使用 DI 注入特定的接口实现

[英]How to inject specific interface implementation using DI in ASP NET Core

我有以下问题。 我有一个由 2 个类实现的接口。 其中一个类执行实际工作,而另一个使用提到的第一个类。 在实例化 object 类型时,如何告诉框架使用接口的特定实现? 我希望 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();
   }

}

正如您在上面的示例中看到的,我需要在我的Facade中注入一种Real类型的IDependency ,而我需要在MyController中注入一种Facade类型的IDependency 怎么可能做到这一点?

Microsoft.Extensions.DependencyInjection 没有任何方法可以做到这一点。 您所能做的就是注入所有实现,即通过List<IDependency> 然后,您可以从那里的可用选项中实现您想要选择的任何手动逻辑。

如果您对这些类有任何控制权,最好简单地实现一个不同的接口,以区分两者。 例如,您可以创建一个从IDependency继承的IFacadeDependency接口,然后让您的Facade class 实现它。 然后,您可以注入IFacadeDependency并得到您想要的。

按如下方式注册您的依赖项:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddTransient<IDependency>(_ => new Facade(new Real()));
}

如果您有其他控制器需要不同的 IDependency 实现,您需要将控制器注册为服务,从而允许覆盖注册。 例如,如果您希望大多数控制器将 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM