[英]How to register an optional decorator or decorator with optional parameters using structuremap asp.net mvc?
我在我的應用程序中實施了一個CQRS方法,受到這篇精彩文章的影響很大: https ://cuttingedge.it/blogs/steven/pivot/entry.php?id = 9 。 我的命令和處理程序代碼的設置與文章相同,而且該部分運行良好。 當我嘗試實現一個裝飾器類來處理命令的驗證時,我的問題出現了。 簡單的命令處理接口如下所示:
public interface ICommand
{
}
public interface ICommandHandler<TCommand>
{
void Handle(TCommand command);
}
然后對於驗證裝飾我有:
public class ValidationCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand> where TCommand : CommandBase
{
private readonly ICommandHandler<TCommand> _decoratedCommandHandler;
private readonly ICommandValidator<TCommand> _commandValidator;
public ValidationCommandHandlerDecorator(ICommandHandler<TCommand> decoratedCommandHandler, ICommandValidator<TCommand> commandValidator)
{
_decoratedCommandHandler = decoratedCommandHandler;
_commandValidator = commandValidator;
}
public void Handle(TCommand command)
{
if (_commandValidator != null)
{
var validationResult = _commandValidator.Validate(command);
if (validationResult != null)
{
command.Success = false;
command.Errors = validationResult;
return;
}
}
_decoratedCommandHandler.Handle(command);
command.Success = true;
}
}
它使用接口來定義驗證器:
public interface ICommandValidator<TCommand>
{
IEnumerable<string> Validate(TCommand command);
}
CommandBase
是一個簡單的基類,它允許我存儲命令的成功或失敗以及失敗時發生的錯誤。 我更喜歡這種方法作為拋出異常的替代方法。 所有命令都將繼承此基類。
public abstract class CommandBase : ICommand
{
public bool Success { get; set; }
public IEnumerable<string> Errors { get; set; }
}
這些都連接到結構映射注冊表中的IoC容器:
public class CommandRegistry : Registry
{
public CommandRegistry()
{
Scan(s =>
{
s.AssemblyContainingType<CommandBase>();
s.ConnectImplementationsToTypesClosing(typeof(ICommandHandler<>));
s.ConnectImplementationsToTypesClosing(typeof(ICommandValidator<>));
s.WithDefaultConventions();
For(typeof(ICommandHandler<>)).DecorateAllWith(typeof(ValidationCommandHandlerDecorator<>));
});
}
}
現在,因為我為每個ICommandHandler注冊了裝飾器,如果我有一個不需要驗證器且沒有定義驗證器的命令,則找不到ValidationCommandHandlerDecorator<TCommand>
類的ICommandValidator<TCommand> _commandValidator
私有字段因為它當然不存在並且總是會拋出結構圖錯誤:
“沒有注冊默認實例,無法自動確定類型'ICommandValidator'沒有為ICommandValidator指定配置”
結構映射中是否有一種方法可以定義如何構造ValidationCommandHandlerDecorator
,以便在不存在時使用某種類型的默認驗證器,而不必依賴於類中的容器或必須創建IValidateableCommandHandler<TCommand>
用驗證器處理命令的接口?
謝謝。
如果有人遇到這個問題,我想出的解決方案是將DefaultCommandValidator類添加為Null Object模式類:
public class DefaultCommandValidator<TCommand> : ICommandValidator<TCommand> where TCommand : CommandBase
{
public IEnumerable<string> Validate(TCommand command)
{
return Enumerable.Empty<string>();
}
}
然后將此行添加到結構映射注冊表:
For(typeof(ICommandValidator<>)).Use(typeof(DefaultCommandValidator<>));
我不知道這個結構映射語法實際上只會使用默認實例,如果它找不到ICommandValidator<TCommand>
的具體實現。 現在,如果我沒有驗證器,我只是不添加驗證器,而DefaultCommandValidator<TCommand>
實例用於返回空/成功驗證。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.