.Net IOC框架入门之——Autofac

一、简介

Autofac是.NET领域最为流行的IOC框架之一,传说是速度最快的一个

目的

1.依赖注入的目的是为了解耦。
2.不依赖于具体类,而依赖抽象类或者接口,这叫依赖倒置。
3.控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。
4. 微软的DependencyResolver如何创建controller

生命周期

1、InstancePerDependency

对每一个依赖或每一次调用创建一个新的唯一的实例。这也是默认的创建实例的方式。官方文档解释:Configure the component so that every dependent component or call to Resolve() gets a new, unique instance (default.)

2、InstancePerLifetimeScope

在一个生命周期域中,每一个依赖或调用创建一个单一的共享的实例,且每一个不同的生命周期域,实例是唯一的,不共享的。官方文档解释:Configure the component so that every dependent component or call to Resolve() within a single ILifetimeScope gets the same, shared instance. Dependent components in different lifetime scopes will get different instances.

3、InstancePerMatchingLifetimeScope

在一个做标识的生命周期域中,每一个依赖或调用创建一个单一的共享的实例。打了标识了的生命周期域中的子标识域中可以共享父级域中的实例。若在整个继承层次中没有找到打标识的生命周期域,则会抛出异常:DependencyResolutionException。官方文档解释:Configure the component so that every dependent component or call to Resolve() within a ILifetimeScope tagged with any of the provided tags value gets the same, shared instance. Dependent components in lifetime scopes that are children of the tagged scope will share the parent‘s instance. If no appropriately tagged scope can be found in the hierarchy an DependencyResolutionException is thrown.

4、InstancePerOwned

在一个生命周期域中所拥有的实例创建的生命周期中,每一个依赖组件或调用Resolve()方法创建一个单一的共享的实例,并且子生命周期域共享父生命周期域中的实例。若在继承层级中没有发现合适的拥有子实例的生命周期域,则抛出异常:DependencyResolutionException。官方文档解释:Configure the component so that every dependent component or call to Resolve() within a ILifetimeScope created by an owned instance gets the same, shared instance. Dependent components in lifetime scopes that are children of the owned instance scope will share the parent‘s instance. If no appropriate owned instance scope can be found in the hierarchy an DependencyResolutionException is thrown.

5、SingleInstance

每一次依赖组件或调用Resolve()方法都会得到一个相同的共享的实例。其实就是单例模式。官方文档解释:Configure the component so that every dependent component or call to Resolve() gets the same, shared instance.

6、InstancePerHttpRequest  (新版autofac建议使用InstancePerRequest)

在一次Http请求上下文中,共享一个组件实例。仅适用于asp.net mvc开发。

官方文档解释:Share one instance of the component within the context of a single HTTP request.

二、常用方法

(1)builder.RegisterType<Object>().As<Iobject>():注册类型及其实例。例如下面就是注册接口IDAL的实例SqlDAL
(2)IContainer.Resolve<IDAL>():解析某个接口的实例。例如上面的最后一行代码就是解析IDAL的实例SqlDAL
(3)builder.RegisterType<Object>().Named<Iobject>(string name):为一个接口注册不同的实例。有时候难免会碰到多个类映射同一个接口,比如SqlDAL和OracleDAL都实现了IDAL接口,为了准确获取想要的类型,就必须在注册时起名字。
(4)IContainer.ResolveNamed<IDAL>(string name):解析某个接口的“命名实例”。例如上面的最后一行代码就是解析IDAL的命名实例OracleDAL
(5)builder.RegisterType<Object>().Keyed<Iobject>(Enum enum):以枚举的方式为一个接口注册不同的实例。有时候我们会将某一个接口的不同实现用枚举来区分,而不是字符串,
(6)IContainer.ResolveKeyed<IDAL>(Enum enum):根据枚举值解析某个接口的特定实例。例如上面的最后一行代码就是解析IDAL的特定实例OracleDAL
(7)builder.RegisterType<Worker>().InstancePerDependency():用于控制对象的生命周期,每次加载实例时都是新建一个实例,默认就是这种方式
(8)builder.RegisterType<Worker>().SingleInstance():用于控制对象的生命周期,每次加载实例时都是返回同一个实例
(9)IContainer.Resolve<T>(NamedParameter namedParameter):在解析实例T时给其赋值

