在标记范围和未标记范围内解析组件 [英] Resolve component in both tagged scope and untagged scope

查看:56
本文介绍了在标记范围和未标记范围内解析组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为AutoFac中某些标记的生命周期作用域提供不同的服务,但似乎无法掌握它.

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

这可能吗?

推荐答案

解决方案可能是在创建范围时为生存期范围提供这些自定义服务.使用container.BeginLifetimeScope创建新的生存期范围时,可以提供其他Action<ContainerBuilder>参数来为此特定生存期范围定义一些自定义注册.

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.

因此,对于您的代码,可以将其移至每个作用域的注册,而不是针对ChildB的全局注册.看起来可能像这样:

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

避免注入生命周期范围是可以理解的.另一个解决方案可能是基于生命周期作用域标签来选择适当的实现,类似于基于参数选择实现,如文档:

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 ...

这篇关于在标记范围和未标记范围内解析组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