StructureMap使用方法(轉)


終於到了題目中的MVC使用StructureMap依賴注入的配置與實現了。在ASP.Net三層架構應用中StructureMap的是最老的IOC/DI工具,也就是依賴注入,很多線上的項目都使用了StructureMap,非常酷的是他是免費的,具體的IOC/DI的設計思想本篇文章不做介紹,想研究可以百度一下,資料很多,哎說道百度想起google一堆淚啊,自從google撤出中國,google是經常的無法訪問,很無奈啊很無奈。

 

依賴注入主要有兩種方式:一種是Setter and Getter,一種是構造函數方式。天屹的這套框架使用的后者Constructor構造器的方式。如果你看了前面的文章,就會發現每個Service和Controller中都會有一個構造方法,沒錯我們就是使用的它們,接下詳細的介紹一下StructureMap是怎么在我們的項目中實現依賴注入的。

mvc-structuremap

一.配置與注冊Services和Repositories

首先我們告訴StructureMap,我們需要注入的是什么,本系統中需要注冊的是Services和Repositories,分別注入到Controller和Service。下面是具體寫法,為什么這么寫,不必較真,寫法是StructureMap提供給我們的,使用就好了。

查看代碼    
  1. using  System ;
  2. using  System.Collections.Generic ;
  3. using  System.Linq ;
  4. using  System.Text ;
  5. using  System.Threading.Tasks ;
  6. using  StructureMap ;
  7.  
  8. namespace TYStudioDemo. StructureMap
  9. {
  10.      public  class BootStrapper
  11.     {
  12.          public  static  void ConfigureStructureMap()
  13.         {
  14.             ObjectFactory. Configure(x  =>
  15.             {
  16.                 x. AddRegistry( new TYStudioDemoStructureMapRegistry()) ;
  17.  
  18.                 x. Scan(scanner  =>
  19.                 {
  20.                     scanner. Assembly( "TYStudioDemo.Services") ;
  21.                     scanner. Assembly( "TYStudioDemo.Repositories") ;
  22.                 }) ;
  23.             }) ;
  24.         }
  25.     }
  26. }

 

上面的代碼告訴了StructureMap去哪里找我們的Service和Repositories。同時TYStudioDemoStructureMapRegistry這個類告訴了StructureMap該用哪個類去實例化我們的接口,下面是TYStudioDemoStructureMapRegistry的代碼:

查看代碼    
  1. using  System ;
  2. using  System.Collections.Generic ;
  3. using  System.Linq ;
  4. using  System.Text ;
  5. using  System.Data ;
  6. using  StructureMap.Configuration.DSL ;
  7. using  TYStudioDemo.Models ;
  8. using  TYStudioDemo.DTO ;
  9. using  TYStudioDemo.Interfaces ;
  10. using  TYStudioDemo.Services ;
  11. using  TYStudioDemo.Repositories ;
  12.  
  13. namespace TYStudioDemo. StructureMap
  14. {
  15.      public  class TYStudioDemoStructureMapRegistry  : Registry
  16.     {
  17.          //注冊接口實際使用的實現類
  18.          public TYStudioDemoStructureMapRegistry()
  19.         {
  20.             SelectConstructor <TYEntities >(()  =>  new TYEntities()) ;
  21.  
  22.              //Exception Handle
  23.              For <ITYExceptionService >(). Use <TYExceptionService >() ;
  24.  
  25.              //Services
  26.              For( typeof(ISupplierService)). Use( typeof(SupplierService)) ;
  27.  
  28.              //Repositories
  29.              For( typeof(ISupplierRepository <>)). Use( typeof(SupplierRepository)) ;
  30.              For( typeof(IProductRepository <>)). Use( typeof(ProductRepository)) ;
  31.         }
  32.     }
  33. }

現在我們已經配置了StructureMap並且注冊了Service和Repository,接下來該告訴系統去使用StructureMap去實例化我們的Controller。

二.創建Controller Factory

既然使用了依賴注入,Controller的實例化當然不能再用系統本身的了,所以我們需要創建一個ControllerFactory:TYStudioDemoStructureMapControllerFactory。

查看代碼    
  1. using  System ;
  2. using  System.Collections.Generic ;
  3. using  System.Linq ;
  4. using  System.Text ;
  5. using  System.Threading.Tasks ;
  6. using  System.Web.Mvc ;
  7. using  StructureMap ;
  8.  
  9. namespace TYStudioDemo. StructureMap
  10. {
  11.      public  class TYStudioDemoStructureMapControllerFactory  : DefaultControllerFactory
  12.     {
  13.          protected  override IController GetControllerInstance(System. Web. Routing. RequestContext requestContext, System. Type controllerType)
  14.         {
  15.              if (controllerType  !=  null)
  16.             {
  17.                 Controller c  = ObjectFactory. GetInstance(controllerType)  as Controller ;
  18.  
  19.                  //當返回一個錯誤頁面,View一級異常會被觸發
  20.                 c. ActionInvoker  =  new ErrorHandlingActionInvoker( new HandleErrorAttribute()) ;
  21.                  return c ;
  22.             }
  23.              else
  24.                  return null ;
  25.         }
  26.     }
  27. }

 

