事件
AutoFac支持三种事件:OnActivating,OnActivated,OnRelease。OnActivating在注册组件使用之前会被调用,此时可以替换实现类或者进行一些其他的初始化工作,OnActivated在实例化之后会被调用,OnRelease在组件释放之后会被调用。
1 public class MyEvent : IDisposable
2 {
3 public MyEvent(string input)
4 {
5 Console.WriteLine(input);
6 }
7
8 public MyEvent()
9 {
10 Console.WriteLine("Init");
11 }
12
13 public void Dispose()
14 {
15 Console.WriteLine("Dispose");
16 }
17 }
1 public void test_event()
2 {
3 var builder = new ContainerBuilder();
4 builder.RegisterType<MyEvent>().
5 OnActivating(e => e.ReplaceInstance(new MyEvent("input"))).
6 OnActivated(e => Console.WriteLine("OnActivated")).
7 OnRelease(e => Console.WriteLine("OnRelease"));
8
9
10 using (IContainer container = builder.Build())
11 {
12 using (var myEvent = container.Resolve<MyEvent>())
13 {
14 }
15 }
16 }
此时的输出为:
1 Init
2 input
3 OnActivated
4 Dispose
5 OnRelease
利用事件可以在构造对象之后调用对象的方法:
1 [Fact]
2 public void call_method_when_init()
3 {
4 var builder = new ContainerBuilder();
5 builder.RegisterType<MyClassWithMethod>().OnActivating(e => e.Instance.Add(5));
6 IContainer container = builder.Build();
7 Assert.Equal(5, container.Resolve<MyClassWithMethod>().Index);
8 }
9
10 public class MyClassWithMethod
11 {
12 public int Index { get; set; }
13 public void Add(int value)
14 {
15 Index = Index + value;
16 }
17 }
循环依赖
循环依赖是个比较头疼的问题,在AutoFac中很多循环依赖的场景不被支持:
1 public class ClassA
2 {
3 private readonly ClassB b;
4
5 public ClassA(ClassB b)
6 {
7 this.b = b;
8 }
9 }
10
11 public class ClassB
12 {
13 public ClassA A { get; set; }
14
15 }
16
17 [Fact]
18 public void circular_dependencies_exception()
19 {
20 var builder = new ContainerBuilder();
21 builder.Register(c => new ClassB(){A = c.Resolve<ClassA>()});
22 builder.Register(c => new ClassA(c.Resolve<ClassB>()));
23 IContainer container = builder.Build();
24 Assert.Throws(typeof(DependencyResolutionException), ()=>container.Resolve<ClassA>());
25 }
可以部分的解决这种循环依赖的问题,前提是ClassA和ClassB的生命周期不能都是InstancePerDependency
1 [Fact]
2 public void circular_dependencies_ok()
3 {
4 var builder = new ContainerBuilder();
5 builder.RegisterType<ClassB>().
6 PropertiesAutowired(PropertyWiringFlags.AllowCircularDependencies).SingleInstance();
7 builder.Register(c => new ClassA(c.Resolve<ClassB>()));
8 IContainer container = builder.Build();
9 Assert.NotNull(container.Resolve<ClassA>());
10 Assert.NotNull(container.Resolve<ClassB>());
11 Assert.NotNull(container.Resolve<ClassB>().A);
12 }
转载链接:http://niuyi.github.io/blog/2012/04/06/autofac-by-unit-test-2/