【问题标题】:Autofac LifetimeScope with BeginLifetimeScope not working带有 BeginLifetimeScope 的 Autofac LifetimeScope 不起作用
【发布时间】:2023-04-09 06:15:02
【问题描述】:

我正在尝试评估 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 

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

我必须做什么才能在第二个块中获得不同的实例?

【问题讨论】:

  • glkernel.BeginLifetimeScope() 调用返回新的作用域对象,但您不使用它,您总是从全局 glkernel 作用域解析,因此您总是得到相同的实例...

标签: autofac lifetime-scoping


【解决方案1】:

问题是您正在解决容器之外的问题 - 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

【讨论】:

  • 你是对的,就像上面的@nemesv 一样。我重写了代码并让它工作。只是指出温莎城堡的语法是: using (kernel.BeginScope()){ // code } .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-09
  • 2020-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多