0

如果我有以下代码

[Serializable]
public abstract class ValidatedCommandArgs
{
}

public interface IValidatedCommand<T>
    where T : ValidatedCommandArgs
{
    IEnumerable<ValidationError> Execute(T args);
}

现在一个简单的实现

public class CreateClientArgs : ValidatedCommandArgs
{
    public string Code { get; set; }
    public string Name { get; set; }
}

public class CreateClientCommand : IValidatedCommand<CreateClientArgs>
{
    public IEnumerable<ValidationError> Execute(CreateClientArgs args)
    {
        throw new NotImplementedException();
    }
}

然后注册命令处理程序

container.RegisterType<IValidatedCommand<CreateClientArgs>>, CreateClientCommand>();

现在我想要做的是包装 IValidatedCommand 的每个分辨率,以便我基本上可以做到这一点

public class LoggedCommandHandler<T> : IValidatedCommand<T>
    where T : ValidatedCommandArgs
{
    readonly IValidatedCommand<T> Inner;

    public LoggedCommandHandler(IValidatedCommand<T> inner)
    {
        this.Inner = inner;
    }

    IEnumerable<ValidationError> IValidatedCommand<T>.Execute(T args)
    {
        //Serialize ARGS
        //Save Inner.GetType().ClassName + the serialized args to the DB
        return Inner.Execute(args);
    }
}

然后每当我解决(例如)IValidatedCommand<CreateClientArgs>我实际上会得到一个实例LoggedCommandHandler<CreateClientArgs>inner = CreateClientCommand

抱歉这么冗长,但我不记得该技术叫什么。

4

3 回答 3

2

您正在寻找的是所谓的装饰者模式

Unity有一个扩展可以帮助您使用它。


更新

这个解决方案比 Jim Christopher 的解决方案更明确。

于 2012-12-12T18:47:30.133 回答
0

我建议您查看 Unity 的策略注入/拦截方面。这允许您以非常轻量级和解耦的方式进行装饰。这将是最简单的方法。

本质上,您将拥有一个调用处理程序,该处理程序在调用 Execute 方法时执行,该方法将日志记录到数据库,然后调用“真实”类。

看一下 ICallHandler 接口、HandlerAttribute 和 Interception 扩展。

于 2012-12-12T20:58:59.403 回答
0

这是我采用的解决方案。它需要一些调试,但似乎可以很好地满足我当前的需求。

http://mrpmorris.blogspot.co.uk/2012/12/decorating-unity-extension.html

于 2012-12-21T23:24:30.223 回答