【问题标题】:What is the best way to implement Dependency Injection in Base Controller在基本控制器中实现依赖注入的最佳方法是什么
【发布时间】:2018-08-30 14:11:37
【问题描述】:

我遇到了以下问题,在我的基本控制器中,我进行了依赖注入。而且我有一个实现基本控制器的类子,我需要传递构造函数。所以我的疑问是,我实现依赖注入的方式是否正确? 如果不是,最好的方法是什么?

我用unity实现D.I,我的ide是VS2017 web api 2。

按照我使用的以下代码: 基本控制器或父控制器:

public class BaseController : ApiController
{
    public string[] includes = null;

    private readonly IFiltroServico servico;
    public BaseController(IFiltroServico _servico)
    {
        servico = _servico;
    }
}

基本控制器到泛型类型实现基本控制器:

 public abstract class BaseController<E, R, F> : BaseController
        where E : class
        where R : class
        where F : class
    {
    private readonly IFiltroServico servico;
            public AreaFormacaoController(IFiltroServico _servico): base(_servico)
            {
                servico = _servico;
            }
}

儿童控制器:

    public abstract class BaseController<R> : BaseController
            where R : class
        {
private readonly IFiltroServico servico;
        public AreaFormacaoController(IFiltroServico _servico): base(_servico)
        {
            servico = _servico;
        }
     //services of controller;
        }

【问题讨论】:

  • 在基本控制器中没有使用 DI 的好方法,nor is there a good reason to have one in the first place
  • @NightOwl888 我决定做 DI,因为我的基本控制器是非常通用的,即不管它会工作的类型,由于使用 FilterService 来减少对具有有效类型的控制器。但是我仍然做了更多的工作来学习使用 DI 并知道如何在系统中正确应用它。我已经阅读了您的更多回复,因此在这种情况下如何应用 DI 还不够清楚。

标签: c# rest asp.net-web-api dependency-injection


【解决方案1】:

您不需要一遍又一遍地定义私有字段servico,因为它已经预设在基本控制器中。只需在基类中将其定义为protected readonly 并在子类中使用即可。

除此之外,您的代码还可以。

一个子类在构造函数中具有相同的依赖项参数是完全合理的,因为它继承了最有可能依赖于依赖项的基类的行为。

另一种选择是在基类中使用property injection,但您需要向属性添加一个统一特定属性。我不喜欢你将代码直接绑定到 Unity。

【讨论】:

    【解决方案2】:

    你见过https://simpleinjector.org/index.html

    https://github.com/simpleinjector/SimpleInjector查看 git

    它是最好的控制反转库 (IOC) 之一。

    您只需注册所有服务和类型。

    using SimpleInjector;
    
    static class Program
    {
    static readonly Container container;
    
    static Program() {
        // 1. Create a new Simple Injector container
        container = new Container();
    
        // 2. Configure the container (register)
        container.Register<IOrderRepository, SqlOrderRepository>();
        container.Register<ILogger, FileLogger>(Lifestyle.Singleton);
        container.Register<CancelOrderHandler>();
    
        // 3. Verify your configuration
        container.Verify();
    }
    
    static void Main(string[] args)) {
        // 4. Use the container
        var handler = container.GetInstance<CancelOrderHandler>();
    
        var orderId = Guid.Parse(args[0]);
        var command = new CancelOrder { OrderId = orderId };
    
        handler.Handle(command);
    }
    }
    

    一旦你注册了所有类型和服务,你就可以在任何你想要的地方注入这些服务

    public class CancelOrderHandler {
    private readonly IOrderRepository repository;
    private readonly ILogger logger;
    private readonly IEventPublisher publisher;
    
    // Use constructor injection for the dependencies
    public CancelOrderHandler(
        IOrderRepository repository, ILogger logger, IEventPublisher publisher) {
        this.repository = repository;
        this.logger = logger;
        this.publisher = publisher;
    }
    
    public void Handle(CancelOrder command) {
        this.logger.Log("Cancelling order " + command.OrderId);
        var order = this.repository.GetById(command.OrderId);
        order.Status = OrderStatus.Cancelled;
        this.repository.Save(order);
        this.publisher.Publish(new OrderCancelled(command.OrderId));
    }
    }
    
    public class SqlOrderRepository : IOrderRepository {
    private readonly ILogger logger;
    
    // Use constructor injection for the dependencies
    public SqlOrderRepository(ILogger logger) {
        this.logger = logger;
    }
    
    public Order GetById(Guid id) {
        this.logger.Log("Getting Order " + order.Id);
        // Retrieve from db.
    }
    
    public void Save(Order order) {
        this.logger.Log("Saving order " + order.Id);
        // Save to db.
    }
    }
    

    如果您有任何疑问,请告诉我,谢谢。

    【讨论】:

      猜你喜欢
      • 2018-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多