Asp.Net MVC 之 Autofac 初步使用2 整合mvc 屬性注入以及自動注入
阿新 • • 發佈:2019-02-16
首先看下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; }Product.cspublic DateTime Date { get; set; } }
第二步 建立資料夾IRepository 用於存放倉儲介面IProductRepository
public interface IProductRepository { IEnumerable<Product> GetAll(); Product Get(int id); Product Add(Product item); bool Update(Product item); boolIProductRepository.csDelete(int id); }
第三步 建立資料夾Repository 定義ProductRepository 實現IProductRepository倉儲介面
public class ProductRepository : IProductRepository { private List<Product> Products = new List<Product>(); public ProductRepository() { Add(ProductRepository.csnew 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); } }ProductController.cs
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>Index.cshtml
最後最關鍵的實現注入
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); }IUserRepository.cs
倉儲實現
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; } }UserRepository.cs
最後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,先到這了...