支持netcore2.0 + framework4.6+
Install-Package Autofac.Annotation
var builder = new ContainerBuilder();
// 注册autofac打标签模式
builder.RegisterModule(new AutofacAnnotationModule(typeof(AnotationTest).Assembly));
//如果需要开启支持循环注入
//builder.RegisterModule(new AutofacAnnotationModule(typeof(AnotationTest).Assembly).SetAllowCircularDependencies(true));
var container = builder.Build();
var serviceB = container.Resolve<B>();
AutofacAnnotationModule有两种构造方法
说明:只能打在class上面(且不能是抽象class) 把某个类注册到autofac容器 例如:
//把class A 注册到容器
[Component]
public class A
{
public string Name { get; set; }
}
//如果 A有父类或者实现了接口 也会自动注册(排除非public的因为autofac不能注册私有类或接口)
public interface IB
{
}
public class ParentB:IB
{
public string Name1 { get; set; }
}
//把class B 注册到容器 并且把 B作为ParentB注册到容器 并且把B最为IB注册到容器
[Component]
public class B:ParentB
{
public string Name { get; set; }
}
[Component(AutofacScope = AutofacScope.SingleInstance)]
public class A
{
public string Name { get; set; }
}
public class B
{
}
[Component(typeof(B))]
public class A6:B
{
}
[Component("a4")]
public class A4
{
public string School { get; set; } = "测试2";
}
[Component(InitMethod = "start",DestroyMetnod = "destroy")]
public class A30
{
[Value("aaaaa")]
public string Test { get; set; }
public A29 a29;
void start(IComponentContext context)
{
this.Test = "bbbb";
a29 = context.Resolve<A29>();
}
void destroy()
{
this.Test = null;
a29.Test = null;
}
}
public class B
{
}
[Component(typeof(B),"a5")]
public class A5:B
{
public string School { get; set; } = "测试a5";
public override string GetSchool()
{
return this.School;
}
}
可以打在Field Property 构造方法的Parameter上面 其中Field 和 Property 支持在父类
[Component]
public class A16
{
public A16([Autowired]A21 a21)
{
Name = name;
A21 = a21;
}
[Autowired("A13")]
public B b1;
[Autowired]
public B B { get; set; }
//Required默认为true 如果装载错误会抛异常出来。如果指定为false则不抛异常
[Autowired("adadada",Required = false)]
public B b1;
}
{
"a9": "aaaaaaaaa",
"list": "1, 2, 3, 4 ",
"dic": "#{'name': 'name1','school': 'school1'}",
"parent": {
"name" : "yuzd"
},
"testInitField": 1,
"testInitProperty": 1,
}
[Component]
[PropertySource("/file/appsettings1.json")]
public class A10
{
public A10([Value("${a10}")]string school,[Value("${list}")]List<int> list,[Value("#{${dic}}")]Dictionary<string,string> dic)
{
this.School = school;
this.list = list;
this.dic = dic;
}
public string School { get; set; }
public List<int> list { get; set; }
public Dictionary<string,string> dic { get; set; }
[Value("${testInitField}")]
public int test;
[Value("${testInitProperty}")]
public int test2 { get; set; }
[Value("${parent:name}")]//json文件如果嵌套对象可以冒号隔开
public string ParentName { get; set; }
//可以直接指定值
[Value("2")]
public int test3 { get; set; }
}
<?xml version="1.0" encoding="utf-8" ?>
<autofac>
<a11>aaaaaaaaa1</a11>
<list>1,2,3</list>
<dic>#{'name': 'name1'}</dic>
</autofac>
[Component]
[PropertySource("/file/appsettings1.xml")]
public class A11
{
public A11([Value("${a11}")]string school,[Value("${list}")]List<int> list,[Value("#{${dic}}")]Dictionary<string,string> dic)
{
this.School = school;
this.list = list;
this.dic = dic;
}
public string School { get; set; }
public List<int> list { get; set; }
public Dictionary<string,string> dic { get; set; }
}
[AutoConfiguration]
public class TestConfiguration
{
//Bean标签只能搭配AutoConfiguration标签使用,在其他地方没有效
//并且是单例注册
[Bean]
private ITestModel4 getTest5()
{
return new TestModel4
{
Name = "getTest5"
};
}
}
在容器build完成后执行: 扫描指定的程序集,发现如果有打了AutoConfiguration标签的class,就会去识别有Bean标签的方法,并执行方法将方法返回实例注册为方法返回类型到容器! 一个程序集可以有多个AutoConfiguration标签的class会每个都加载。
AutoConfiguration标签的其他属性:
搭配如下代码可以设置过滤你想要加载的,比如你想要加载Key = “test” 的所有 AutoConfiguration标签class //builder.RegisterModule(new AutofacAnnotationModule(typeof(AnotationTest).Assembly).SetAutofacConfigurationKey("test"));
Bean标签的其他属性:
[Component] //注册到容器
[Aspect]//开启AOP拦截器
public class TestModel
{
[TestHelloBefor]//参考下面的类 这是一个前置拦截器
public virtual void Say()
{
Console.WriteLine("say");
}
[TestHelloAfter]//参考下面的类,这是一个后置拦截器
public virtual void SayAfter()
{
Console.WriteLine("SayAfter");
}
[TestHelloArround]//参考下面的类,这是一个环绕拦截器
public virtual void SayArround()
{
Console.WriteLine("SayArround");
}
}
//定义一个前置拦截器
public class TestHelloBefor : AspectBeforeAttribute
{
public override Task Before(IInvocation invocation)
{
Console.WriteLine("TestHelloBefor");
return Task.CompletedTask;
}
}
//定义一个后置拦截器
public class TestHelloAfter : AspectAfterAttribute
{
public override Task After(IInvocation invocation, Exception exp)
{
if(exp!=null) Console.WriteLine(exp.Message);
Console.WriteLine("TestHelloAfter");
return Task.CompletedTask;
}
}
//定义一个环绕拦截器
public class TestHelloArround : AspectAroundAttribute
{
public override Task After(IInvocation invocation, Exception exp)
{
if (exp != null) Console.WriteLine(exp.Message);
Console.WriteLine("TestHelloArround");
return Task.CompletedTask;
}
public override Task Before(IInvocation invocation)
{
Console.WriteLine("TestHelloArround.Before");
return Task.CompletedTask;
}
}
//测试代码
public void Test_Type_08()
{
var builder = new ContainerBuilder();
// autofac打标签模式
builder.RegisterModule(new AutofacAnnotationModule(typeof(TestModel).Assembly));
var container = builder.Build();
var a12 = container.Resolve<TestModel>();
a12.Say();
a12.SayAfter();
a12.SayArround();
}
public class AutofacAutowiredResolveBenchmark
{
private IContainer _container;
[GlobalSetup]
public void Setup()
{
var builder = new ContainerBuilder();
builder.RegisterType<A13>().As<B>().WithAttributeFiltering();
builder.RegisterType<Log>().As<AsyncInterceptor>();
builder.RegisterType<Log2>().Keyed<AsyncInterceptor>("log2");
builder.RegisterType<A21>().WithAttributeFiltering().PropertiesAutowired();
builder.RegisterType<A23>().As<IA23>().WithAttributeFiltering().PropertiesAutowired().EnableInterfaceInterceptors()
.InterceptedBy(typeof(AsyncInterceptor));
builder.RegisterType<A25>().WithAttributeFiltering().PropertiesAutowired().EnableClassInterceptors()
.InterceptedBy(new KeyedService("log2", typeof(AsyncInterceptor)));
_container = builder.Build();
}
[Benchmark]
public void Autofac()
{
var a1 = _container.Resolve<A25>();
var a2= a1.A23.GetSchool();
}
}
BenchmarkDotNet=v0.11.3, OS=Windows 10.0.18362
Intel Core i7-7700K CPU 4.20GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=2.2.300
[Host] : .NET Core 2.1.13 (CoreCLR 4.6.28008.01, CoreFX 4.6.28008.01), 64bit RyuJIT [AttachedDebugger]
DefaultJob : .NET Core 2.1.13 (CoreCLR 4.6.28008.01, CoreFX 4.6.28008.01), 64bit RyuJIT
Method | Mean | Error | StdDev |
---|---|---|---|
Autofac | 28.61 us | 0.2120 us | 0.1879 us |
//打标签模式
public class AutowiredResolveBenchmark
{
private IContainer _container;
[GlobalSetup]
public void Setup()
{
var builder = new ContainerBuilder();
builder.RegisterModule(new AutofacAnnotationModule(typeof(A13).Assembly));
_container = builder.Build();
}
[Benchmark]
public void AutofacAnnotation()
{
var a1 = _container.Resolve<A25>();
var a2= a1.A23.GetSchool();
}
}
BenchmarkDotNet=v0.11.3, OS=Windows 10.0.18362
Intel Core i7-7700K CPU 4.20GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=2.2.300
[Host] : .NET Core 2.1.13 (CoreCLR 4.6.28008.01, CoreFX 4.6.28008.01), 64bit RyuJIT [AttachedDebugger]
DefaultJob : .NET Core 2.1.13 (CoreCLR 4.6.28008.01, CoreFX 4.6.28008.01), 64bit RyuJIT
Method | Mean | Error | StdDev |
---|---|---|---|
AutofacAnnotation | 29.77 us | 0.2726 us | 0.2550 us |