2011-04-07 54 views
1

因此,在高层次上,我理解了依赖注入的概念。我们公司希望采用这种做法,我认为这是一个好主意,但我需要更多信息并提出一些问题。如何做ASP.NET依赖注入

  1. 什么是良好或最流行的依赖注入容器?我听说过ninject,这对.NET 4 Webforms有效吗?微软是否拥有可能更好的专有DI容器?

  2. 我们的应用程序的结构是这样的:

    • 解决方案
      • UI项目(ASP.NET Web应用程序)
      • 业务层(类库)
      • 数据访问层(类库)
    • 数据访问层包含用于访问数据的存储库类。这些存储库位于业务层交互的接口下。
    • 业务层具有包含通用功能的“控制器”类(不要与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 Container在什么时候接管并注入IOrderRepository的实例?会不会有某种工厂,所以我可以做OrderController _orderController = OrderControllerFactory.Create()或类似的东西?我有点迷路。

让我知道我是否需要澄清一些事情。谢谢。

+0

参见这篇文章:http://bit.ly/gbEjv0。它适用于每个DI容器。 – Steven 2011-04-07 20:34:20

+0

我只有exp与Ninject。控制器结构的方式,ninject会因为构造函数注入而很好地适应。 – 2011-04-07 20:35:00

+0

感谢您的文章。现在阅读。 – Chev 2011-04-07 20:55:19

回答

4

我的首选是坚持使用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; } 
    } 
} 
+0

你能澄清你包含的代码的后半部分吗?所以'ConfigureUnity()'方法进入global.asax.cs,'CreateOrderController()'和'WebUnityContainer'去哪里? 'ConfigureUnity()'被调用到什么地方?另外,'.RegisterInstance(new OrderController())'不会被编译,因为OrderController没有一个构造函数,它的参数为零。 – Chev 2011-04-07 21:59:00

+0

WebUnityContainer类可以添加到您的业务模块,因为Web类和您的域类都需要访问。在你的Application_Start()方法中的Global.asax.cs中调用ConfigureUnity()。 – Winger 2011-04-07 22:10:16

+1

哎呀,我的坏。尝试像这样注册OrderController:.RegisterType (),当您在UnityContainer上调用Resolve()时,它会使用具有最多参数的构造函数创建对象,并解析传递给该构造函数的每个接口的依赖关系。 – Winger 2011-04-07 22:12:29

0

使用结构图在这里。

http://structuremap.net/structuremap/

在构造图是这样的:

ObjectFactory.GetInstance(Of OrderController) 

约结构地图尼斯链接:

http://weblogs.asp.net/shijuvarghese/archive/2008/10/10/asp-net-mvc-tip-dependency-injection-with-structuremap.aspx

Which .NET Dependency Injection frameworks are worth looking into?

开源应用程序:

用途团结,另一个很好的依赖注入框架:http://kigg.codeplex.com/

我1〜2年前有同样的问题,我一直在使用StructureMap从那时起,我很喜欢它,但我知道其他框架,如Ninject和StructureMap一样好。