【发布时间】:2012-11-06 07:21:23
【问题描述】:
我正在尝试利用简单注射器中的一些不错的功能。
我目前在使用装饰器时遇到问题,但我期望它们也没有受到影响。
我是这样注册的:
container.RegisterManyForOpenGeneric(
typeof(ICommandHandler<>),
AppDomain.CurrentDomain.GetAssemblies());
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(CreateValidFriendlyUrlCommandHandler<>),
context => context.ServiceType == typeof(ICommandHandler<CreateProductCommand>)
);
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(CreateProductValidationCommandHandler<>),
context => context.ServiceType == typeof(ICommandHandler<CreateProductCommand>)
);
我想我一定遗漏了一些东西,因为我期望对 ICommandHandler<CreateProductCommand> 的调用会在运行之前调用 CreateValidFriendlyUrlCommandHandler<> 和 CreateProductValidationCommandHandler<>。
我尝试过这样的不同注册:
container.RegisterManyForOpenGeneric(
typeof(ICommandHandler<>),
AppDomain.CurrentDomain.GetAssemblies());
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(CreateValidFriendlyUrlCommandHandler<>),
context => context.ImplementationType == typeof(CreateProductCommandHandler)
);
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(CreateProductValidationCommandHandler<>),
context => context.ImplementationType == typeof(CreateProductCommandHandler)
);
当CreateProductValidationCommandHandler 和CreateValidFriendlyUrlCommandHandler 实现ICommandHandler<CreateProductCommand> 时,我认为在ICommandHandler<CreateProductCommand> 类型上为ICommandHandler<CreateProductCommand> 注册一个装饰器可能会遇到一些循环引用。
但改变这一点并没有什么不同。
这是我的CreateProductValidationCommandHandler<TCommand>:
public class CreateProductValidationCommandHandler<TCommand>
: ICommandHandler<CreateProductCommand>
{
private readonly ICommandHandler<TCommand> decorated;
private readonly IValidationService validationService;
public CreateProductValidationCommandHandler(
ICommandHandler<TCommand> decorated,
IValidationService validationService)
{
this.decorated = decorated;
this.validationService = validationService;
}
public void Handle(CreateProductCommand command)
{
if (!validationService.IsValidFriendlyName(
command.Product.ProductFriendlyUrl))
{
command.ModelStateDictionary.AddModelError(
"ProductFriendlyUrl",
"The Friendly Product Name is not valid...");
return;
}
if (!validationService.IsUniqueFriendlyName(
command.Product.ProductFriendlyUrl))
{
command.ModelStateDictionary.AddModelError(
"ProductFriendlyUrl",
"The Friendly Product Name is ...");
return;
}
}
}
这是我的CreateValidFriendlyUrlCommandHandler<TCommand>:
public class CreateValidFriendlyUrlCommandHandler<TCommand>
: ICommandHandler<CreateProductCommand>
{
private readonly ICommandHandler<TCommand> decorated;
public CreateValidFriendlyUrlCommandHandler(ICommandHandler<TCommand> decorated)
{
this.decorated = decorated;
}
public void Handle(CreateProductCommand command)
{
if (string.IsNullOrWhiteSpace(
command.Product.ProductFriendlyUrl))
{
command.Product.ProductFriendlyUrl =
MakeFriendlyUrl(command.Product.Name);
}
}
}
【问题讨论】:
-
你的装饰器不应该是通用的。事实上,从技术上讲,它们不是装饰器 :-)
-
请注意
Appdomain.CurrentDomain.GeAssemblies只返回已经加载的程序集。如果所有实现都与ICommandHandler<T>在同一个程序集中,那不会有问题,但要小心。
标签: c# .net dependency-injection ioc-container simple-injector