截取方法调用以获取附加功能的最简单方法是什么?

Mat*_*caj 6 structuremap aop castle-dynamicproxy mixins interceptor

假设我有一个存储库,它返回一个Posts 列表.存储库接口有一个GetAll()方法可以完成它的建议.

现在按照我不应该将域逻辑放在存储库中的理论,我想拦截对具体GetAll()方法的调用,以便我可以在GetAll()结果中添加以下逻辑:

return GetAll().OrderByDescending(p => p.Posted).ToList();
Run Code Online (Sandbox Code Playgroud)

我想拦截这个的原因是因为(1)我不想让客户端记得调用扩展方法(OrderByDescending或者一些无用的包装器),我想每次调用它,(2)我不我想让我所有的具体实现都记住订购GetAll()结果 - 我想把这个逻辑放在任何存储库外部的一个地方.

最简单的方法是什么?

我已经在使用StructureMap,所以如果我可以拦截它,它可能是一个低成本选项.但我不认为SM拦截方法调用,只是创建对象实例?

我需要转到代理还是混合模式?我是否需要使用Castle Dynamic Proxy全押?或者是否有其他方法我应该考虑或者可能是一种组合?

我真的对上面我特定例子的具体建议感兴趣.我是AOP的新手所以请保持温柔.

Mat*_*caj 12

使用DynamicProxy选项.它比我想象的更容易使用.

所有这一切都是using Castle.DynamicProxy;参考......

有点IInterceptor......

public class PostRepoInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        invocation.Proceed();

        if (invocation.Method.Name.Equals("GetAll", StringComparison.InvariantCultureIgnoreCase))
            invocation.ReturnValue = this.GetModifiedGetAllResult(invocation.ReturnValue);
    }

    private object GetModifiedGetAllResult(object getAllResult)
    {
        return Post.GetOrderedPosts((IList<Post>)getAllResult);
    }
}
Run Code Online (Sandbox Code Playgroud)

StructureMap配置中的两个新行:

    public RepoRegistry()
    {
        var pg = new ProxyGenerator();

        For<IPostRepository>()
            .EnrichAllWith(z => pg.CreateInterfaceProxyWithTarget<IPostRepository>(z, new PostRepoInterceptor()));
    }
Run Code Online (Sandbox Code Playgroud)

..它已经完成了.GetAll()现在表现得我想要的.我仍然可以按照我熟悉的方式使用接口,并且我将它全部保持干燥并且为DDD解耦.

感谢SamAndre.