首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Command/Decorator Pattern和Simple Injector从应用程序重新打印

使用Command/Decorator Pattern和Simple Injector从应用程序重新打印
EN

Stack Overflow用户
提问于 2015-03-09 23:33:11
回答 1查看 82关注 0票数 1

因此,在处理某些命令后,我使用装饰器进行打印。我的问题是,如果用户想要重印。我创建了一个从UI层发送的Reprint命令类,但是Reprint命令不需要独立于PrintDecorator的处理程序,因为重新打印处理就是打印装饰器中的所有内容。是否有仅针对SimpleInjectorPrintDecorator的策略?我知道这可能与模式背道而驰,但我能想到的唯一方法就是为reprint命令创建一个空的命令处理程序,但这似乎并不正确。谢谢。

代码语言:javascript
复制
  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
      }
    }
  }
EN

回答 1

Stack Overflow用户

发布于 2015-03-09 23:43:08

这完全取决于你想要什么。我的建议是将重新打印逻辑放在一个真正的ReprintCommandHandler中(可能是通过注入一个执行打印的服务,就像您使用装饰器一样)。这对我来说似乎是合理的,因为在重印的情况下,重印是实际的业务逻辑,而不是横切的关注点。

在这种情况下,您必须将PrintDecorator排除在您的ReprintCommandHandler周围,这可以按如下方式完成:

代码语言:javascript
复制
container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(PrintDecorator<>),
    c => c.ServiceType != typeof(ICommandHandler<Reprint>));

另一方面,如果您希望将打印逻辑保留在PrintDecorator中,而不必在业务层中复制此逻辑,则可以实现一个完全空的ReprintCommandHandler,也可以注册一个特殊的Null Object命令处理程序。

使用空处理程序当然很简单,并且会使您的配置变得非常简单:

代码语言:javascript
复制
// NOTE: Use RegisterManyForOpenGeneric for Simple Injector v2.x
container.Register(typeof(ICommandHandler<>),
   new[] { typeof(ICommandHandler<>).Assembly });

container.RegisterDecorator(
    typeof(ICommandHandler<>),
    typeof(PrintDecorator<>));

当然,缺点是你需要一个空类。因此,另一种方法是实现空对象模式,如下所示:

代码语言:javascript
复制
public class NullCommandHandler<T> : ICommandHandler<T> {
    public void Handle(T command) { }
}

如果您有多个空实现,则可以重用此实现,您可以按如下方式进行注册:

代码语言:javascript
复制
// 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<>));
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28945877

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档