首先看下Demo2的結構
分享下demo源碼 :http://pan.baidu.com/s/1qYtZCrM
然后下面一步步將Autofac集成到mvc中。
首先,定義Model Product.cs

public class Product { public int Id { get; set; } public string Name { get; set; } public double Price { get; set; } public string Remark { get; set; } public DateTime Date { get; set; } }
第二步 創建文件夾IRepository 用於存放倉儲接口IProductRepository

public interface IProductRepository { IEnumerable<Product> GetAll(); Product Get(int id); Product Add(Product item); bool Update(Product item); bool Delete(int id); }
第三步 創建文件夾Repository 定義ProductRepository 實現IProductRepository倉儲接口

public class ProductRepository : IProductRepository { private List<Product> Products = new List<Product>(); public ProductRepository() { Add(new Product { Id = 1, Name = "手機", Price = 100, Remark = "4g 手機", Date = DateTime.Now.AddDays(-1) }); Add(new Product { Id = 2, Name = "電腦", Price = 120, Remark = "筆記本本", Date = DateTime.Now.AddDays(-2) }); Add(new Product { Id = 3, Name = "bb機", Price = 10, Remark = "大時代必備", Date = DateTime.Now.AddDays(-1100) }); Add(new Product { Id = 4, Name = "pad", Price = 130, Remark = "mini 電腦", Date = DateTime.Now }); } public IEnumerable<Product> GetAll() { return Products; } public Product Get(int id) { return Products.Find(p => p.Id == id); } public Product Add(Product item) { if (item == null) { throw new ArgumentNullException("item"); } Products.Add(item); return item; } public bool Update(Product item) { if (item == null) { throw new ArgumentNullException("item"); } int index = Products.FindIndex(p => p.Id == item.Id); if (index == -1) { return false; } Products.RemoveAt(index); Products.Add(item); return true; } public bool Delete(int id) { Products.RemoveAll(p => p.Id == id); return true; } }
ok,WebApplication_AutoFac引用AutoFac_Demo2 以及從VS中的NuGet來加載Autofac.Integration.Mvc
下一步定義ProductController 這里我們用構造器注入

public class ProductController : Controller { readonly IProductRepository repository; //構造器注入 public ProductController(IProductRepository repository) { this.repository = repository; } // GET: /Product/ public ActionResult Index() { var data = repository.GetAll(); return View(data); } }
index頁也比較簡單,用vs根據model生成的list頁

@model IEnumerable<AutoFac_Demo2.Model.Product> @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>Index</h2> <p> @Html.ActionLink("Create New", "Create") </p> <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.Name) </th> <th> @Html.DisplayNameFor(model => model.Price) </th> <th> @Html.DisplayNameFor(model => model.Remark) </th> <th> @Html.DisplayNameFor(model => model.Date) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.DisplayFor(modelItem => item.Price) </td> <td> @Html.DisplayFor(modelItem => item.Remark) </td> <td> @Html.DisplayFor(modelItem => item.Date) </td> <td> @Html.ActionLink("Edit", "Edit", new { id=item.Id }) | @Html.ActionLink("Details", "Details", new { id=item.Id }) | @Html.ActionLink("Delete", "Delete", new { id=item.Id }) </td> </tr> } </table>
最后最關鍵的實現注入
protected void Application_Start() { //創建autofac管理注冊類的容器實例 var builder = new ContainerBuilder(); //下面就需要為這個容器注冊它可以管理的類型 //builder的Register方法可以通過多種方式注冊類型,之前在demo1里面也演示了好幾種方式了。 builder.RegisterType<ProductRepository>().As<IProductRepository>(); //使用Autofac提供的RegisterControllers擴展方法來對程序集中所有的Controller一次性的完成注冊 builder.RegisterControllers(Assembly.GetExecutingAssembly());//生成具體的實例 var container = builder.Build(); //下面就是使用MVC的擴展 更改了MVC中的注入方式. DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); }
其實除了構造函數注入還可以屬性注入 把之前repository 改為get set 就變成屬性了
public class ProductController : Controller { #region //readonly IProductRepository repository; ////構造器注入 //public ProductController(IProductRepository repository) //{ // this.repository = repository; //} #endregion public IProductRepository repository { get; set; } // GET: /Product/ public ActionResult Index() { var data = repository.GetAll(); return View(data); } }
然后,將
//使用Autofac提供的RegisterControllers擴展方法來對程序集中所有的Controller一次性的完成注冊 builder.RegisterControllers(Assembly.GetExecutingAssembly());
改為
builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired(); // 這樣支持屬性注入
最后效果:
最后的最后,為了不像 builder.RegisterType<ProductRepository>().As<IProductRepository>(); 這樣一個一個的注冊,所以要像裝載controller一樣完成自動注入
自動注入
Autofac提供一個RegisterAssemblyTypes方法。它會去掃描所有的dll並把每個類注冊為它所實現的接口。既然能夠自動注入,那么接口和類的定義一定要有一定的規律。我們可以定義IDependency接口的類型,其他任何的接口都需要繼承這個接口。
public interface IDependency { } public interface IProductRepository : IDependency { IEnumerable<Product> GetAll(); Product Get(int id); Product Add(Product item); bool Update(Product item); bool Delete(int id); }
添加IUserRepository.cs 繼承IDependency

public interface IUserRepository : IDependency { IEnumerable<User> GetAll(); User Get(int id); User Add(User item); bool Update(User item); bool Delete(int id); }
倉儲實現

public class UserRepository : IUserRepository { private List<User> Users = new List<User>(); public UserRepository() { Add(new User { Id = 1, Name = "hyh" }); Add(new User { Id = 2, Name = "hyg" }); Add(new User { Id = 3, Name = "hyr" }); } public IEnumerable<User> GetAll() { return Users; } public User Get(int id) { return Users.Find(p => p.Id == id); } public User Add(User item) { if (item == null) { throw new ArgumentNullException("item"); } Users.Add(item); return item; } public bool Update(User item) { if (item == null) { throw new ArgumentNullException("item"); } int index = Users.FindIndex(p => p.Id == item.Id); if (index == -1) { return false; } Users.RemoveAt(index); Users.Add(item); return true; } public bool Delete(int id) { Users.RemoveAll(p => p.Id == id); return true; } }
最后Global
#region 自動注入 //創建autofac管理注冊類的容器實例 var builder = new ContainerBuilder(); Assembly[] assemblies = Directory.GetFiles(AppDomain.CurrentDomain.RelativeSearchPath, "*.dll").Select(Assembly.LoadFrom).ToArray(); //注冊所有實現了 IDependency 接口的類型 Type baseType = typeof(IDependency); builder.RegisterAssemblyTypes(assemblies) .Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract) .AsSelf().AsImplementedInterfaces() .PropertiesAutowired().InstancePerLifetimeScope(); //注冊MVC類型 builder.RegisterControllers(assemblies).PropertiesAutowired(); builder.RegisterFilterProvider(); var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); #endregion
結果如下:
ok,先到這了...