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

时间:2014-09-04 16:35:51

标签: c# dependency-injection signalr autofac signalr-hub

我正在尝试以此测试通过的方式设置我的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);
}

即。我希望在单个Context内使用相同的Hub对象,但在创建新的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请求的工作单元生存期。)< / p>

1 个答案:

答案 0 :(得分:2)

@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