因此,在较高的层次上,我了解了依赖注入的概念。我们公司希望采用这种做法,我认为这是个好主意,但我需要更多信息,并有几个问题。


什么是好的或最受欢迎的依赖项注入容器?我听说过ninject,它可以与.NET 4 Webforms一起很好地工作吗? Microsoft是否拥有可能会更好的专有DI容器?
我们的应用程序结构如下:




UI项目(ASP.NET Web App)
业务层(类库)
数据访问层(类库)

数据访问层包含用于访问数据的存储库类。这些存储库位于与业务层进行交互的接口下。
业务层具有包含通用功能的“控制器”类(不要与MVC控制器混淆)。



这是我们业务层的示例控制器:

public class OrderController
{
    IOrderRepository _orderRepository;

    public OrderController(IOrderRepository orderRepository)
    {
        _orderRepository = orderRepository;
    }

    public List<string> GetFilters()
    {
        // Return list of filters.
    }

    public List<Order> GetFilteredOrders(string filter)
    {
        switch (filter)
        {
            case "Newest":
                return // Get orders sorted by newest first.
            case "Oldest":
                return // Get orders sorted by oldest first.
            default:
                return // etc etc etc
        }
    }
}


如您所见,这采用了IOrderRepository的注入实例,以便于进行单元测试。 OrderController当前在需要使用它的相应页面后面的代码中实例化。我们不想在实例化IOrderRepository的每个地方都创建一个新的OrderController,这是我们要使用DI的地方。

实现此目的的最佳方法是什么? DI容器在什么时候接管并注入IOrderRepository实例?是否会有某种工厂,以便我可以做OrderController _orderController = OrderControllerFactory.Create()之类的事情?我有点迷路了。

让我知道是否需要澄清一下。谢谢。

最佳答案

我的首选是坚持使用Microsoft堆栈并使用Unity。尽管我有一些在项目中使用Ninject并喜欢它的同事。

这是我如何在Web应用程序中执行此操作的方式(MVC应用程序的参与程度略高):

using Microsoft.Practices.Unity;

public class OrderController
{
    IOrderRepository _orderRepository;

    [InjectionConstructor]
    public OrderController(IOrderRepository orderRepository)
    {
        _orderRepository = orderRepository;
    }

    public List<string> GetFilters()
    {
        // Return list of filters.
    }

    public List<Order> GetFilteredOrders(string filter)
    {
        switch (filter)
        {
            case "Newest":
                return // Get orders sorted by newest first.
            case "Oldest":
                return // Get orders sorted by oldest first.
            default:
                return // etc etc etc
        }
    }
}


///
/// From Global.asax.cs

using Microsoft.Practices.Unity;

private void ConfigureUnity()
{
    // Create UnityContainer
    IUnityContainer container = new UnityContainer()
    .RegisterInstance(new OrderController())
    .RegisterType<IOrderRepository, OrderRepository>();

    // Set container for use in Web Forms
    WebUnityContainer.Container = container;
}

///
/// Creating the OrderController from your Web UI

public OrderController CreateOrderController()
{
    return WebUnityContainer.Container.Resolve<OrderController>();
}

///
/// Shared static class for the Unity container

using Microsoft.Practices.Unity;

namespace MyCompany.MyApplication.Web
{
    public static class WebUnityContainer
    {
        public static IUnityContainer Container { get; set; }
    }
}

08-17 12:52