Autofac的使用

一、为什么使用AutoFac

Autofac是一款IOC框架,比较于其他的IOC框架,如 Spring.NET,Unity,Castle等等所包含的,它很轻量级性能上非常高。
官方网站:http://autofac.org/
源码下载地址:https://github.com/autofac/Autofac
引用博客地址:
https://blog.csdn.net/silasila__/article/details/79450512
https://www.cnblogs.com/liupeng/p/4806184.html
控制反转(IoC/Inverse Of Control):调用者不再创建被调用者的实例,由autofac框架实现(容器创建)所以称为控制反转。
依赖注入(DI/Dependence injection) :容器创建好实例后再注入调用者称为依赖注入。

二、AutoFac的使用

首先你必须获取AutoFac,这里你可以通过各种方式加载它,我这里还是通过VS中的NuGet来加载AutoFac,不论是哪种方式,最终的目的就是将 Autofac.dll,Autofac.Configuration.dll 这两个程序集引用到你的项目中。

三、AutoFac常用方法说明

(1)builder.RegisterType().As():注册类型及其实例。例如下面就是注册接口IDAL的实例SqlDAL

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<SqlDAL>().As<IDAL>();
IContainer container = builder.Build();
SqlDAL sqlDAL = (SqlDAL)container.Resolve<IDAL>();

(2)IContainer.Resolve():解析某个接口的实例。例如上面的最后一行代码就是解析IDAL的实例SqlDAL
(3)builder.RegisterType().Named(string name):为一个接口注册不同的实例。有时候难免会碰到多个类映射同一个接口,比如SqlDAL和OracleDAL都实现了IDAL接口,为了准确获取想要的类型,就必须在注册时起名字。

builder.RegisterType<SqlDAL>().Named<IDAL>("sql");
builder.RegisterType<OracleDAL>().Named<IDAL>("oracle");
IContainer container = builder.Build();
SqlDAL sqlDAL = (SqlDAL)container.ResolveNamed<IDAL>("sql");
OracleDAL oracleDAL = (OracleDAL)container.ResolveNamed<IDAL>("oracle");

(4)IContainer.ResolveNamed(string name):解析某个接口的“命名实例”。例如上面的最后一行代码就是解析IDAL的命名实例OracleDAL
(5)builder.RegisterType().Keyed(Enum enum):以枚举的方式为一个接口注册不同的实例。有时候我们会将某一个接口的不同实现用枚举来区分,而不是字符串,例如:

public enum DBType{ Sql, Oracle}
builder.RegisterType<SqlDAL>().Keyed<IDAL>(DBType.Sql);
builder.RegisterType<OracleDAL>().Keyed<IDAL>(DBType.Oracle);
IContainer container = builder.Build();
SqlDAL sqlDAL = (SqlDAL)container.ResolveKeyed<IDAL>(DBType.Sql);
OracleDAL oracleDAL = (OracleDAL)container.ResolveKeyed<IDAL>(DBType.Oracle);

(6)IContainer.ResolveKeyed(Enum enum):根据枚举值解析某个接口的特定实例。例如上面的最后一行代码就是解析IDAL的特定实例OracleDAL
(7)builder.RegisterType().InstancePerDependency():用于控制对象的生命周期,每次加载实例时都是新建一个实例,默认就是这种方式
(8)builder.RegisterType().SingleInstance():用于控制对象的生命周期,每次加载实例时都是返回同一个实例
(9)IContainer.Resolve(NamedParameter namedParameter):在解析实例T时给其赋值

DBManager manager = container.Resolve<DBManager>(new NamedParameter("name", "SQL"));
public class DBManager 
{   
    IDAL dal;
    public DBManager (string name,IDAL  _dal)
    {
        Name = name;
        dal= _dal;
    }
}

四、通过配置的方式使用AutoFac

(1)先配置好配置文件

