在Base Controller中实现依赖注入的最佳方法是什么?

时间:2018-03-21 12:42:40

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

我有跟随麻烦,在我的基础控制器中我做依赖注入。我有一个基类控制器实现的类子,我需要传递构造函数。所以我怀疑,我实现依赖注入的方法是正确的吗? 如果不是,最好的方法是什么?

我使用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;
        }

2 个答案:

答案 0 :(得分:2)

您不需要反复定义私有字段servico,因为它已在基本控制器中预设。只需在基类中将其定义为protected readonly并在子项中使用它。

除了你的代码没问题。

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

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

答案 1 :(得分:1)

您见过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.
}
}

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