首先看下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,先到这了...