三、文件配置

通过配置的方式使用

(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‘)");
    }

四、示例

MVC5示例中实现的功能有:程序集注册、按服务注册、属性注入、泛型注入

global.cs

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        InitDependency();
        StackExchange.Profiling.EntityFramework6.MiniProfilerEF6.Initialize();
    }
    private void InitDependency()
    {
        ContainerBuilder builder = new ContainerBuilder();
        Type baseType = typeof(IDependency);
        // 自动注册当前程序集
        //builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces();
        // 注册当前程序集
        Assembly assemblies = Assembly.GetExecutingAssembly();
        builder.RegisterAssemblyTypes(assemblies)
        .Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract)
        .AsImplementedInterfaces().InstancePerLifetimeScope();//保证对象生命周期基于请求
        //注册引用的程序集
        //var assemblyList = BuildManager.GetReferencedAssemblies().Cast<Assembly>().Where(assembly => assembly.GetTypes().Any(type => type.GetInterfaces().Contains(baseType)));
        //var enumerable = assemblyList as Assembly[] ?? assemblyList.ToArray();
        //if (enumerable.Any())
        //{
        //    builder.RegisterAssemblyTypes(enumerable)
        //        .Where(type => type.GetInterfaces().Contains(baseType))
        //        .AsImplementedInterfaces().InstancePerLifetimeScope();
        //}
        //注册指定的程序集
        //自动注册了IStudentService、IUserService
        builder.RegisterAssemblyTypes(Assembly.Load("AppService"), Assembly.Load("AppService"))
        .Where(t => t.Name.EndsWith("Service"))
        .AsImplementedInterfaces();
        //一、Type注册服务
        builder.RegisterType<CourseService>().As<ICourseService>();
        builder.RegisterType<UserService>().AsSelf();// 注入类本身,等价于.As<UserService>();
        builder.RegisterType<ScoreManage>().AsImplementedInterfaces();//批量注册,等价于.As<IEnglishScoreManage>().As<IMathematicsScoreManage>();
        //二、Named注册服务
        //builder.RegisterType<ChineseScorePlusManage>().Named<IChineseScoreManage>(ChineseScoreEnum.ChineseScorePlus.ToString());// 一个接口与多个类型关联
        //builder.RegisterType<ChineseScoreManage>().Named<IChineseScoreManage>(ChineseScoreEnum.ChineseScore.ToString());// 一个接口与多个类型关联
        //三、Keyed注册服务
        builder.RegisterType<ChineseScorePlusManage>().Keyed<IChineseScoreManage>(ChineseScoreEnum.ChineseScorePlus);// 一个接口与多个类型关联
        builder.RegisterType<ChineseScoreManage>().Keyed<IChineseScoreManage>(ChineseScoreEnum.ChineseScore);// 一个接口与多个类型关联

        //泛型注册,可以通过容器返回List<T> 如:List<string>,List<int>等等
        //builder.RegisterGeneric(typeof(List<>)).As(typeof(IList<>)).InstancePerLifetimeScope();
        //生命周期
        //builder.RegisterType<StudentService>().As<IStudentService>().InstancePerLifetimeScope(); //基于线程或者请求的单例..就是一个请求 或者一个线程 共用一个
        //builder.RegisterType<StudentService>().As<IStudentService>().InstancePerDependency(); //服务对于每次请求都会返回单独的实例
        //builder.RegisterType<StudentService>().As<IStudentService>().SingleInstance(); //单例.. 整个项目公用一个
        //builder.RegisterType<StudentService>().As<IStudentService>().InstancePerRequest(); //针对MVC的,或者说是ASP.NET的..每个请求单例
        builder.RegisterType<ServiceGetter>().As<IServiceGetter>();//用于一个接口与多个类型关联
        builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();//属性注入,未注册将出现“没有为该对象定义无参数的构造函数。”
        builder.RegisterType<TestDbContext>().As<IDbContext>().InstancePerLifetimeScope();
        builder.RegisterGeneric(typeof(EfRepository<>)).As(typeof(IRepository<>)).InstancePerLifetimeScope();//泛型注入
        //builder.RegisterFilterProvider(); //注入特性,特性里面要用到相关的服务
        IContainer container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));//生成容器并提供给MVC
    }
    protected void Application_BeginRequest()
    {
        if (Request.IsLocal)//这里是允许本地访问启动监控,可不写
        {
            MiniProfiler.Start();
        }
    }
    protected void Application_EndRequest()
    {
        MiniProfiler.Stop();
    }
}

