AutoFac使用方法总结二:事件与依赖循环

     事件

     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/

posted on   SuperSnowYao  阅读(1657)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示