<?xml version="1.0"?>
  <configuration>
    <configSections>
  <section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/>
    </configSections>
    <autofac defaultAssembly="ConsoleApplication1">
  <components>
    <component type="ConsoleApplication1.SqlDAL, ConsoleApplication1" service="ConsoleApplication1.IDAL" />
  </components>
    </autofac>
  </configuration> 

(2)读取配置实现依赖注入(注意引入Autofac.Configuration.dll)

static void Main(string[] args)
{
        ContainerBuilder builder = new ContainerBuilder();
        builder.RegisterType<DBManager>();
        builder.RegisterModule(new ConfigurationSettingsReader("autofac"));
        using (IContainer container = builder.Build())
        {
            DBManager manager = container.Resolve<DBManager>();
            manager.Add("INSERT INTO Persons VALUES ('Man', '25', 'WangW', 'Shanghai')"); 
}
} 

五、ASP.NET MVC与AtuoFac

终于到了ASP.NET MVC与AtuoFac双剑合璧的时候了,下面就看看AtuoFac在MVC中的应用,其实很简单,大概就几个步骤搞定:
1、首先在函数Application_Start() 注册自己的控制器类,一定要引入Autofac.Integration.Mvc.dll

namespace AtuoFacOfMVC4
{
   public class MvcApplication : System.Web.HttpApplication
   {
        protected void Application_Start()
       {
            var builder = new ContainerBuilder();
            SetupResolveRules(builder);
            builder.RegisterControllers(Assembly.GetExecutingAssembly());
            var container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        }
        private void SetupResolveRules(ContainerBuilder builder)
        {
            builder.RegisterType<StudentRepository>().As<IStudentRepository>();
        }
    }
}

2、现在在你的MVC程序中注入依赖代码
(1)首先声明一个Student学生类

namespace AtuoFacOfMVC4.Models
{
    		public class Student
    		{
        		public int Id { get; set; }
        		public string Name { get; set; }
        		public string Graduation { get; set; }
        		Public string School { get; set; }
        		public string Major { get; set; }
         }
}

(2)然后声明仓储接口及其实现

namespace AtuoFacOfMVC4.Models
{
    		public interface IStudentRepository
    		{
        		IEnumerable<Student> GetAll();
        		Student Get(int id);
        		Student Add(Student item);
        		bool Update(Student item);
        		bool Delete(int id);
    		}
}

(3)最后添加控制器StudentController,并注入依赖代码

namespace AtuoFacOfMVC4.Controllers
{
    public class StudentController : Controller
    {
        readonly IStudentRepository repository;
        //构造器注入
        public StudentController(IStudentRepository repository)
        {
            this.repository = repository;
        }
       public ActionResult Index()
        {
            var data = repository.GetAll();
            return View(data);
        }
    }
}

(四)属性注入
public class DefaultController : Controller
{

    public IDataSource ds { get; set; }
    // 接口定义  构造函数注入
    //public DefaultController(IDataSource _ds)
    //{
    //    ds = _ds;
    //}

    // GET: Default
    public ActionResult Index()
    {
        //调用具体类的具体方法返回结果 赋值给ViewBag.Message
        ViewBag.Message = "STONE刘先生:" + ds.GetData();
        return View();
    }
}

如果现在任何地方都不改的情况下,是不是提醒ds为null,那怎么支持属性注入呢!

builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();

把Global.asax里面的这句改成如上这句 就好了!

六、自动注入

Autofac提供一个RegisterAssemblyTypes方法。它会去扫描所有的dll并把每个类注册为它所实现的接口。既然能够自动注入,那么接口和类的定义一定要有一定的规律。我们可以定义IDependency接口的类型,其他任何的接口都需要继承这个接口。比如

   public interface IDependency
    {
    }

业务逻辑实现——岗位管理

  public class PostService : IDependency
    {
      public IPostService postService { get; set; }
      ........
     }

自动注入原理说明:
首先我们去找到所有Dll,再去找到实现了IDependency接口的类,然后使用RegisterAssemblyTypes进行注入。

 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));
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值