控制器

public class HomeController : Controller
{
    private readonly IStudentService _studentService;
    private readonly ITeacherService _teacherService;
    private readonly IUserService _userService;
    public readonly UserService UserService;
    private readonly IEnglishScoreManage _englishScoreManage;
    private readonly IMathematicsScoreManage _mathematicsScoreManage;
    private IServiceGetter getter;
    public ICourseService CourseService
    {
        get;
        set;
    }
    private readonly IRepository<Student> _studentRrepository;
    public HomeController(IStudentService studentService, IUserService userService, ITeacherService teacherService, UserService userService1, IMathematicsScoreManage mathematicsScoreManage, IEnglishScoreManage englishScoreManage, IServiceGetter getter, IRepository<Student> studentRrepository)
    {
        _studentService = studentService;
        _userService = userService;
        _teacherService = teacherService;
        this.UserService = userService1;
        _mathematicsScoreManage = mathematicsScoreManage;
        _englishScoreManage = englishScoreManage;
        this.getter = getter;
        _studentRrepository = studentRrepository;
    }
    public ActionResult Index()
    {
        var name = "";
        var student = _studentRrepository.GetById("4b900c95-7aac-4ae6-a122-287763856601");
        if (student != null)
        {
            name = student.Name;
        }
        ViewBag.Name = _teacherService.GetName();
        ViewBag.UserName1 = _userService.GetName();
        ViewBag.UserName2 = UserService.GetName();
        ViewBag.StudentName = _studentService.GetName() + "-" + name;
        ViewBag.CourseName = CourseService.GetName();
        ViewBag.EnglishScore = _englishScoreManage.GetEnglishScore();
        ViewBag.MathematicsScore = _mathematicsScoreManage.GetMathematicsScore();
        //ViewBag.ChineseScore = getter.GetByName<IChineseScoreManage>(ChineseScoreEnum.ChineseScore.ToString()).GetScore();
        //ViewBag.ChineseScorePlus = getter.GetByName<IChineseScoreManage>(ChineseScoreEnum.ChineseScorePlus.ToString()).GetScore();
        ViewBag.ChineseScore = getter.GetByKey<ChineseScoreEnum, IChineseScoreManage>(ChineseScoreEnum.ChineseScore).GetScore();
        ViewBag.ChineseScorePlus = getter.GetByKey<ChineseScoreEnum, IChineseScoreManage>(ChineseScoreEnum.ChineseScorePlus).GetScore();
        return View();
    }
}

页面

@{
    ViewBag.Title = "Home Page";
}

<div class="jumbotron">
    <h1>ASP.NET</h1>
</div>

<div class="row">
    <div class="col-md-4">
        <h2>Teacher: @ViewBag.Name </h2>
        <p>
            CourseName: @ViewBag.CourseName
        </p>
        <p></p>
    </div>
    <div class="col-md-4">
        <h2>User</h2>
        <p>接口注入:@ViewBag.UserName1</p>
        <p>类注入:@ViewBag.UserName2</p>
    </div>
    <div class="col-md-4">
        <h2>Student: @ViewBag.StudentName</h2>
        <p>English:@ViewBag.EnglishScore</p>
        <p>Math: @ViewBag.MathematicsScore</p>
        <p>Chinese: @ViewBag.ChineseScore</p>
        <p>ChinesePlus:@ViewBag.ChineseScorePlus</p>
    </div>
</div>

代码下载:https://gitee.com/zmsofts/XinCunShanNianDaiMa/blob/master/EntityFrameworkExtension.rar

注意:codefirst开发,先迁移后才能使用

参考文章:

https://www.cnblogs.com/struggle999/p/6986903.html

https://www.cnblogs.com/gdsblog/p/6662987.html

https://www.cnblogs.com/kissdodog/p/3611799.html

https://www.cnblogs.com/fuyujian/p/4115474.html

http://www.cnblogs.com/tiantianle/category/779544.html

原文地址:https://www.cnblogs.com/zhaoshujie/p/11543714.html

时间: 2024-08-29 16:19:18

.Net IOC框架入门之——Autofac的相关文章

