【发布时间】:2016-04-05 14:11:37
【问题描述】:
我是 CQRS 模式的新手,但我想了解您为什么应该使用两个接口:
public interface IQuery{}
public interface ICommand{}
而不是只有一个接口(例如 IExecutable 或其他...)
比您还拥有一个处理程序(例如 IExecutionHandler 或其他...)
如果您愿意,您仍然可以将其拆分为 ICommandExecutionHandler 和 IQueryExecutionHandler
更新:尝试
下一个代码只是我如何看待它的一个示例。这可能是我完全错误的......所以请分享你的担忧/我的错误。我只是想明白这一点。
public interface IExecutable { }
public interface ICommand : IExecutable { }
public interface IReturnCommand<TOutput>: ICommand
{
TOutput Result { get; set; }
}
public interface IQuery<TOutput>: IExecutable
{
TOutput Result { get; set; }
}
public interface IExecutionHandler<in T>: IDisposable where T : IExecutable
{
void Execute(T executable);
}
public class CreateAttachments : IReturnCommand<List<Guid>>
{
public List<Attachment> Attachments { get; set; }
public List<Guid> Result { get; set; }
}
public abstract class BaseExecutionHandler : IDisposable
{
protected readonly IUnitOfWork UnitOfWork;
private bool _disposed;
protected BaseExecutionHandler(IUnitOfWork unitOfWork)
{
UnitOfWork = unitOfWork;
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
UnitOfWork.Dispose();
}
}
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
public class AttachmentCommandHandler : BaseExecutionHandler,
IExecutionHandler<CreateAttachments>
{
public AttachmentCommandHandler(IUnitOfWork unitOfWork) : base(unitOfWork)
{
}
public void Execute(CreateAttachments command)
{
command.Result = command.Attachments.Select(x => UnitOfWork.Create(x)).ToList();
}
}
public interface IProcessor : IDisposable
{
void Process<TExecutable>(TExecutable command) where TExecutable : IExecutable;
}
public class Processor : IProcessor
{
private readonly Dictionary<IExecutable, IExecutionHandler<IExecutable>> _handlers;
private readonly IUnitOfWork _unitOfWork;
private bool _disposed;
public Processor(IUnitOfWork unitOfWork)
{
_handlers = new Dictionary<IExecutable, IExecutionHandler<IExecutable>>();
_unitOfWork = unitOfWork;
}
private IExecutionHandler<IExecutable> GetHandler<TExecutable>(TExecutable executable) where TExecutable: IExecutable
{
if (_handlers.ContainsKey(executable))
{
return _handlers[executable];
}
var handlerType = typeof(IExecutionHandler<>).MakeGenericType(executable.GetType());
var handler = Activator.CreateInstance(handlerType, _unitOfWork) as IExecutionHandler<IExecutable>;
_handlers.Add(executable, handler);
return handler;
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
foreach (var handler in _handlers.Values)
{
handler.Dispose();
}
}
}
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Process<TExecutable>(TExecutable executable) where TExecutable : IExecutable
{
var handler = GetHandler(executable);
handler.Execute(executable);
}
}
public class AttachmentController : ApiController
{
private readonly IProcessor _processor;
public AttachmentController(IProcessor processor)
{
_processor = processor;
}
public List<Guid> Post(List<Attachment> attachments)
{
var command = new CreateAttachments { Attachments = attachments };
_processor.Process(command);
return command.Result;
}
[EnableQuery]
public IQueryable<Attachment> Get()
{
var query = new GetAllAttachments { };
_processor.Process(query);
return query.Result;
}
protected override void Dispose(bool disposing)
{
_processor.Dispose();
base.Dispose(disposing);
}
}
【问题讨论】: