【发布时间】:2015-03-09 15:33:11
【问题描述】:
所以我在处理某些命令后使用装饰器进行打印。我的问题是用户是否想重印。我创建了一个从 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
}
}
}
【问题讨论】:
-
我发现你的空检查有点吓人。为什么你的装饰者没有数据库或没有被装饰者是有效的?通常,您应该通过在构造函数中注入所有必需的依赖项并在其中添加保护语句来防止无效状态。这可以防止您的代码因空检查而变得复杂。
-
关于那些“可选依赖项”,请查看this article of mine,它解释了为什么“依赖项几乎不应该是可选的”。
-
对于空检查,想法是只有在跟踪打印时才需要数据库,在我看来这是可选的。我最初将处理程序检查为 null,因为我认为我可以直接将
Reprint命令与装饰器一起使用,而无需处理程序,我现在可以删除它。
标签: c# decorator simple-injector