Asp.Net Ioc框架入门之一 Unity

一.概述 IOC:英文全称:Inversion of Control,中文名称:控制反转,它还有个名字叫依赖注入(Dependency Injection). 作用:将各层的对象以松耦合的方式组织在一起,解耦,各层对象的调用完全面向接口.当系统重构的时候,代码的改写量将大大减少. 依赖注入: 当一个类的实例需要另一个类的实例协助时,在传统的程序设计过程中,通常有调用者来创建被调用者的实例.然而采用依赖注入的方式,创建被调用者的工作不再由调用者来完成,因此叫控制反转,创建被调用者的实例的工作由IO

IOC框架之Unity

一.IOC介绍 IOC(Inversion of Control),中文译为控制反转,又称为“依赖注入”(DI =Dependence Injection) IOC的基本概念是:不创建对象,但是描述创建它们的方式.在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务.容器负责将这些联系在一起. 其原理是基于OO设计原则的The Hollywood Principle:Don't call us, we'll call you(别找我,我会来找你的).也就是说,所有的组件都是

IOC框架之AutoFac简介

一.为什么使用AutoFac? 之前介绍了Unity和Ninject两个IOC容器,但是发现园子里用AutoFac的貌似更为普遍,于是捯饬了两天,发现这个东东确实是个高大上的IOC容器~ Autofac是.NET领域最为流行的IOC框架之一,传说是速度最快的一个: 优点: 它是C#语言联系很紧密,也就是说C#里的很多编程方式都可以为Autofac使用,例如可以用Lambda表达式注册组件 较低的学习曲线,学习它非常的简单,只要你理解了IoC和DI的概念以及在何时需要使用它们 XML配置支持 自动

NET领域最为流行的IOC框架之一Autofac

一.前言 Autofac是.NET领域最为流行的IOC框架之一,微软的Orchad开源程序使用的就是Autofac,Nopcommerce开源程序也是用的Autofac. Orchad和Nopcommerce在用Autofac的时候进行封装,看过源码的都知道Autafac使用简单,功能强大. 建议下载Orchad和Nopcommerce学习下源码:附上下载地址 http://www.orchardproject.net/ http://www.nopcommerce.com/ 和其他IOC对比:

spring IOC快速入门,属性注入,注解开发

我们使用spring框架也会使用到配置文件,我们需要在src下创建一个关于spring的配置文件,一般情况名称叫applicationContext.xml 基本约束: <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> IOC快速入门 inversion of Controller

各大主流.Net的IOC框架性能测试比较

在上一篇中,我简单介绍了下Autofac的使用,有人希望能有个性能上的测试,考虑到有那么多的IOC框架,而主流的有:Castle Windsor.微软企业库中的Unity.Spring.NET.StructureMap.Ninject等等.本篇文章主要针对这些IOC框架编写测试程序. Autofac下载地址:http://code.google.com/p/autofac/ Castle Windsor下载地址:http://sourceforge.net/projects/castleproj

Spring中IoC的入门实例

Spring中IoC的入门实例 Spring的模块化是很强的,各个功能模块都是独立的,我们可以选择的使用.这一章先从Spring的IoC开始.所谓IoC就是一个用XML来定义生成对象的模式,我们看看如果来使用的. 数据模型 1.如下图所示有三个类,Human(人类)是接口,Chinese(中国人)是一个子类,American(美国人)是另外一个子类. 源代码如下: package cn.com.chengang.spring;public interface Human {void eat();

主流IOC框架测验(.NET)

上一篇中,我简单介绍了下Autofac的使用,有人希望能有个性能上的测试,考虑到有那么多的IOC框架,而主流的有:Castle Windsor.微软企业库中的Unity.Spring.NET.StructureMap.Ninject等等.本篇文章主要针对这些IOC框架编写测试程序. Autofac下载地址:http://code.google.com/p/autofac/ Castle Windsor下载地址:http://sourceforge.net/projects/castleproje

Spring FrameWork4(MVC + IOC)快速入门实例

使用Maven创建工程并配置依赖项 首先创建一个Maven Project: 然后选择创建Maven 的webapp实例,当然也可以通过命令行方式创建Maven webapp的项目再转化并导入到MyEclipse中. 在pom.xml中需要对于Spring依赖项进行配置: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-insta