1. 程式人生 > >Asp.Net MVC 之 Autofac 初步使用2 整合mvc 屬性注入以及自動注入

Asp.Net MVC 之 Autofac 初步使用2 整合mvc 屬性注入以及自動注入

首先看下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; } }
Product.cs

 第二步 建立資料夾IRepository 用於存放倉儲介面IProductRepository

 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倉儲介面

  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

下一步定義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,先到這了...