IoC實踐--用Autofac實現MVC5.0的IoC控制反轉方法
阿新 • • 發佈:2019-01-22
EFDbContext定義的EF類,我這裡是用EF框架來實現讀取資料庫記錄,當然你可以用純的ADO、或者其它框架如ibatis.Net、Nhibernate、dapper等。
Autofac是一個.net平臺下發效能還不錯的IoC框架,利用它可以實現依賴注入和控制反轉,使自己的軟體模組之間的耦合性大大降低,讓軟體擴充套件、維護更加容易。控制反轉(Inversion of Control,英文縮寫為IoC)是一個重要的面向物件程式設計的法則來削減計算機程式的耦合問題。下面我就用Autofac實現ASP.NET mvc5.0的IOC控制反轉的方法。這裡用到是vs2013,Autofac ASP.NET MVC 5 Integration和mvc 5.0。Autofac ASP.NET MVC 5 Integration是Autofac的MVC封裝庫,我們只需要很少的程式碼就可以實現依賴注入。下面請看詳細例項。
1、下載安裝相關程式碼
在你的web專案右鍵選擇“管理nuget程式包”選中左邊的聯機,然後在搜尋的輸入框輸入“autofac”
選中Autofac ASP.NET MVC 5 Integration,點選安裝,這樣你的專案就下載Autofac ASP.NET MVC 5 Integration了這個相關的dll的引用,並自動給添加了相關引用。
2、案例展示
定義一個業務介面IProductRepository,用來獲取所有產品public interface IProductRepository { IQueryable<Product> Products { get定義一個業務具體類,實現IProductRepository介面; } }
![複製程式碼](http://common.cnblogs.com/images/copycode.gif)
public class EFProductRepository : IProductRepository { private EFDbContext context = new EFDbContext(); public IQueryable<Product> Products { get { return context.Products; } } }
![複製程式碼](http://common.cnblogs.com/images/copycode.gif)
2.1、定義一個Controller依賴IProductRepository介面
![複製程式碼](http://common.cnblogs.com/images/copycode.gif)
public class BuyController : Controller { private IProductRepository repository; public BuyController(IProductRepository repo) { repository = repo; } //此處省略其它程式碼 }
![複製程式碼](http://common.cnblogs.com/images/copycode.gif)
2.2、繫結IProductRepository介面依賴的具體實現的類
![複製程式碼](http://common.cnblogs.com/images/copycode.gif)
using Autofac; using Autofac.Integration.Mvc; using System; using System.Collections.Generic; using System.Configuration; using System.linq; using System.Web; using System.Web.Mvc; using WenMarine.BLL.Abstract; using WenMarine.BLL.Concrete; using WenMarine.Web.Infrastructure.Abstract; using WenMarine.Web.Infrastructure.Concrete; namespace WenMarine.Web.Infrastructure { public class IocConfig { public static void RegisterDependencies() { var builder = new ContainerBuilder(); builder.RegisterControllers(typeof(MvcApplication).Assembly); builder.RegisterType<EFProductRepository>().As<IProductRepository>(); //autofac 註冊依賴 IContainer container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); } } }
![複製程式碼](http://common.cnblogs.com/images/copycode.gif)
2.3、呼叫IocConfig使依賴生效
![複製程式碼](http://common.cnblogs.com/images/copycode.gif)
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); IocConfig.RegisterDependencies(); }
![複製程式碼](http://common.cnblogs.com/images/copycode.gif)
3、總結
通過上面可以看到,BuyController(高層模組)中是引用一個IProductRepository抽象介面而不是具體的實現EFProductRepository(具體模組)類。這樣做到依賴倒置,也就是控制反轉。這裡高層模組(BuyController)不依賴於底層模組(EFProductRepository裡面的讀取資料庫操作的低層程式碼),二者都同依賴於抽象(IProductRepository);抽象不依賴於具體(EFProductRepository),具體依賴於抽象。 這裡BuyController中的IProductRepository到底是哪個實現,是通過IocConfig類使用autofac的來註冊繫結的。這樣如果以後要更改資料庫讀取方式,考慮到效能問題,比如不用EF了框架了,要用Dapper,直接新建一個類DapperProductRepository繼承IProductRepository介面,實現Products 屬性。 最後把IocConfig中builder.RegisterType<EFProductRepository>().As<IProductRepository>(); 改為 builder.RegisterType<DapperProductRepository >().As<IProductRepository>();就可以了。這樣BuyController高層的程式碼根本不用改,這樣做到了對擴充套件開發,對修改關閉(OCP-面向物件的開放封閉原則),這個是面向物件程式設計的核心。很好的做到的鬆耦合,模組之間的耦合性大大降低,讓軟體擴充套件、維護更加容易。