所以我在处理某些命令后使用装饰器进行打印。我的问题是用户是否想要发行转载。我创建了一个从UI层发送的Reprint
命令类,但Reprint
命令不需要PrintDecorator
的单独处理程序,因为重新打印处理正是打印装饰器中的所有内容。是否有策略仅使用PrintDecorator
定位SimpleInjector
?我知道这可能违背了模式,但我能想到的唯一方法是为reprint命令创建一个空的命令处理程序,但这似乎不对。感谢。
public class Reprint : ICommandParam, IPrintFrom
{
public string Id { get; set; }
public string Printer { get; set; }
public int Copies { get; set; }
}
public class PrintDecorator<TCommand> : ICommandHandler<TCommand>
where TCommand : IPrintFrom
{
private readonly IFooService _svc;
private readonly ICommandHandler<TCommand> _handler;
public PrintDecorator(IFooService svc, ICommandHandler<TCommand> handler)
{
if (svc == null)
throw new ArgumentNullException("IFooService");
_svc = svc;
_handler = handler;
}
[Import] // optional
public IDatabase Database { get; set; }
public void Handle(TCommand commandParm)
{
if (_handler != null)
_handler.Handle(commandParm);
svc.GetDataFromService(commandParm.id);
svc.PrintData(commandParm.Printer, commandParm.Copies);
if (Database != null && commandParm.Copies > 0) {
// TODO - add a print record
}
}
}
答案 0 :(得分:2)
这完全取决于你想要什么。我的建议是将重新打印逻辑保持在一个真实的ReprintCommandHandler
内(可能通过注入一个与装饰器相同的方式进行打印的服务)。这对我来说似乎是合理的,因为在重印的情况下,重印是实际的商业逻辑,而不是交叉问题。
在这种情况下,您必须排除在PrintDecorator
周围装饰ReprintCommandHandler
,这可以按照以下方式完成:
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(PrintDecorator<>),
c => c.ServiceType != typeof(ICommandHandler<Reprint>));
另一方面,如果您希望将打印逻辑保留在PrintDecorator
内,而不必在业务层中复制此逻辑,则可以实现完全空ReprintCommandHandler
,或者您可以注册一个特殊的Null Object命令处理程序。
使用空处理程序当然是简单的,这将使您的配置非常简单:
// NOTE: Use RegisterManyForOpenGeneric for Simple Injector v2.x
container.Register(typeof(ICommandHandler<>),
new[] { typeof(ICommandHandler<>).Assembly });
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(PrintDecorator<>));
下行当然是你需要一个空类。所以另一种方法是实现Null Object模式,如下所示:
public class NullCommandHandler<T> : ICommandHandler<T> {
public void Handle(T command) { }
}
如果您有多个空实现,可以重复使用此实现,您可以按如下方式注册:
// NOTE: Use RegisterManyForOpenGeneric for Simple Injector v2.x
container.Register(typeof(ICommandHandler<>),
new[] { typeof(ICommandHandler<>).Assembly });
container.Register<ICommandHandler<Reprint>, NullCommandHandler<Reprint>>();
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(PrintDecorator<>));