services.Scan(scan => scan.FromAssemblies(typeof(IQueryHandler<,>).Assembly)
.AddClasses(classes => classes.AssignableTo(typeof(IQueryHandler<,>)))
.AsImplementedInterfaces()
.WithScopedLifetime());
并且它没有注册任何QueryHandler。但对于命令
services.Scan(scan => scan.FromAssemblies(typeof(ICommandHandler<>).Assembly)
.AddClasses(classes => classes.AssignableTo(typeof(ICommandHandler<>)))
.AsImplementedInterfaces()
.WithScopedLifetime());
它有效。我有什么不对吗?我试过跟随:
var queryTypes = typeof(IQuery<>)
.GetTypeInfo()
.Assembly.GetTypes()
.Where(t => t.GetTypeInfo() != null
&& !t.GetTypeInfo().IsInterface && !t.GetTypeInfo().IsAbstract
&& t.GetTypeInfo().ImplementedInterfaces.Any(i => i.Name.Equals("IQuery`1")));
var handlerTypes = typeof(IQueryHandler<,>)
.GetTypeInfo()
.Assembly.GetTypes()
.Where(t => t.GetTypeInfo() != null && !t.GetTypeInfo().IsInterface
&& !t.GetTypeInfo().IsAbstract
&& t.GetTypeInfo().ImplementedInterfaces.Any(i => i.Name.Equals("IQueryHandler`2")));
var closedHandlers = queryTypes.Select(t => typeof(IQueryHandler<,>).MakeGenericType(t, t.GetTypeInfo().ImplementedInterfaces.First().GenericTypeArguments[0]));
foreach (var closedHandler in closedHandlers)
{
// services.AddTransient(typeof(IQueryHandler<,>), closedHandler);
var implementation = handlerTypes.FirstOrDefault(t => t.GetTypeInfo().ImplementedInterfaces.Any(i => i.FullName.Equals(closedHandler.FullName)));
if (implementation != null)
{
// services.AddTransient(typeof(IQueryHandler<,>), implementation);
services.AddTransient(closedHandler, implementation);
}
}
并且在服务竞争中似乎是正确的,但解决崩溃。如果不使用某些第三方容器,这可能吗? THX
更新#1:
现在它可以将foreach更新为:
foreach (var closedHandler in closedHandlers)
{
// services.AddTransient(typeof(IQueryHandler<,>), closedHandler);
var implementation = handlerTypes.FirstOrDefault(t => t.GetTypeInfo().ImplementedInterfaces.Any(i => i.FullName.Equals(closedHandler.FullName)));
var imp = implementation.MakeGenericType(closedHandler.GenericTypeArguments[0], closedHandler.GenericTypeArguments[1]);
if (implementation != null)
{
// services.AddTransient(typeof(IQueryHandler<,>), implementation);
services.AddTransient(closedHandler, imp);
}
}
但它必须严格实现那些具有完全通用参数计数的接口。无论如何,我会尽力找到更好的方法