Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入

首先看下Demo2的结构

分享下demo源码 :http://pan.baidu.com/s/1qYtZCrM

   Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入

然后下面一步步将Autofac集成到mvc中。

首先,定义Model Product.cs

Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入
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; }
    }
Product.cs

 第二步 创建文件夹IRepository 用于存放仓储接口IProductRepository

Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入
 public interface IProductRepository
    {
        IEnumerable<Product> GetAll();
        Product Get(int id);
        Product Add(Product item);
        bool Update(Product item);
        bool Delete(int id);
    }
IProductRepository.cs

 第三步 创建文件夹Repository 定义ProductRepository 实现IProductRepository仓储接口

Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入
  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;
        }
    }
ProductRepository.cs

 ok,WebApplication_AutoFac引用AutoFac_Demo2 以及从VS中的NuGet来加载Autofac.Integration.Mvc

Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入

下一步定义ProductController 这里我们用构造器注入

Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入
 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页

Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入
@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(); // 这样支持属性注入

最后效果:

Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入

最后的最后,为了不像 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

Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入
 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

 仓储实现

Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入
 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

 结果如下:

Asp.Net MVC 之 Autofac 初步使用2 集成mvc 属性注入以及自动注入

 ok,先到这了...