ILifetimeScope.ResolveNamed ComponentNotRegisteredException

ILifetimeScope.ResolveNamed ComponentNotRegisteredException

我正在将 ILifetimeScope 传递给 class ctor,目的是通过名称和接口类型解析已注册的类型。名称存储在数据库中,可以是 5 或 6 种类型之一。例如:

public interface ISomeInterface
{
    Task SomeTask();
}

public class TypeA : ISomeInterface
{
    public async Task SomeTask()
    {
        await Task.Yield();
    }
}

public class TypeB : ISomeInterface
{
    public async Task SomeTask()
    {
        await Task.Delay(1000);
    }
}

public class SomeExecutor()
{
    private readonly ILifetimeScope _scope;

    public SomeExecutor(ILifetimeScope scope)
    {
        _scope = scope;
    }

    public async Task RunAsync(string type)
    {
        var class = _scope.ResolveNamed<ISomeInterface>(type); // This throws the exception.
        await class.SomeTask();
    }
}

public static class Program()
{
    static void Main()
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<SomeExecutor>();
        builder.RegisterAssemblyTypes(typeof(ISomeInterface).Assembly)
            .Where(x => typeof(ISomeInterface.IsAssignableFrom(x))
            .AsImplementedInterfaces()
            .AsSelf(); // Taken from Autofac docs.
        var container = builder.Build();
        var executor = container.Resolve<SomeExecutor>();
        executor.RunAsync("TypeA").Wait();
    }
}

抛出的异常是

The requested service 'TypeA (ISomeInterface)' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.

我按照错误提示进行了操作,并检查了 IsRegistered(typeof(ISomeInterface))IsRegistered(typeof(TypeA)),结果都是 True

我已经进行了一些运行时调试并验证了该类型存在于 _scope.ComponentRegistry.Registrations 中,但是我注意到该特定类型的范围是 CurrentScopeLifetime 而不是其他一些类型 [=20] =].我不确定这是否有任何意义。

我试过用几种不同的方式注册 ISomeInterface,例如

builder.RegisterAssemblyTypes(typeof(ISomeInterface).Assembly)
    .Where(x => typeof(ISomeInterface.IsAssignableFrom(x))
    .AsSelf();

builder.RegisterAssemblyTypes(typeof(ISomeInterface).Assembly)
    .Where(x => typeof(ISomeInterface.IsAssignableFrom(x))
    .As<ISomeInterface>();

builder.RegisterAssemblyTypes(typeof(ISomeInterface).Assembly)
    .Where(x => typeof(ISomeInterface.IsAssignableFrom(x))
    .As<ISomeInterface>()
    .AsSelf();

builder.RegisterAssemblyTypes(typeof(ISomeInterface).Assembly)
    .Where(x => typeof(ISomeInterface.IsAssignableFrom(x))
    .AsImplementedInterfaces()
    .AsSelf()
    .AssignableTo<ISomeInterface>();

可能还有我能想到的所有其他组合。

我的问题是,我做错了什么,我无法通过名称和接口解析类型?

如果您设置名称,那么它将起作用

builder.RegisterAssemblyTypes(typeof(ISomeInterface).Assembly)
    .Where(x => typeof(ISomeInterface).IsAssignableFrom(x))
    .AsImplementedInterfaces()
    .AsSelf().Named<ISomeInterface>(x => x.Name);

或者您可以使用实际类型而不是类型名称

public class SomeExecutor
{
    private readonly ILifetimeScope _scope;

    public SomeExecutor(ILifetimeScope scope)
    {
        _scope = scope;
    }

    public async Task RunAsync<T>() where T:ISomeInterface
    {
        var tt = _scope.Resolve<T>(); 
        await  tt.SomeTask();
    }
}

static void Main(string[] args)
{
        var builder = new ContainerBuilder();
        builder.RegisterType<SomeExecutor>();
        builder.RegisterAssemblyTypes(typeof(ISomeInterface).Assembly)
            .Where(x => typeof(ISomeInterface).IsAssignableFrom(x))
            .AsImplementedInterfaces()
            .AsSelf();
        var container = builder.Build();
        var executor = container.Resolve<SomeExecutor>();
        executor.RunAsync<TypeA>().Wait();
    }