TYStudioDemoStructureMapControllerFactory繼承自DefaultControllerFactory,DefaultControllerFactory是MVC默認的Controller Factory,然后重新器獲得Controller實例的方法,由StructureMap的ObjectFactory來創建實例,StructureMap會幫我們把Controller構造函數中的參數實例化。

上面的ErrorHandlingActionInvoker方法:

查看代碼    
  1. using  System ;
  2. using  System.Collections.Generic ;
  3. using  System.Linq ;
  4. using  System.Text ;
  5. using  System.Web.Mvc ;
  6.  
  7. namespace TYStudioDemo. StructureMap
  8. {
  9.      public  class ErrorHandlingActionInvoker  : ControllerActionInvoker
  10.     {
  11.          private  readonly IExceptionFilter filter ;
  12.  
  13.          public ErrorHandlingActionInvoker(IExceptionFilter filter)
  14.         {
  15.              if (filter  ==  null)
  16.                  throw  new ArgumentNullException( "Exception filter is missing") ;
  17.  
  18.              this. filter  = filter ;
  19.         }
  20.  
  21.          protected  override FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
  22.         {
  23.             var filterInfo  =  base. GetFilters(controllerContext, actionDescriptor) ;
  24.             filterInfo. ExceptionFilters. Add( this. filter) ;
  25.              return filterInfo ;
  26.         }
  27.     }
  28. }

Controller Factory創建ok。但是這樣系統是不會使用我們自己的Controller Factory的,所以需要通知一下MVC系統。

三.配置Global.asax文件

在Application_Start()方法中也就是項目啟動的時候注冊StructureMap並通知系統使用我們自己的Controller Factory進行實例化Controller。

查看代碼    
  1. using  System ;
  2. using  System.Collections.Generic ;
  3. using  System.Linq ;
  4. using  System.Web ;
  5. using  System.Web.Http ;
  6. using  System.Web.Mvc ;
  7. using  System.Web.Optimization ;
  8. using  System.Web.Routing ;
  9. using  TYStudioDemo.StructureMap ;
  10.  
  11. namespace TYStudioDemo. WebUI
  12. {
  13.      // Note: For instructions on enabling IIS6 or IIS7 classic mode,
  14.      // visit http://go.microsoft.com/?LinkId=9394801
  15.  
  16.      public  class MvcApplication  : System. Web. HttpApplication
  17.     {
  18.          protected  void Application_Start()
  19.         {
  20.             AreaRegistration. RegisterAllAreas() ;
  21.  
  22.             WebApiConfig. Register(GlobalConfiguration. Configuration) ;
  23.             FilterConfig. RegisterGlobalFilters(GlobalFilters. Filters) ;
  24.             RouteConfig. RegisterRoutes(RouteTable. Routes) ;
  25.             BundleConfig. RegisterBundles(BundleTable. Bundles) ;
  26.             AuthConfig. RegisterAuth() ;
  27.  
  28.              //注冊StructureMap
  29.             BootStrapper. ConfigureStructureMap() ;
  30.  
  31.              //通過StructureMap返回Controller實例,通過構造器注入
  32.             ControllerBuilder. Current. SetControllerFactory( new TYStudioDemoStructureMapControllerFactory()) ;
  33.         }
  34.  
  35.          protected  void Application_EndRequest( object sender, EventArgs e)
  36.         {
  37.             TYStudioDemo. Models. TYEntities. Cleanup() ;
  38.         }
  39.     }
  40. }

ok,到此StructureMap的配置就全部完成了,接下來我們該怎么使用它呢。

文章開頭已經告訴大家了我們使用Constructor構造器的方式進行依賴注入。

四.Controller的寫法

既然是構造器就要寫構造函數了,見下面寫法:

查看代碼    
  1. ISupplierService _supplierService ;
  2.  
  3. public SupplierController(ITYExceptionService tyExceptionService,
  4.                             ISupplierService supplierService)
  5. {
  6.     _tyExceptionService  = tyExceptionService ;
  7.     _supplierService  = supplierService ;
  8.  
  9. }

在構造方法中加入我們要注入的Service接口,然后StructureMap就會根據上面TYStudioDemoStructureMapRegistry的配置去創建我們需要實例化的service對象了。

同樣向Service中注入Repository的寫法是一樣的:

查看代碼    
  1. ISupplierRepository <Supplier > _supplierRepository ;
  2. IProductRepository <Product > _productRepository ;
  3.  
  4. public SupplierService(ISupplierRepository <Supplier > supplierRepotitory,
  5.                             IProductRepository <Product > productRepository)
  6. {
  7.     _supplierRepository  = supplierRepotitory ;
  8.     _productRepository  = productRepository ;
  9. }

至此StructureMap配置與使用就全部完成了。

總結:

我們發現,我們的參數都是接口類型了,這樣的好處就是將來對ISupplierService的實現不一樣了,我們只需要重寫寫一個ISupplierService的實現了,並修改TYStudioDemoStructureMapRegistry使ISupplierService使用新的實現類,就可以了。因為我們使用的都是接口所以方法和參數都是固定的,所以呢~~ Controller中不用修改任何代碼,同理Service也是一樣的。這樣就充分的降低了代碼之間的耦合度。

下篇文章將介紹使用Enterprise Library 5.0 實現異常與日志的處理。

 

轉自:http://www.tystudio.net/2013/04/06/mvc-structuremap-config/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM