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();
}
我正在将 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();
}