Resolve component in both tagged scope and untagged scope

假装没事ソ 提交于 2020-01-15 17:19:12

问题


I'm try to supply a different service to some tagged lifetime scopes in AutoFac, but can't seem to get the hang of it.

I've tried using the custom lifetime from Instance per matching lifetime scope, with default? but that didn't work.

I've written a test that illustrates what I'm trying to do:

[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));
    }
}

Is this possible?


回答1:


The solution could be to provide these custom services for the lifetime scope when you create the scope. When creating a new lifetime scope with container.BeginLifetimeScope you can provide additional Action<ContainerBuilder> parameter to define some custom registrations for this particular lifetime scope.

So, for your code, instead of global registration for ChildB, you could move it to per-scope registration. It could look something like that:

[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: Avoiding injecting lifetime scope is understandable. Another solution could be picking proper implementation, based on lifetime scope tag, similar to selection of implementation based on parameter, described in 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 ...


来源:https://stackoverflow.com/questions/55323684/resolve-component-in-both-tagged-scope-and-untagged-scope

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!