如何使AutoFac在每个顶层对象中使用相同的嵌套依赖实例?(每个集线器的SignalR依赖项注入)

本文关键字:依赖 实例 嵌套 SignalR 注入 集线器 AutoFac 何使 对象 | 更新日期: 2023-09-27 18:20:37

我正试图以这样一种方式设置我的AutoFac注册,以使此测试通过:

[Test]
public void Autofac_registration_test()
{
    // Given
    var builder = new ContainerBuilder();
    RegisterServices(builder);
    var container = builder.Build();
    // When
    var firstHub = container.Resolve<Hub>();
    var secondHub = container.Resolve<Hub>();
    // Then
    firstHub.Should().NotBe(secondHub);
    firstHub.FooRepo.Context.Should().Be(firstHub.BarRepo.Context);
    firstHub.FooRepo.Context.Should().NotBe(secondHub.FooRepo.Context);
}

即,我想在单个Hub内一直使用相同的Context对象,但在创建新的Hub时使用不同的对象。

RegisterServices目前只是:

private void RegisterServices(ContainerBuilder builder)
{
    builder.RegisterType<MyHub>();
    builder.RegisterType<FooRepo>();
    builder.RegisterType<BarRepo>();
    builder.RegisterType<Context>(); // How should I scope this?
}

它在firstHub.FooRepo.Context.Should().Be(firstHub.BarRepo.Context);失败,因为Context是临时作用域的。

但是每个生命周期的作用域上下文也会失败,这次是在firstHub.FooRepo.Context.Should().NotBe(secondHub.FooRepo.Context);

感觉这是一件合理的事情,所以我在这里错过了任何明显的东西吗?还是我必须手动跟踪Hub的创建?

(就上下文而言,这是针对SignalR应用程序的。集线器是根据SignalR请求创建的,因此这是为了在正常的webby情况下匹配HTTP请求的工作寿命单位)。

如何使AutoFac在每个顶层对象中使用相同的嵌套依赖实例?(每个集线器的SignalR依赖项注入)

@Steven在评论中所说的是正确的,我需要一种按对象图的生活方式。

Castle。Windsor支持这一点,所以我切换到使用它来进行依赖项注入,而不是AutoFac。注册现在看起来像:

container.Register(Component.For<Hub>().LifestyleTransient());
container.Register(Component.For<FooRepo>().LifestyleTransient());
container.Register(Component.For<BarRepo>().LifestyleTransient());
container.Register(Component.For<Context>().LifestyleBoundTo<Hub>()); // Important bit

有关详细信息,请参阅:http://docs.castleproject.org/Windsor.LifeStyles.ashx?HL=scope#Bound_8