我正在尝试将我以前在Autofac中执行的操作转换为Microsoft依赖注入。我有一堆基于接口的RequestHandler:
public interface IRequestHandler<TParameter, TResult>
where TResult : IResponse
where TParameter : IRequest
{
TResult Handle(TParameter query);
}
我已经注册了所有请求处理程序和所有IResponse对象以及我的IRequest对象:
var request handlers = ReflectionUtils.GetClosedTypes(typeof(IRequestHandler<,>), assemblies);
foreach (var requestHandler in requestHandlers)
{
serviceCollection.AddScoped(requestHandler);
}
我收集所有要注册的类型:
public static IEnumerable<Type> GetClosedTypes(Type openGeneric, params Assembly[] assemblies)
{
if (assemblies == null || assemblies.Length == 0)
{
return new Type[0];
}
var list = new List<Type>();
foreach (var assembly in assemblies)
{
if (!assembly.IsDynamic)
{
var types = ReflectionUtils.GetExportedTypes(assembly);
var q = from type in types
from i in type.GetInterfaces()
where i.IsGenericType && i.GetGenericTypeDefinition() == openGeneric
select type;
list.AddRange(q);
}
}
return list;
}
我可以单步执行代码并查看它们已注册。然后,我希望能够通过一个RequestDispatcher来检索它们,这个RequestDispatcher从ServideProvider中检索项目并调用Handle方法:
public TResult Dispatch<TParameter, TResult>(TParameter query)
where TParameter : IRequest
where TResult : IResponse
{
//Get the approproprite command handler by resolving it from the autofac _serviceProvider based on the IQuery and IQueryResult
var handler = _serviceProvider.GetService<IRequestHandler<TParameter, TResult>>();
return handler.Handle(query);
}
但是GetService返回null。我怀疑它与物品在容器中的注册方式有关。以下是我在Autofac中注册事物的方法:
builder.RegisterAssemblyTypes(MyAssembly)
.AsClosedTypesOf(typeof(IRequestHandler<,>))
.InstancePerLifetimeScope()
.AsImplementedInterfaces();
答案 0 :(得分:2)
您应该首先更改将类型注册到DI容器中的方式。
我认为仅注册具体类型将不允许服务提供商解析其接口(如果未明确注册)。
尝试提供所需的ServiceCollection
所有类型:
public static IDictionary<Type, Type> GetClosedTypesRegistrations(Type openGeneric, params Assembly[] assemblies)
{
if (assemblies == null || assemblies.Length == 0)
{
return new Dictionary<Type, Type>();
}
return assemblies
.Where(a => !a.IsDynamic)
.SelectMany(ReflectionUtils.GetExportedTypes)
.SelectMany(t => t.GetInterfaces(), (t, i) => new { service = i, type = t } )
.Where(r => r.service.IsGenericType && r.service.GetGenericTypeDefinition() == openGeneric)
.ToDictionary(r => r.service, r => r.type);
}
内部ConfigureServices
:
var requestHandlers = ReflectionUtils.GetClosedTypesRegistrations(typeof(IRequestHandler<,>), assemblies);
foreach (var requestHandler in requestHandlers)
{
serviceCollection.AddScoped(requestHandler.Key, requestHandler.Value);
}