ILifetimeScope.ResolveNamed ComponentNotRegisteredException
本文关键字:ComponentNotRegisteredException ResolveNamed ILifetimeScope | 更新日期: 2023-09-27 17:58:40
我将ILifetimeScope
传递给类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();
}
}
抛出的异常是
请求的服务"TypeA(ISomeInterface)"尚未注册。若要避免此异常,请注册一个组件以提供服务,使用IsRegistered()检查服务注册,或者使用ResolveOption()方法解析可选依赖项。
我按照错误的建议进行了检查,检查了IsRegistered(typeof(ISomeInterface))
和IsRegistered(typeof(TypeA))
,结果都是True
。
我已经进行了一些运行时调试,并验证了_scope.ComponentRegistry.Registrations
中存在该类型,但我注意到该特定类型的范围是CurrentScopeLifetime
,而其他一些类型是RootScopeLifetime
。我不确定这是否有任何意义。
我尝试过以几种不同的方式注册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();
}