C#IOC注入框架——Autofac的实战应用
倒转依赖是软件开发六大原则之一
网络上有多种IOC注入框架,例如Grace、微软的Unity等,其中数Autofac最轻量,也最快。
本文demo地址
https://gitee.com/chenheze90/L15_AutoFac
ICO优点
-
降低耦合度:通过依赖注入,对象之间的依赖关系由容器负责,而不是由对象自己负责,从而降低了对象之间的耦合度。
-
提高代码的可复用性:由于对象的创建和维护都由容器负责,所以代码中不包含任何与这些工作相关的代码,这使得代码更加简洁,也提高了代码的可复用性。
-
提高代码的可测试性:由于对象的依赖关系由容器负责,所以在进行单元测试时,可以通过容器提供的接口来插入mock对象,从而方便地进行单元测试。
-
提供了一种解耦的设计模式:IOC容器就像是一个工厂,可以根据需要生产出各种对象及其依赖对象,而调用者无需关心这些对象的创建过程,只需从容器中获取即可。
-
提高开发效率:开发者只需要关注业务逻辑的实现,而不需要关心对象的创建和销毁等问题,大大提高了开发效率。
-
更好的组织架构:通过使用IOC,可以将系统分解为一组合作的对象,这些对象通过接口进行通信,从而使得系统的组织结构更加清晰。
Autofac官方信息
官网地址:http://autofac.org/
开源代码:https://github.com/autofac/Autofac
官方文档:https://autofac.readthedocs.io/en/latest/index.html
代码实例
1.按类型注册
builder.RegisterType<Student>().As<IStudent>();
builder.RegisterType<Student>().AsImplementedInterfaces();
IContainer container = builder.Build();
container.Resolve<IStudent>().Learn("学习了按类型注册");
2.按文本/名称注册
builder = new ContainerBuilder();
builder.RegisterType<Student>().Named<IStudent>("A");
builder.RegisterType<Student>().Named<IStudent>("B");
container = builder.Build();
var student1 = container.ResolveNamed<IStudent>("A");
student1.Name = "张三";
student1.Learn("学习了按名字注册");
var student2 = container.ResolveNamed<IStudent>("B");
student2.Name = "李四";
student2.Learn("学习了按名字注册");
3.按枚举注册
builder = new ContainerBuilder();
builder.RegisterType<Student>().Keyed<IStudent>(StudentType.Mid);
builder.RegisterType<Student>().Keyed<IStudent>(StudentType.Sup);
container = builder.Build();
student1 = container.ResolveKeyed<IStudent>(StudentType.Mid);
student1.Name = "王五";
student1.Learn("学习了按枚举注册");
student2 = container.ResolveKeyed<IStudent>(StudentType.Sup);
student2.Name = "赵六";
student2.Learn("学习了按枚举注册");
4.注册实例单例
builder = new ContainerBuilder();
builder.RegisterInstance<IStudent>(new Student());
builder.RegisterInstance(new Student()).Named<Student>("AA");
container = builder.Build();
IStudent student = container.Resolve<IStudent>();
student.Learn("注册了实例");
5.Lanmda注册
builder = new ContainerBuilder();
builder.Register(c => new Student()).As<IStudent>();
container = builder.Build();
IStudent studentlmd = container.Resolve<IStudent>();
student.Learn("Lanmda注册");
6.Lanmda多样化注册
builder = new ContainerBuilder();
builder.Register<IStudent>((c, p) =>
{
var type = p.Named<string>("type");
if (type == "Dog")
{
return new Student();
}
else
{
return new Student();
}
}).As<IStudent>();
container = builder.Build();
var dog = container.Resolve<IStudent>(new NamedParameter("type", "Dog"));
dog.Learn("Lanmda多样化注册");
7.程序集注册
builder = new ContainerBuilder();
Assembly assembly = Assembly.Load("LinkTo.Test.Autofac.Service"); //实现类所在的程序集名称
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces(); //常用
//builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces().PropertiesAutowired().InstancePerDependency(); //常用
//builder.RegisterAssemblyTypes(assembly).Where(t=>t.Name.StartsWith("S")).AsImplementedInterfaces(); //带筛选
//builder.RegisterAssemblyTypes(assembly).Except<s>().AsImplementedInterfaces(); //带筛选
container = builder.Build();
8.实例集合注册
builder = new ContainerBuilder();
builder.RegisterInstance<List<IStudent>>(new List<IStudent>() { new Student() { Name = "张三" }, new Student() { Name = "李四" } });
container = builder.Build();
List<IStudent> animals = container.Resolve<List<IStudent>>();
foreach (var item in animals)
{
item.Learn("实例集合注册");
}
9.泛型注册
builder = new ContainerBuilder();
builder.RegisterGeneric(typeof(List<>)).As(typeof(IList<>));
container = builder.Build();
IList<string> list = container.Resolve<IList<string>>();
10.非覆盖注册
builder = new ContainerBuilder();
builder.RegisterInstance<IStudent>(new Student() { Name = "张三" });
builder.RegisterInstance<IStudent>(new Student() { Name = "李四" }).PreserveExistingDefaults(); //指定为非默认值
container = builder.Build();
student = container.Resolve<IStudent>();
student.Learn("非覆盖注册");
11.生命周期注入的生命周期
builder = new ContainerBuilder();
builder.RegisterType<Student>().As<IStudent>().InstancePerLifetimeScope();
container = builder.Build();
IStudent s1 = container.Resolve<IStudent>();
IStudent s2 = container.Resolve<IStudent>();
Console.WriteLine(s1.Equals(s2));
using (ILifetimeScope lifetime = container.BeginLifetimeScope())
{
IStudent s3 = lifetime.Resolve<IStudent>();
IStudent s4 = lifetime.Resolve<IStudent>();
Console.WriteLine(s3.Equals(s4));
Console.WriteLine(s2.Equals(s3));
}