1

我想使用 AOP 来拦截对 ASP.NET 控制器和 ApiControllers 中所有方法的调用。

http://structuremap.github.io/dynamic-interception/之后,我试图让它按如下方式工作。

拦截器目前并没有做太多的事情,只是提供了一种查看方法名称及其属性的方法:

public class AuthorisationInterceptor : ISyncInterceptionBehavior
{
    public IMethodInvocationResult Intercept(ISyncMethodInvocation methodInvocation)
    {
        var classType = methodInvocation.MethodInfo.DeclaringType;
        var classAttributes = classType.Attributes;

        string methodName  = methodInvocation.MethodInfo.Name;
        var methodAttributes = methodInvocation.MethodInfo.Attributes;

        //var argument = methodInvocation.GetArgument("value");

        return methodInvocation.InvokeNext();
    }
}

问题是如何附加它——不会出错。

我尝试了几种不同的方法,都引发了相同类型的错误..

"Decorator Interceptor failed during object construction. Specified type is not an interface,Parameter name: interfaceToProxy"

问题是 ASP.MVC 直接要求控制器(例如:“AboutController”,而不是“IAboutController”)。

public class AppCoreControllerConvention : ICustomRegistrationConvention
{
    public void ScanTypes(TypeSet types, Registry registry)
    {
        // Attach a policy to intercept all Controllers before attaching Controllers...but it raises error.
        // "Decorator Interceptor failed during object construction. Specified type is not an interface,Parameter name: interfaceToProxy"
        registry.Policies.Interceptors(
            new DynamicProxyInterceptorPolicy(
                x => (x.IsConcrete() | !x.IsOpenGeneric()) & (x.CanBeCastTo<Controller>() | x.CanBeCastTo<ApiController>()),
                new IInterceptionBehavior[]
                {
                    new AuthorisationInterceptor(),
                    new AuditingInterceptor()
                }
            ));


        // Now find all Controllers/ApiControllers:
        var foundControllers = types.FindTypes(
                            TypeClassification.Concretes | TypeClassification.Closed)
                        .Where(x => x.CanBeCastTo<Controller>() | x.CanBeCastTo<ApiController>())
                        .ToArray();

        // to register them with StructureMap as themselves (ie, no 'Use' statement):
        foreach (var serviceType in foundControllers)
        {
            registry.For(serviceType).LifecycleIs(new UniquePerRequestLifecycle());

            // Although when I tried use/fore, it also raised {"Specified type is not an interface\r\nParameter name: interfaceToProxy"}
            // AttachBehaviour(registry, serviceType);
        }

    }


    //private static void AttachBehaviour(Registry registry, Type serviceType)
    //{
    //    var dynamicProxyInterceptorType = typeof(StructureMap.DynamicInterception.DynamicProxyInterceptor<>);
    //    var genericDynamicProxyInterceptorType = dynamicProxyInterceptorType.MakeGenericType(new[] { serviceType });

    //    var interceptorBehaviors = new StructureMap.DynamicInterception.IInterceptionBehavior[]
    //    {
    //        new AuthorisationInterceptor(),
    //        new AuditingInterceptor()
    //    };
    //    var args = new[] { interceptorBehaviors };

    //    // Create
    //    IInterceptor interceptor =
    //        (StructureMap.Building.Interception.IInterceptor)Activator.CreateInstance(
    //            genericDynamicProxyInterceptorType,
    //            (BindingFlags)0,
    //            null,
    //            args,
    //            null);

    //    // Attach interceptors to Service:
    //    registry.For(serviceType).Use(serviceType).InterceptWith(interceptor);
    //}
}

我在用着:

<package id="StructureMap" version="4.5.1" targetFramework="net461" />
<package id="StructureMap.DynamicInterception" version="1.1.1" targetFramework="net461" />
<package id="StructureMap.MVC5" version="3.1.1.134" targetFramework="net461" />
<package id="structuremap.web" version="4.0.0.315" targetFramework="net461" />
<package id="StructureMap.WebApi2" version="3.0.4.125" targetFramework="net461" />

感谢您对如何进行的任何建议。

PS:我不确定我是否完全理解https://stackoverflow.com/a/47582778/9314395的建议,但以下内容并没有神奇地产生任何拦截:

registry.For<IController>().InterceptWith(new DynamicProxyInterceptor<IController>(new IInterceptionBehavior[]{new AuthorisationInterceptor()}));
4

0 回答 0