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

问题描述 投票:0回答:2

你好,我有以下问题,我有一个接口是由2个类实现的,其中一个类做真正的工作,而其他使用第一个提到的,我如何告诉框架在实例化一个类型的对象时,使用一个特定的接口实现?我希望控制器得到的是facaded实现,而不是真正的实现。

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();
   }

}

正如你可以看到在上面的例子中,我需要一个 Real 类型 IDependency 注射到我的体内 Facade 一个,而我需要一个 Facade 类型 IDependency 注入 MyController.如何才能做到这一点?

asp.net-core dependency-injection facade
2个回答
0
投票

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

如果你对这些类有任何控制,最好是简单地实现一个不同的接口,以区分两者。例如,你可以创建一个 IFacadeDependency 接口,继承自 IDependency然后让你的 Facade 类来实现这个功能。然后,你可以注入 IFacadeDependency 并得到你想要的东西。


1
投票

按如下方式注册你的依赖。

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>())));
    }
© www.soinside.com 2019 - 2024. All rights reserved.