Autofac基本使用
名词解释:
组件(Components):容器中的基本单元,凡是注册到容器中的都叫组件(包含暴漏的服务类型、生命周期域、绑定的具象对象等等基本信息)
服务(Services)::类似于组件的暴露类型,As方法后面中的对象类型,可以有多个
生命周期作用域(LifeTimeScope):
-
生命周期:服务实例在应用程序中存在的时间长度,从开始实例化到最后释放
-
作用域:服务在应用程序中可以消费的地方
-
生命周期作用域:上面的两个概念,应用中的一个工作单元
注册组件的几个方法
1、反射注册:直接指定注入的对象和暴露类型,使用RegisterType<T>或者RegisterType(typeof(T))方法
2、实例注册:使用RegisterInstance()方法
3、Lambda注册
4、泛型注册(最常用)
5、条件注册:
-
IfNotRegistered表示:如果没注册过xxx,就执行语句:
builder.RegisterType<TeacherRepository>()
.AsSelf()
.IfNotRegistered(typeof(ITeacherRepository));
-
OnlyIf表示:只有...,才会执行语句:
builder.RegisterType<TeacherService>()
.AsSelf()
.As<ITeacherService>()
.OnlyIf(x =>
x.IsRegistered(new TypedService(typeof(ITeacherRepository)))||
x.IsRegistered(new TypedService(typeof(TeacherRepository))));
6、程序集批量注册,利用反射实现
7、属性注入:属性注入与构造注入不同,是将容器内对应的组件直接注入到类内的属性中去
-
要使用这种属性注入,在注册该属性所属类的时候,需要使用
PropertiesAutowired()
builder.RegisterType<TeacherService>().PropertiesAutowired();
构造注入如果当参数的对象在容器中不存在的时候,解析会报错,属性注入不会报错
暴露服务
1、As<xxx>()函数,表示以其自身为暴露类型,当没有标注暴露服务时候的默认
下面四种方法等效:
builder.RegisterType<TestService>();//不标注,默认以自身类型暴露服务
builder.RegisterType<TestService>().AsSelf();
builder.RegisterType<TestService>().As<TestService>();
builder.RegisterType<TestService>().As(typeof(TestService));
2、以实现的接口暴露服务:使用As()方法,暴露类型可以是多个
builder.RegisterType<CallLogger>()
.As<ILogger>()
.As<ICallInterceptor>()
.AsSelf();
生命周期作用域
Autofac的生命周期作用域
瞬时单例(Instance Per Dependency)即:每次从容器中拿出来的都是全新的对象,相当于每次new出来一个,在其他容器中被叫做“Transient”(瞬时)或者“Factory”(工厂)
注册:使用InstanPerDependency()方法标注,如果不标注则为默认
builder.RegisterType<TestService>().As<ITestService>();//默认为瞬时模式
builder.RegisterType<TestService>().As<ITestService>().InstancePerDependency();
var t1 = Container.Instance.Resolve<ITestService>();
Console.WriteLine($"t1.HashCode:{t1.GetHashCode()}");
var t2 = Container.Instance.Resolve<ITestService>();
Console.WriteLine($"t2.HashCode:{t2.GetHashCode()}");
结果:

全局单例(Single Instance):SingleInstance
builder.RegisterType<TestService>().As<ITestService>().SingleInstance();
var t1 = Container.Instance.Resolve<ITestService>();
Console.WriteLine($"t1.HashCode:{t1.GetHashCode()}");
var t2 = Container.Instance.Resolve<ITestService>();
Console.WriteLine($"t2.HashCode:{t2.GetHashCode()}");
结果:

域内单例(Instance Per Lifetime Scope):在每个生命周期内都是单例
builder.RegisterType<TestService>().As<ITestService>().InstancePerLifetimeScope();
using (var scope1 = Container.Instance.BeginLifetimeScope())
{
var t1 = scope1.Resolve<ITestService>();
Console.WriteLine($"t1.HashCode:{t1.GetHashCode()}");
var t2 = scope1.Resolve<ITestService>();
Console.WriteLine($"t2.HashCode:{t2.GetHashCode()}");
}
using (var scope2 = Container.Instance.BeginLifetimeScope())
{
var t3 = scope2.Resolve<ITestService>();
Console.WriteLine($"t3.HashCode:{t3.GetHashCode()}");
var t4 = scope2.Resolve<ITestService>();
Console.WriteLine($"t4.HashCode:{t4.GetHashCode()}");
}
结果:

匹配域内单例(Instance Per Matching Lifetime Scope):InstancePerMatchingLifetimeScope(string tagName)在tagName标签域内就是单例
builder.RegisterType<TestService>().As<ITestService>().InstancePerMatchingLifetimeScope("test1");
using (var scope1 = Container.Instance.BeginLifetimeScope("test1"))
{
var t1 = scope1.Resolve<ITestService>();
Console.WriteLine($"t1.HashCode:{t1.GetHashCode()}");
var t2 = scope1.Resolve<ITestService>();
Console.WriteLine($"t2.HashCode:{t2.GetHashCode()}");
}
using (var scope2 = Container.Instance.BeginLifetimeScope("test1"))
{
var t3 = scope2.Resolve<ITestService>();
Console.WriteLine($"t3.HashCode:{t3.GetHashCode()}");
var t4 = scope2.Resolve<ITestService>();
Console.WriteLine($"t4.HashCode:{t4.GetHashCode()}");
}
using (var scope3 = Container.Instance.BeginLifetimeScope())
{
try
{
var t5 = scope3.Resolve<ITestService>();
Console.WriteLine($"t5.HashCode:{t5.GetHashCode()}");
var t6 = scope3.Resolve<ITestService>();
Console.WriteLine($"t6.HashCode:{t6.GetHashCode()}");
}
catch (Exception ex)
{
Console.WriteLine($"ex{ex.ToString()}");
}
}
结果:

这里同一个tag但是不通的生命周期,哈希值也是不同的,t5和t6报异常是因为无标签的域或者不是test1标签都会异常
每次请求内单例(Instance Per Request):适用于“request”类型的应用
使用InstancePerRequest()方法标注
//使用静态字符串标记
builder.RegisterType<TestService>().InstancePerMatchingLifetimeScope(Autofac.Core.Lifetime.MatchingScopeLifetimeTags.RequestLifetimeScopeTag);
//或者直接写明字符串
builder.RegisterType<TestService>().InstancePerMatchingLifetimeScope("AutofacWebRequest");
本文介绍了Autofac的基本使用,包括组件、服务、生命周期作用域的概念,以及组件的多种注册方法如反射、实例、Lambda、泛型、条件和批量注册。还详细讲解了生命周期作用域的几种模式,如瞬时单例、全局单例、域内单例和匹配域内单例,并给出了相应的实例解析。

559

被折叠的 条评论
为什么被折叠?



