1

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

代码:

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 

也许我对范围的理解是错误的。如果是这样,请您解释一下。

我该怎么做才能在第二个块中获得不同的实例?

4

1 回答 1

3

问题是您正在解决容器之外的问题 -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 有一些关于生命周期范围的好信息,您可能想查看

于 2013-10-01T22:31:53.017 回答