使用具有Castle Proxy Interceptor的Simple Injector

时间:2014-07-01 15:02:19

标签: c# simple-injector castle-dynamicproxy

我在asp.net mvc 4项目中使用Simple Injector。

我无法弄清楚如何使用带有城堡代理拦截器的Simple Injector。

1 个答案:

答案 0 :(得分:15)

事实上,简单注入者section about Interception中有一个documentation,它非常清楚地描述了如何进行拦截。这里给出的代码示例没有显示如何使用Castle DynamicProxy,但实际上您需要更改几行代码才能使其正常工作。

如果您使用Interception Extensions code snippet,要使其正常运行,您只需删除IInterceptorIInvocation接口,在文件顶部添加using Castle.DynamicProxy ,并使用以下内容替换通用Interceptor

public static class Interceptor
{
    private static readonly ProxyGenerator generator = new ProxyGenerator();

    public static object CreateProxy(Type type, IInterceptor interceptor,
        object target)
    {
        return generator.CreateInterfaceProxyWithTarget(type, target, interceptor);
    }
}

但至少,这将是您使用Castle DynamicProxy进行拦截所需的代码:

using System;
using System.Linq.Expressions;
using Castle.DynamicProxy;
using SimpleInjector;

public static class InterceptorExtensions
{
    private static readonly ProxyGenerator generator = new ProxyGenerator();

    private static readonly Func<Type, object, IInterceptor, object> createProxy =
        (p, t, i) => generator.CreateInterfaceProxyWithTarget(p, t, i);

    public static void InterceptWith<TInterceptor>(this Container c, 
        Predicate<Type> predicate)
        where TInterceptor : class, IInterceptor
    {
        c.ExpressionBuilt += (s, e) =>
        {
            if (predicate(e.RegisteredServiceType))
            {
                var interceptorExpression = 
                    c.GetRegistration(typeof(TInterceptor), true).BuildExpression();

                e.Expression = Expression.Convert(
                    Expression.Invoke(Expression.Constant(createProxy),
                        Expression.Constant(e.RegisteredServiceType, typeof(Type)),
                        e.Expression,
                        interceptorExpression),
                    e.RegisteredServiceType);
            }
        };
    }
}

这是如何使用它:

container.InterceptWith<MonitoringInterceptor>(
    type => type.IsInterface && type.Name.EndsWith("Repository"));

这允许拦截名称以&#39; Repository&#39;结尾的所有界面注册。被短暂的MonitoringInterceptor拦截。