在asp.net mvc 中使用Autofac

据说.net 世界里,最强的依赖注入容器是Autofac 。不管是谁,Nopcommerce2.8 用了它,所以就简单研究一下喽。

          用vs 2012 创建一个Asp.net mvc3 的样例项目。然后使用NuGet(Vs2012 自带的有,版本低的话,似乎要安装插件),下载安装autofac的dll,如图1,2.

               

                              图1 NuGet

                  图2 ,load  autofac

autofac 要加载两个dll哦,一个是autofac 的core ,另外一个是和asp.net mvc3集成的dll

然后,我新建一个实体数据模型,链接我的数据库,加载Customer这个我已经建好的表,字段随意,数据随意。实体类Customer自动生成。加一个集合类,装customer,

public class LCust
{
  public List<Customer> clist;
}

 

接下来是一个ICusotmer接口和一个它的实现CustomerService:

复制代码
 public interface ICustomer
 {
        List<Customer>GetCustomers( );
 }
 public class CustomerService : ICustomer
 {

        public List<Customer>GetCustomers()
        {
           
            return new SeendioEntities().T_Adv_Customer.ToList();
        }
}
复制代码

 好,准备工作就绪,开始依赖注入了。

在Gloabal.ascx文件中:

using Autofac;
using Autofac.Builder;
using Autofac.Integration.Mvc;

 

下面是编辑Application_Start()方法,对ICustomer进行依赖注入:

var builder = new ContainerBuilder();
builder.RegisterType<CustomerService>().As<ICustomer>();

 

在HomeController.cs中,修改构造函数:

private ICustomer _icustomer;
public HomeController(ICustomer customerservice)
{
      _icustomer = customerservice;

}

修改action:

复制代码
  public ActionResult Index( )
 {
     ViewBag.Message = "欢迎使用 ASP.NET MVC!";
     List<Customer> clist = _icustomer.GetCustomers();//调用借口方法,获取所有的Customer
     LCust c = new LCust();
     c.clist = clist;
     return View(c); //把Customer返回给视图
 }
复制代码

在index.cshtml 中显示Customer列表中每一个customer的email:

复制代码
@model MvcApplication2.LCust

@{
    ViewBag.Title = "主页";
}
<ul>
@foreach (var item in Model.clist)
{
    <li>@item.Email</li>
}
    </ul>
复制代码

运行,发现报了错:

 

 解决这个问题的方法似乎不少,我翻了翻Nopcommerce 2.8的代码,发现了这么一个方法:RegisterControllers

于是在Application_Start()方法加上一句,对Controller进行依赖注入

 builder.RegisterControllers(Assembly.GetExecutingAssembly());

问题解决,运行出结果。

 

Autofac 粗浅的用还简单,但是在Nopcommerce2.8里,我看到了对它进行封装的代码,好纠结。

 

 Autofac是传说中速度最快的一套.NET高效的依赖注入框架。Autofac的介绍与使用请去参考Autofac全面解析系列(版本:3.5)。   这里介绍的已经挺详细的啦。

      下面我就先来说说MVC4中使用Autofac吧,至于工厂模式与依赖注入的区别的话,这个我简单的解释一下,也只是我的个人观点。使用依赖注入最主要的就是为了解耦,当然工厂模式也可以实现实现大部分的解耦,这个是毋庸置疑的。工厂模式实现方式是向客户端提供一个接口,使客户端不要指定具体产品对象,创建多个产品族的产品对象。将具体实例的创建延迟到对应实现的子类中。但是当我们每次要去拿这个接口的时候就要通过这个工厂来拿了,那么就是说虽然我们排除了对实现接口的具体的方法的依赖,但是我们对工厂模式产生接口的方式产生了依赖。那么依赖注入就可以解决这个依赖了。我们在使用接口的时候可以完全的不需要考虑去取这个接口然后再继续使用接口。我们只要直接拿接口来用就可以了。这就是我个人对工厂模式和依赖注入的解释了,是不是把你们给搞混淆了。

  下面我就在MVC4中使用下Autofac吧。首先我们要先去NuGet下载一个Autofac MVC4的东西

点击安装。

将AuthoryManage.AutofacRegister 也引入Autofac包

导入成功之后,我先在AuthoryManage.InterfaceRepository这个类库中添加一个接口,

 接口

然后在AuthoryManage.Repository中分别加入下面这些类

