Разрешить компонент в области тегов и тегов без тегов - PullRequest
1 голос
/ 24 марта 2019

Я пытаюсь предоставить другой сервис для некоторых помеченных областей действия в AutoFac, но, похоже, не могу его освоить.

Я пытался использовать настраиваемое время жизни от Экземпляр на соответствующий диапазон времени жизни, по умолчанию? , но это не сработало.

Я написал тест, который иллюстрирует, что я пытаюсь сделать:

[TestMethod]
public void NamedLifetimeTests()
{
    var builder = new ContainerBuilder();
    builder.Register(c => new ChildA()).As<Parent>().InstancePerLifetimeScope();
    builder.Register(c => new ChildB()).As<Parent>().InstancePerMatchingLifetimeScope("system").PreserveExistingDefaults();

    var container = builder.Build();
    using (var scope = container.BeginLifetimeScope())
    {
        var parent = scope.Resolve<Parent>();
        Assert.IsTrue(parent.GetType() == typeof(ChildA));
    }

    using (var scope = container.BeginLifetimeScope("system"))
    {
        var parent = scope.Resolve<Parent>();
        Assert.IsTrue(parent.GetType() == typeof(ChildB));
    }
}

Возможно ли это?

1 Ответ

2 голосов
/ 28 марта 2019

Решением может быть предоставление этих пользовательских сервисов для жизненного диапазона при создании области действия. При создании новой области действия с помощью container.BeginLifetimeScope вы можете указать дополнительный параметр Action<ContainerBuilder>, чтобы определить некоторые пользовательские регистрации для этой конкретной области действия.

Таким образом, для вашего кода вместо глобальной регистрации для ChildB вы можете переместить его в область регистрации. Это может выглядеть примерно так:

[TestMethod]
public void NamedLifetimeTests()
{
    var builder = new ContainerBuilder();
    builder.Register(c => new ChildA()).As<Parent>().InstancePerLifetimeScope();    

    var container = builder.Build();
    using (var scope = container.BeginLifetimeScope())
    {
        var parent = scope.Resolve<Parent>();
        Assert.IsTrue(parent.GetType() == typeof(ChildA));
    }

    using (var scope = container.BeginLifetimeScope("system"), cb => { cb.RegisterType<ChildB>().As<Parent>(); }))
    {
        var parent = scope.Resolve<Parent>();
        Assert.IsTrue(parent.GetType() == typeof(ChildB));
    }
}

EDIT: Избегать введения объема жизни понятно. Другим решением может быть выбор правильной реализации, основанной на теге области действия, аналогично выбору реализации на основе параметра, описанного в docs :

// omitted ...
var builder = new ContainerBuilder();
builder.Register<Parent>(c =>
    {
        var currentScope = c.Resolve<ILifetimeScope>();
        if (currentScope.Tag?.ToString() == "system")
        {
            return new ChildB();
        }

        return new ChildA();
    }).InstancePerLifetimeScope();   

var container = builder.Build();
// omitted ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...