Как внедрить конкретную реализацию интерфейса c с использованием DI в ASP NET Core - PullRequest
0 голосов
/ 07 мая 2020

Здравствуйте, у меня следующая проблема. У меня есть интерфейс, который реализован двумя классами. Один из этих классов выполняет реальную работу, а другой использует первый из упомянутых. Как я могу указать фреймворку использовать конкретную c реализацию интерфейса при создании экземпляра типа объекта? Я хочу, чтобы контроллер получил фасадную реализацию, а не реальную:

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. Как это могло быть сделано?

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Зарегистрируйте свою зависимость следующим образом:

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>())));
    }
0 голосов
/ 07 мая 2020

Microsoft.Extensions.DependencyInjection не имеет для этого никаких средств. Все, что вы можете сделать, это внедрить все реализации, то есть через List<IDependency>. Затем вы можете реализовать любой ручной logi c, который вы хотите выбрать, и выбрать из доступных вариантов.

Если у вас есть какой-либо контроль над этими классами, было бы лучше просто реализовать другой интерфейс , чтобы различать guish два. Например, вы можете создать интерфейс IFacadeDependency, наследующий от IDependency, а затем вместо этого реализовать его в своем классе Facade. Затем вы можете ввести IFacadeDependency и получить именно то, что хотите.

...