下面是代码:

    public class BaseRepository :IBaseRepository{
        public string GetData() {
            return "这里是MsSql";
        }
    }
    public class BaseRepository : IBaseRepository {
        public string GetData() {
            return "这里是MySql";
        }
    }
    public class BaseRepository : IBaseRepository {
        public string GetData() {
            return "这里是Oracle";
        }
    }

记得添加对AuthoryManage.InterfaceRepository的引用。

接下来写下Service层的代码

    public interface IBaseService {
        string GetData();
    }
    public interface IBaseService {
        string GetData();
    }

 

最值得注意的Service实现类代码,请看:

复制代码
    public class BaseService:IBaseService {
        private readonly IBaseRepository _repository;
        public BaseService(IBaseRepository repository) {
            this._repository = repository;
        }
        public string GetData() {
            return _repository.GetData();
        }
    }
复制代码

这是建好之后的Service层结构

也要记得引用对应DLL,那么接下来就看看控制器这边怎么写吧。

我就简单先建立一个Home控制器吧。并添加对service的引用。

复制代码
    public class HomeController : Controller {
        //
        // GET: /Home/
        private IBaseService _service;
        public HomeController(IBaseService service) {
            this._service = service;
        }
        public ActionResult Index() {
            ViewBag.SSSS = _service.GetData();
            return View();
        }

    }
复制代码

视图代码如下:

@{
    ViewBag.Title = "Index";
}

<h2>@ViewBag.SSSS</h2>

 

接下来就去Global中实现我们的注入:

 

复制代码
using Autofac;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Autofac.Integration.Mvc;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace AuthoryManage.Web {
    // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
    // 请访问 http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication {
        protected void Application_Start() {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);


            var builder = new ContainerBuilder();
            var assembly = Assembly.GetExecutingAssembly();
            var repository = System.Reflection.Assembly.Load("AuthoryManage.MsSqlRepository");
            builder.RegisterAssemblyTypes(repository, repository)
              .AsImplementedInterfaces();
            var service = System.Reflection.Assembly.Load("AuthoryManage.Service");
            builder.RegisterAssemblyTypes(service, service)
              .AsImplementedInterfaces();
            builder.RegisterControllers(typeof(MvcApplication).Assembly);
            //容器
            var container = builder.Build();
            //注入改为Autofac注入
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        }
    }
}
复制代码

要记住,在反射程序集的时候你要引用相对应的程序集。然后我们在运行一下程序来看下界面效果:

我们把global.asax里面的代码更改下,改成对Oracle的程序集注册,

复制代码
using Autofac;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Autofac.Integration.Mvc;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace AuthoryManage.Web {
    // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
    // 请访问 http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication {
        protected void Application_Start() {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);


            var builder = new ContainerBuilder();
            var assembly = Assembly.GetExecutingAssembly();
            var repository = System.Reflection.Assembly.Load("AuthoryManage.OracleRepository");
            builder.RegisterAssemblyTypes(repository, repository)
              .AsImplementedInterfaces();
            var service = System.Reflection.Assembly.Load("AuthoryManage.Service");
            builder.RegisterAssemblyTypes(service, service)
              .AsImplementedInterfaces();
            builder.RegisterControllers(typeof(MvcApplication).Assembly);
            //容器
            var container = builder.Build();
            //注入改为Autofac注入
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        }
    }
}
复制代码

看下运行效果:

需要注意的是我们需要引用下AuthoryManage.OracleRepository这个dll引用,那么就是说我实现的方法更改了 我UI层也要去改动对应的引用。

 

 

 


Mvc中使用Autofac

前面学习了AutoFac的注册、解析、生命周期,这里写一个AutoFac在ASP.NET MVC中的简单使用。

基本结构:AutoFacMvc作为ui层 ,IService类库(各种服务接口),Service类库(IService中接口的实现),Model类库(数据模型,这里使用EF)

我们的目的:实现MVC中的Controller和Service中的具体实现类解耦

获取用户列表的简单例子:

IService中的接口:

复制代码
namespace IService
{
    public interface IUserInfoService
    {
        List<UserInfo> GetUsers();
    }
}
复制代码

Service中的实现:

复制代码
namespace Service
{
    public class UserInfoService : IUserInfoService
    {
        //获取用户列表
        public List<Model.UserInfo> GetUsers()
        {
            DbContext context = DbFactory.GetDbContext();
            return context.Set<UserInfo>().ToList<UserInfo>();
        }
    }
}
复制代码

 

