代码改变世界

AutoFac使用方法总结:Part II

2016-04-21 09:56  Dorisoy  阅读(263)  评论(0编辑  收藏  举报

事件

AutoFac支持三种事件:OnActivating,OnActivated,OnRelease。OnActivating在注册组件使用之前会被调用,此时可以替换实现类或者进行一些其他的初始化工作,OnActivated在实例化之后会被调用,OnRelease在组件释放之后会被调用。

 public class MyEvent : IDisposable
  {
      public MyEvent(string input)
      {
          Console.WriteLine(input);
      }

      public MyEvent()
      {
          Console.WriteLine("Init");
      }

      public void Dispose()
      {
          Console.WriteLine("Dispose");
      }
  }
public void test_event()
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<MyEvent>().
            OnActivating(e => e.ReplaceInstance(new MyEvent("input"))).
            OnActivated(e => Console.WriteLine("OnActivated")).
            OnRelease(e => Console.WriteLine("OnRelease"));


        using (IContainer container = builder.Build())
        {
            using (var myEvent = container.Resolve<MyEvent>())
            {
            }
        }
    }

 

 

此时的输出为:

Init
input
OnActivated
Dispose
OnRelease

  

利用事件可以在构造对象之后调用对象的方法:

 [Fact]
    public void call_method_when_init()
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<MyClassWithMethod>().OnActivating(e => e.Instance.Add(5));
        IContainer container = builder.Build();
        Assert.Equal(5, container.Resolve<MyClassWithMethod>().Index);
    }
  public class MyClassWithMethod
  {
      public int Index { get; set; }
      public void Add(int value)
      {
          Index = Index + value;
      }
  }

 

循环依赖

循环依赖是个比较头疼的问题,在AutoFac中很多循环依赖的场景不被支持:

 public class ClassA
  {
      private readonly ClassB b;

      public ClassA(ClassB b)
      {
          this.b = b;
      }
  }

  public class ClassB
  {
      public ClassA A { get; set; }
      
  }
 
 [Fact]
    public void circular_dependencies_exception()
    {
        var builder = new ContainerBuilder();
        builder.Register(c => new ClassB(){A = c.Resolve<ClassA>()});
        builder.Register(c => new ClassA(c.Resolve<ClassB>()));
        IContainer container = builder.Build();
        Assert.Throws(typeof(DependencyResolutionException), ()=>container.Resolve<ClassA>());
    }

 

可以部分的解决这种循环依赖的问题,前提是ClassA和ClassB的生命周期不能都是InstancePerDependency

[Fact]
    public void circular_dependencies_ok()
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<ClassB>().
            PropertiesAutowired(PropertyWiringFlags.AllowCircularDependencies).SingleInstance();
        builder.Register(c => new ClassA(c.Resolve<ClassB>()));
        IContainer container = builder.Build();
        Assert.NotNull(container.Resolve<ClassA>());
        Assert.NotNull(container.Resolve<ClassB>());
        Assert.NotNull(container.Resolve<ClassB>().A);
    }