Структура карты перехвата контроллеров
Я хотел бы использовать 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: я не уверен, что я точно понял, что рекомендует /questions/20519808/aspektno-orientirovannoe-programmirovanie-s-structuremapdynamicinterception/20519823#20519823, но следующее магическим образом не произвело никакого перехвата:
registry.For<IController>().InterceptWith(new DynamicProxyInterceptor<IController>(new IInterceptionBehavior[]{new AuthorisationInterceptor()}));