第一步:在mvc中添加dll文件,可以通过Nuget直接添加

第二步:在App_Start文件夹中添加一个AutofacConfig类

复制代码
 1     public class AutofacConfig
 2     {
 3         /// <summary>
 4         /// 负责调用autofac框架实现业务逻辑层和数据仓储层程序集中的类型对象的创建
 5         /// 负责创建MVC控制器类的对象(调用控制器中的有参构造函数),接管DefaultControllerFactory的工作
 6         /// </summary>
 7         public static void Register()
 8         {
 9             //实例化一个autofac的创建容器
10             var builder = new ContainerBuilder();
11             //告诉Autofac框架,将来要创建的控制器类存放在哪个程序集 (AutoFacMvcDemo)
12             Assembly controllerAss = Assembly.Load("AutoFacMvcDemo");
13             builder.RegisterControllers(controllerAss);
14 
15             //如果有Dal层的话,注册Dal层的组件
16             //告诉autofac框架注册数据仓储层所在程序集中的所有类的对象实例
17             //Assembly dalAss = Assembly.Load("Dal");
18             //创建respAss中的所有类的instance以此类的实现接口存储
19             //builder.RegisterTypes(dalAss.GetTypes()).AsImplementedInterfaces();
20 
21             //告诉autofac框架注册业务逻辑层所在程序集中的所有类的对象实例
22             Assembly serviceAss = Assembly.Load("Service");
23             //创建serAss中的所有类的instance以此类的实现接口存储
24             builder.RegisterTypes(serviceAss.GetTypes()).AsImplementedInterfaces();
25 
26 
27             //创建一个Autofac的容器
28             var container = builder.Build();
29             //将MVC的控制器对象实例 交由autofac来创建
30             DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
31         }
32     }
复制代码

第三步:在Global.asax调用AutofacConfig类中的Register方法,注册组件

复制代码
 1     public class MvcApplication : System.Web.HttpApplication
 2     {
 3         protected void Application_Start()
 4         {
 5             AreaRegistration.RegisterAllAreas();
 6             RouteConfig.RegisterRoutes(RouteTable.Routes);
 7             //注册组件
 8             AutofacConfig.Register();
 9         }
10     }
复制代码

第四步:简单测试

UserInfoController :
复制代码
 1 namespace AutoFacMvcDemo.Controllers
 2 {
 3     public class UserInfoController : Controller
 4     {
 5         private IUserInfoService userinfoService;
 6         //通过构造器注入依赖
 7         public UserInfoController(IUserInfoService _userinfoService)
 8         {
 9             userinfoService = _userinfoService;
10         }
11         
12         public ActionResult Index()
13         {
14             //不使用autofac时,service层和mvc ui层强耦合
15              //UserInfoService userInfoService = new UserInfoService();
16              //List<UserInfo> users= userInfoService.GetUsers();
17 
18            List<UserInfo> users=  userinfoService.GetUsers();
19            ViewBag.users = users; 
20            return View();
21         }
22     }
23 }
复制代码

View

复制代码
@{
    ViewBag.Title = "Index";
}
<h2>用户列表</h2>

@* 简单展示用户 *@
<table>
    @foreach (var item in ViewBag.users)
    {
        <tr>
            <td>@item.UId</td>
            <td>@item.UserName</td>
            <td>@item.Age</td>
        </tr>
    }
</table>
复制代码

运行结果:


 

补充:可以逐个进行注册代码如下,在Application_Start方法中添加如下代码 :

复制代码
      //创建autofac管理注册类的容器实例
            var builder = new ContainerBuilder();
            //注册组件(注意:在注册时添加了UserInfoService的引用,其实还是耦合的,在不分层的项目中好用)
            builder.RegisterType<UserInfoService>().As<IUserInfoService>();
            //使用Autofac提供的RegisterControllers扩展方法来对程序集中所有的Controller一次性的完成注册
            builder.RegisterControllers(Assembly.GetExecutingAssembly());
            //生成具体的实例
            var container = builder.Build();
            //下面就是使用MVC的扩展 更改了MVC中的注入方式.
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
复制代码

 

         
欢迎转载,但请标明出处。如果本文对您有些许帮助,点击一下推荐吧,Thanks♪(・ω・)ノ

posted on 2020-03-07 22:20  大西瓜3721  阅读(404)  评论(0编辑  收藏  举报

导航