Generics LightInject注册泛型查询处理程序
我对CQRS模式非常陌生,在将所有这些与我选择的依赖注入容器结合起来时遇到了问题 我拥有的是一个通用查询对象Generics LightInject注册泛型查询处理程序,generics,dependencies,registration,code-injection,Generics,Dependencies,Registration,Code Injection,我对CQRS模式非常陌生,在将所有这些与我选择的依赖注入容器结合起来时遇到了问题 我拥有的是一个通用查询对象 public interface IQuery<TResult> { } 公共接口iquiry { } 它由GenericQuery实现 public class GenericQuery<TSrcEntity> : IQuery<IEnumerable<TSrcEntity>> { public Expression<F
public interface IQuery<TResult>
{
}
公共接口iquiry
{
}
它由GenericQuery实现
public class GenericQuery<TSrcEntity> : IQuery<IEnumerable<TSrcEntity>>
{
public Expression<Func<TSrcEntity, bool>> Filter { get; set; }
public Func<IQueryable<TSrcEntity>, IOrderedQueryable<TSrcEntity>> OrderBy { get; set; }
public IEnumerable<string> IncludeProperties { get; set; }
}
公共类泛型查询:IQuery
{
公共表达式筛选器{get;set;}
公共Func OrderBy{get;set;}
公共IEnumerable IncludeProperty{get;set;}
}
然后,我通过查询分派器来处理所有这些,查询分派器通过依赖项解析器确定要使用哪个处理程序
public class QueryDispatcher:IQueryDispatcher
{
public TResult Dispatch<TQuery, TResult>(TQuery query) where TQuery : IQuery<TResult>
{
var handler = DependencyResolver.Get<IQueryHandler<TQuery,TResult>>();
return handler.Retreive(query);
}
}
公共类QueryDispatcher:IQueryDispatcher
{
公共TResult调度(TQuery查询),其中TQuery:IQuery
{
var handler=DependencyResolver.Get();
返回处理程序.检索(查询);
}
}
处理程序实现
public class GenericQueryHandler<TSrcEntity> : IQueryHandler<GenericQuery<TSrcEntity>, IEnumerable<TSrcEntity>> where TSrcEntity : class
{
public IEnumerable<TSrcEntity> Retreive(GenericQuery<TSrcEntity> query)
{
return GetDocuments();
}
公共类GenericQueryHandler:IQueryHandler其中TSrcEntity:class
{
公共IEnumerable检索(GenericQuery查询)
{
返回GetDocuments();
}
我的LightInject注册如下
class Program
{
static void Main(string[] args)
{
var container = new ServiceContainer();
//service
container.Register<ITestService, TestService>();
//query
container.Register(typeof(IQuery<>), typeof(GenericQuery<>));
//handler This one works, but I dont want to register everything explicity.
container.Register(typeof(IQueryHandler<GenericQuery<Document>, IEnumerable<Document>>), typeof(GenericQueryHandler<Document>));
//dispatcher
container.Register<IQueryDispatcher, QueryDispatcher>();
DependencyResolver.SetResolver(container);
var service = container.GetInstance<ITestService>();
var a = service.GetDocuments();
}
类程序
{
静态void Main(字符串[]参数)
{
var container=新的ServiceContainer();
//服务
container.Register();
//质疑
Register(typeof(IQuery),typeof(GenericQuery));
//处理程序这一个工作,但我不想登记的一切明确。
容器寄存器(typeof(IQueryHandler),typeof(GenericQueryHandler));
//调度员
container.Register();
DependencyResolver.SetResolver(容器);
var service=container.GetInstance();
var a=service.GetDocuments();
}
只要我像这里看到的那样显式注册我的处理程序,一切都是顺利的
//handler This one works, but I dont want to register everything explicity.
container.Register(typeof(IQueryHandler<GenericQuery<Document>, IEnumerable<Document>>), typeof(GenericQueryHandler<Document>));
//这一个有效,但我不想明确地注册所有内容。
容器寄存器(typeof(IQueryHandler),typeof(GenericQueryHandler));
但我不想对每个实体都这样做。更熟悉LightInject的人能帮我吗
可以在以下位置找到示例程序:
谢谢我知道这是一篇老文章,但我也遇到了同样的问题,我找到了解决办法。我在这里找到了解决办法: 该页上的代码如下:
public static class ContainerExtensions
{
public static void RegisterCommandHandlers(this IServiceRegistry serviceRegistry)
{
var commandTypes =
Assembly.GetCallingAssembly()
.GetTypes()
.Select(t => GetGenericInterface(t, typeof(ICommandHandler<>)))
.Where(m => m != null);
RegisterHandlers(serviceRegistry, commandTypes);
serviceRegistry.Register<ICommandExecutor>(factory => new CommandExecutor((IServiceFactory)serviceRegistry));
serviceRegistry.Decorate(typeof(ICommandHandler<>), typeof(TransactionalCommandDecorator<>));
}
public static void RegisterQueryHandlers(this IServiceRegistry serviceRegistry)
{
var commandTypes =
Assembly.GetCallingAssembly()
.GetTypes()
.Select(t => GetGenericInterface(t, typeof(IQueryHandler<,>)))
.Where(m => m != null);
RegisterHandlers(serviceRegistry, commandTypes);
serviceRegistry.Register<IQueryExecutor>(factory => new QueryExecutor((IServiceFactory)serviceRegistry));
serviceRegistry.Decorate(typeof(IQueryHandler<,>), typeof(QueryHandlerLogDecorator<,>));
}
private static Tuple<Type, Type> GetGenericInterface(Type type, Type genericTypeDefinition)
{
var closedGenericInterface =
type.GetInterfaces()
.SingleOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == genericTypeDefinition);
if (closedGenericInterface != null)
{
var constructor = type.GetConstructors().FirstOrDefault();
if (constructor != null)
{
var isDecorator = constructor.GetParameters().Select(p => p.ParameterType).Contains(closedGenericInterface);
if (!isDecorator)
{
return Tuple.Create(closedGenericInterface, type);
}
}
}
return null;
}
private static void RegisterHandlers(IServiceRegistry registry, IEnumerable<Tuple<Type, Type>> handlers)
{
foreach (var handler in handlers)
{
registry.Register(handler.Item1, handler.Item2);
}
}
}
公共静态类ContainerExtensions
{
公共静态无效注册表CommandHandlers(此IServiceRegistry serviceRegistry)
{
var命令类型=
Assembly.GetCallingAssembly()
.GetTypes()
.Select(t=>GetGenericInterface(t,typeof(ICommandHandler)))
。其中(m=>m!=null);
RegisterHandler(serviceRegistry、CommandType);
Register(factory=>newcommandexecutor((IServiceFactory)serviceRegistry));
decoration(typeof(ICommandHandler),typeof(TransactionalCommandDecorator));
}
公共静态无效注册表QueryHandler(此IServiceRegistry服务注册表)
{
var命令类型=
Assembly.GetCallingAssembly()
.GetTypes()
.Select(t=>GetGenericInterface(t,typeof(IQueryHandler)))
。其中(m=>m!=null);
RegisterHandler(serviceRegistry、CommandType);
Register(工厂=>newQueryExecutor((IServiceFactory)serviceRegistry));
decoration(typeof(IQueryHandler)、typeof(QueryHandlerLogDecorator));
}
私有静态元组GetGenericInterface(类型类型,类型genericTypeDefinition)
{
var closedGenericInterface=
type.GetInterfaces()
.SingleOrDefault(i=>i.IsGenericType&&i.GetGenericTypeDefinition()==genericTypeDefinition);
if(closedGenericInterface!=null)
{
var constructor=type.GetConstructors().FirstOrDefault();
if(构造函数!=null)
{
var isDecorator=constructor.GetParameters().Select(p=>p.ParameterType).Contains(closedGenericInterface);
如果(!isDecorator)
{
返回Tuple.Create(closedGenericInterface,type);
}
}
}
返回null;
}
私有静态无效注册表句柄(IServiceRegistry注册表,IEnumerable句柄)
{
foreach(处理程序中的变量处理程序)
{
Register(handler.Item1,handler.Item2);
}
}
}
希望它也能帮助别人:)
干杯!假设LINQ本身为任何过滤器映射减少需求提供了足够的抽象,那么我认为您额外的抽象似乎是不必要的复杂性。此外,我将删除您问题中的任何CQRS引用,因为它纯粹是关于在您的容器中注册泛型的。谢谢Alexey。我对帖子做了一些更改。您你说得对,注册泛型比注册CQR更重要。@SimonFine你找到解决办法了吗?我面临着确切的问题。