具有BeginLifetimeScope的Autofac LifetimeScope无法正常工作

时间:2013-10-01 15:10:52

标签: autofac lifetime-scoping

我正在尝试评估Autofac的范围,据我了解,当一个实例被声明为InstancePerLifetimeScope时,然后在using(container.BeginLifetimeScope())块中,我们应该获得相同的实例。但在另一个这样的块中,我们应该得到一个不同的实例。但我的代码(在linqpad中)给了我相同的实例。然而,温莎的生活方式就像我认为的那样有效。

代码:

static IContainer glkernel;
void Main()
{
  var builder = new ContainerBuilder();
  builder.RegisterType<Controller>();
  builder.RegisterType<A>().As<IInterface>().InstancePerLifetimeScope();
  glkernel = builder.Build();

  using (glkernel.BeginLifetimeScope()){
    Controller c1 = glkernel.Resolve<Controller>();
    c1.GetA();//should get instance 1
    c1.GetA();//should get instance 1
  }

  using (glkernel.BeginLifetimeScope()){
    Controller d = glkernel.Resolve<Controller>();
    d.GetA();//should get instance 2
    d.GetA();//should get instance 2
  }
}

public interface IInterface
{
  void DoWork(string s);
}

public class A : IInterface
{
  public A()
  {
    ID = "AAA-"+Guid.NewGuid().ToString().Substring(1,4);
  }
  public string ID { get; set; }
  public string Name { get; set; }
  public void DoWork(string s)
  {
    Display(ID,"working...."+s);
  }
}

public static void Display(string id, string mesg)
{
  mesg.Dump(id);
}

public class Controller 
{
  public Controller()
  {
    ("controller ins").Dump();
  }

  public void GetA()
  {
    //IInterface a = _kernel.Resolve<IInterface>();
    foreach(IInterface a in glkernel.Resolve<IEnumerable<IInterface>>())
    {
      a.DoWork("from A");
    }
  }
}

输出结果为:

controller ins

AAA-04a0 
working....from A 

AAA-04a0 
working....from A 

controller ins

AAA-04a0 
working....from A 

AAA-04a0 
working....from A 

也许我对范围界定的理解是错误的。如果是的话,请你解释一下。

我需要做些什么才能在第二个区块中获得不同的实例?

1 个答案:

答案 0 :(得分:2)

问题是你要从容器中解决问题 - glkernel而不是生命范围之外的问题。容器生命周期范围 - 根生存期范围。

改为退出生命周期范围。这可能意味着您需要更改控制器以传递组件列表而不是使用服务位置。

public class Controller 
{
  private IEnumerable<IInterface> _interfaces;
  public Controller(IEnumerable<IInterface> interfaces)
  {
    this._interfaces = interfaces;
    ("controller ins").Dump();
  }

  public void GetA()
  {
    foreach(IInterface a in this._interfaces)
    {
      a.DoWork("from A");
    }
  }
}

然后很容易切换你的分辨率代码。

using (var scope1 = glkernel.BeginLifetimeScope()){
  Controller c1 = scope1.Resolve<Controller>();
  c1.GetA();
  c1.GetA();
}

using (var scope2 = glkernel.BeginLifetimeScope()){
  Controller c2 = scope2.Resolve<Controller>();
  c2.GetA();
  c2.GetA();
}

Autofac wiki有一些good information on lifetime scopes you might want to check out