在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一、为什么使用Autofac?Autofac是.NET领域最为流行的IoC框架之一,传说是速度最快的一个。 1.1、性能有人专门做了测试: 1.2、优点1)与C#语言联系很紧密。C#里的很多编程方式都可以为Autofac使用,例如可以使用Lambda表达式注册组件。 2)较低的学习曲线。学习它非常的简单,只要你理解了IoC和DI的概念以及在何时需要使用它们。 3)支持JSON/XML配置。 4)自动装配。 5)与Asp.Net MVC集成。 6)微软的Orchad开源程序使用的就是Autofac,可以看出它的方便和强大。 1.3、资源官方网站:http://autofac.org/ GitHub网址:https://github.com/autofac/Autofac 学习资料:Autofac中文文档 二、数据准备2.1、新建项目IService下的接口类: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace LinkTo.Test.Autofac.IService { /// <summary> /// 动物吠声接口类 /// </summary> public interface IAnimalBark { /// <summary> /// 吠叫 /// </summary> void Bark(); } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace LinkTo.Test.Autofac.IService { /// <summary> /// 动物睡眠接口类 /// </summary> public interface IAnimalSleep { /// <summary> /// 睡眠 /// </summary> void Sleep(); } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace LinkTo.Test.Autofac.IService { /// <summary> /// 学校接口类 /// </summary> public interface ISchool { /// <summary> /// 放学 /// </summary> void LeaveSchool(); } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace LinkTo.Test.Autofac.IService { /// <summary> /// 学生接口类 /// </summary> public interface IStudent { /// <summary> /// 增加学生 /// </summary> /// <param name="studentID">学生ID</param> /// <param name="studentName">学生姓名</param> void Add(string studentID, string studentName); } } Service下的接口实现类: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using LinkTo.Test.Autofac.IService; namespace LinkTo.Test.Autofac.Service { /// <summary> /// 猫类 /// </summary> public class Cat : IAnimalSleep { /// <summary> /// 睡眠 /// </summary> public void Sleep() { Console.WriteLine("小猫咪睡着了zZ"); } } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using LinkTo.Test.Autofac.IService; namespace LinkTo.Test.Autofac.Service { /// <summary> /// 狗类 /// </summary> public class Dog : IAnimalBark, IAnimalSleep { /// <summary> /// 吠叫 /// </summary> public void Bark() { Console.WriteLine("汪汪汪"); } /// <summary> /// 睡眠 /// </summary> public void Sleep() { Console.WriteLine("小狗狗睡着了zZ"); } } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using LinkTo.Test.Autofac.IService; namespace LinkTo.Test.Autofac.Service { /// <summary> /// 学校类 /// </summary> public class School : ISchool { /// <summary> /// IAnimalBark属性 /// </summary> public IAnimalBark AnimalBark { get; set; } /// <summary> /// 放学 /// </summary> public void LeaveSchool() { AnimalBark.Bark(); Console.WriteLine("你家的熊孩子放学了⊙o⊙"); } } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using LinkTo.Test.Autofac.IService; namespace LinkTo.Test.Autofac.Service { /// <summary> /// 学生类 /// </summary> public class Student : IStudent { /// <summary> /// 无参构造函数 /// </summary> public Student() { } /// <summary> /// 有参构造函数 /// </summary> /// <param name="studentID">学生ID</param> /// <param name="studentName">学生姓名</param> public Student(string studentID, string studentName) { Add(studentID, studentName); } /// <summary> /// 增加学生 /// </summary> /// <param name="studentID">学生ID</param> /// <param name="studentName">学生姓名</param> public void Add(string studentID, string studentName) { Console.WriteLine($"新增的学生是:{studentName}"); } } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using LinkTo.Test.Autofac.IService; namespace LinkTo.Test.Autofac.Service { /// <summary> /// 动物摇尾巴 /// </summary> public class AnimalWagging { /// <summary> /// IAnimalBark属性 /// </summary> IAnimalBark animalBark; /// <summary> /// 有参构造函数 /// </summary> /// <param name="bark">IAnimalBark变量</param> public AnimalWagging(IAnimalBark bark) { animalBark = bark; } /// <summary> /// 摇尾巴 /// </summary> public virtual void Wagging() { animalBark.Bark(); Console.WriteLine("摇尾巴"); } /// <summary> /// 计数 /// </summary> /// <returns></returns> public static int Count() { return 6; } /// <summary> /// 任务 /// </summary> /// <param name="name">动物名称</param> /// <returns></returns> public virtual async Task<string> WaggingAsync(string name) { var result = await Task.Run(() => Count()); return $"{name}摇了{result}下尾巴"; } } } 2.2、Autofac安装Client项目右键->管理 NuGet 程序包->Autofac。 三、IoC-注册3.1、类型注册a)类型注册:使用RegisterType进行注册。 //注册Autofac组件 ContainerBuilder builder = new ContainerBuilder(); //注册实现类Student,当我们请求IStudent接口的时候,返回的是类Student的对象。 builder.RegisterType<Student>().As<IStudent>(); //上面这句也可改成下面这句,这样请求Student实现了的任何接口的时候,都会返回Student对象。 //builder.RegisterType<Student>().AsImplementedInterfaces(); IContainer container = builder.Build(); //请求IStudent接口 IStudent student = container.Resolve<IStudent>(); student.Add("1001", "Hello"); b)类型注册(别名):假如一个接口有多个实现类,可以在注册时起别名。 ContainerBuilder builder = new ContainerBuilder(); builder.RegisterType<Dog>().Named<IAnimalSleep>("Dog"); builder.RegisterType<Cat>().Named<IAnimalSleep>("Cat"); IContainer container = builder.Build(); var dog = container.ResolveNamed<IAnimalSleep>("Dog"); dog.Sleep(); var cat = container.ResolveNamed<IAnimalSleep>("Cat"); cat.Sleep(); c)类型注册(枚举):假如一个接口有多个实现类,也可以使用枚举的方式注册。 public enum AnimalType { Dog, Cat } ContainerBuilder builder = new ContainerBuilder(); builder.RegisterType<Dog>().Keyed<IAnimalSleep>(AnimalType.Dog); builder.RegisterType<Cat>().Keyed<IAnimalSleep>(AnimalType.Cat); IContainer container = builder.Build(); var dog = container.ResolveKeyed<IAnimalSleep>(AnimalType.Dog); dog.Sleep(); var cat = container.ResolveKeyed<IAnimalSleep>(AnimalType.Cat); cat.Sleep(); 3.2、实例注册ContainerBuilder builder = new ContainerBuilder(); builder.RegisterInstance<IStudent>(new Student()); IContainer container = builder.Build(); IStudent student = container.Resolve<IStudent>(); student.Add("1001", "Hello"); 3.3、Lambda注册a)Lambda注册 ContainerBuilder builder = new ContainerBuilder(); builder.Register(c => new Student()).As<IStudent>(); IContainer container = builder.Build(); IStudent student = container.Resolve<IStudent>(); student.Add("1001", "Hello"); b)Lambda注册(NamedParameter) ContainerBuilder builder = new ContainerBuilder(); builder.Register<IAnimalSleep>((c, p) => { var type = p.Named<string>("type"); if (type == "Dog") { return new Dog(); } else { return new Cat(); } }).As<IAnimalSleep>(); IContainer container = builder.Build(); var dog = container.Resolve<IAnimalSleep>(new NamedParameter("type", "Dog")); dog.Sleep(); 3.4、程序集注册如果有很多接口及实现类,假如觉得这种一一注册很麻烦的话,可以一次性全部注册,当然也可以加筛选条件。 ContainerBuilder builder = new ContainerBuilder(); Assembly assembly = Assembly.Load("LinkTo.Test.Autofac.Service"); //实现类所在的程序集名称 builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces(); //常用 //builder.RegisterAssemblyTypes(assembly).Where(t=>t.Name.StartsWith("S")).AsImplementedInterfaces(); //带筛选 //builder.RegisterAssemblyTypes(assembly).Except<School>().AsImplementedInterfaces(); //带筛选 IContainer container = builder.Build(); //单实现类的用法 IStudent student = container.Resolve<IStudent>(); student.Add("1001", "Hello"); //多实现类的用法 IEnumerable<IAnimalSleep> animals = container.Resolve<IEnumerable<IAnimalSleep>>(); foreach (var item in animals) { item.Sleep(); } 3.5、泛型注册ContainerBuilder builder = new ContainerBuilder(); builder.RegisterGeneric(typeof(List<>)).As(typeof(IList<>)); IContainer container = builder.Build(); IList<string> list = container.Resolve<IList<string>>(); 3.6、默认注册ContainerBuilder builder = new ContainerBuilder(); //对于同一个接口,后面注册的实现会覆盖之前的实现。 //如果不想覆盖的话,可以用PreserveExistingDefaults,这样会保留原来注册的实现。 builder.RegisterType<Dog>().As<IAnimalSleep>(); builder.RegisterType<Cat>().As<IAnimalSleep>().PreserveExistingDefaults(); //指定为非默认值 IContainer container = builder.Build(); var dog = container.Resolve<IAnimalSleep>(); dog.Sleep(); 四、IoC-注入4.1、构造函数注入ContainerBuilder builder = new ContainerBuilder(); builder.RegisterType<AnimalWagging>(); builder.RegisterType<Dog>().As<IAnimalBark>(); IContainer container = builder.Build(); AnimalWagging animal = container.Resolve<AnimalWagging>(); animal.Wagging(); 4.2、属性注入ContainerBuilder builder = new ContainerBuilder(); Assembly assembly = Assembly.Load("LinkTo.Test.Autofac.Service"); //实现类所在的程序集名称 builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces().PropertiesAutowired(); //常用 IContainer container = builder.Build(); ISchool school = container.Resolve<ISchool>(); school.LeaveSchool(); 五、IoC-事件Autofac在组件生命周期的不同阶段,共对应了5个事件,执行顺序如下所示: 1.OnRegistered->2.OnPreparing->3.OnActivating->4.OnActivated->5.OnRelease ContainerBuilder builder = new ContainerBuilder(); builder.RegisterType<Student>().As<IStudent>() .OnRegistered(e => Console.WriteLine("OnRegistered:在注册的时候调用")) .OnPreparing(e => Console.WriteLine("OnPreparing:在准备创建的时候调用")) .OnActivating(e => Console.WriteLine("OnActivating:在创建之前调用")) //.OnActivating(e => e.ReplaceInstance(new Student("1000", "Test"))) .OnActivated(e => Console.WriteLine("OnActivated:在创建之后调用")) .OnRelease(e => Console.WriteLine("OnRelease:在释放占用的资源之前调用")); using (IContainer container = builder.Build()) { IStudent student = container.Resolve<IStudent>(); student.Add("1001", "Hello"); } 六、IoC-生命周期6.1、Per DependencyPer Dependency:为默认的生命周期,也被称为"transient"或"factory",其实就是每次请求都创建一个新的对象。 ContainerBuilder builder = new ContainerBuilder(); Assembly assembly = Assembly.Load("LinkTo.Test.Autofac.Service"); //实现类所在的程序集名称 builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces().PropertiesAutowired().InstancePerDependency(); //常用 IContainer container = builder.Build(); ISchool school1 = container.Resolve<ISchool>(); ISchool school2 = container.Resolve<ISchool>(); Console.WriteLine(school1.Equals(school2)); 6.2、Single InstanceSingle Instance:就是每次都用同一个对象。 ContainerBuilder builder = new ContainerBuilder(); Assembly assembly = Assembly.Load("LinkTo.Test.Autofac.Service"); //实现类所在的程序集名称 builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces().PropertiesAutowired().SingleInstance(); //常用 IContainer container = builder.Build(); ISchool school1 = container.Resolve<ISchool>(); ISchool school2 = container.Resolve<ISchool>(); Console.WriteLine(ReferenceEquals(school1, school2)); 6.3、Per Lifetime ScopePer Lifetime Scope:同一个Lifetime生成的对象是同一个实例。 ContainerBuilder builder = new ContainerBuilder(); builder.RegisterType<School>().As<ISchool>().InstancePerLifetimeScope(); IContainer container = builder.Build(); ISchool school1 = container.Resolve<ISchool>(); ISchool school2 = container.Resolve<ISchool>(); Console.WriteLine(school1.Equals(school2)); using (ILifetimeScope lifetime = container.BeginLifetimeScope()) { ISchool school3 = lifetime.Resolve<ISchool>(); ISchool school4 = lifetime.Resolve<ISchool>(); Console.WriteLine(school3.Equals(school4)); Console.WriteLine(school2.Equals(school3)); } 七、IoC-通过配置文件使用Autofac7.1、组件安装Client项目右键->管理 NuGet 程序包->Autofac.Configuration及Microsoft.Extensions.Configuration.Xml。 7.2、配置文件新建一个AutofacConfigIoC.xml文件,在其属性的复制到输出目录项下选择始终复制。 <?xml version="1.0" encoding="utf-8" ?> <autofac defaultAssembly="LinkTo.Test.Autofac.IService"> <!--无注入--> <components name="1001"> <type>LinkTo.Test.Autofac.Service.Student, LinkTo.Test.Autofac.Service</type> <services name="0" type="LinkTo.Test.Autofac.IService.IStudent" /> <injectProperties>true</injectProperties> </components> <components name="1002"> <type>LinkTo.Test.Autofac.Service.Dog, LinkTo.Test.Autofac.Service</type> <services name="0" type="LinkTo.Test.Autofac.IService.IAnimalBark" /> <injectProperties>true</injectProperties> </components> <!--构造函数注入--> <components name="2001"> <type>LinkTo.Test.Autofac.Service.AnimalWagging, LinkTo.Test.Autofac.Service</type> <services name="0" type="LinkTo.Test.Autofac.Service.AnimalWagging, LinkTo.Test.Autofac.Service" /> <injectProperties>true</injectProperties> </components> <!--属性注入--> <components name="3001"> <type>LinkTo.Test.Autofac.Service.School, LinkTo.Test.Autofac.Service</type> <services name="0" type="LinkTo.Test.Autofac.IService.ISchool" /> <injectProperties>true</injectProperties> </components> </autofac> 7.3、测试代码//加载配置 ContainerBuilder builder = new ContainerBuilder(); var config = new ConfigurationBuilder(); config.AddXmlFile("AutofacConfigIoC.xml"); var module = new ConfigurationModule(config.Build()); builder.RegisterModule(module); IContainer container = builder.Build(); //无注入测试 IStudent student = container.Resolve<IStudent>(); student.Add("1002", "World"); //构造函数注入测试 AnimalWagging animal = container.Resolve<AnimalWagging>(); animal.Wagging(); //属性注入测试 ISchool school = container.Resolve<ISchool>(); school.LeaveSchool(); 八、AOP8.1、组件安装Client项目右键->管理 NuGet 程序包->Autofac.Extras.DynamicProxy。 8.2、拦截器using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using Castle.DynamicProxy; namespace LinkTo.Test.Autofac.Client { /// <summary> /// 拦截器:需实现IInterceptor接口。 /// </summary> public class CallLogger : IInterceptor { private readonly TextWriter _output; public CallLogger(TextWriter output) { _output = output; } /// <summary> 全部评论
专题导读
热门推荐
热门话题
阅读排行榜
|
请发表评论