2015-11-26 3 views
0

Я создал простой аспект:применить аспект к другим методам сборки класса вызывает

[Serializable()] 
public class NullableCallAspect : PostSharp.Aspects.OnMethodBoundaryAspect 
{ 
    public override void OnEntry(PostSharp.Aspects.MethodExecutionArgs args) 
    { 
     if (args.Instance == null) 
      args.FlowBehavior = PostSharp.Aspects.FlowBehavior.Return; 
    } 
} 

По сути, я хочу, чтобы в зависимости от того instance.method вызова, который instance == null это не входит в методе. Я выясняю, мне нужно изменить наследование аспекта. Итак, мне нужно будет изменить OnMethodBoundaryAspect на другой. Это был бы первый вопрос.

Другой вопрос заключается в том, как применить этот аспект к вызовам методов из классов, наследующих интерфейс другой сборки.

Я попытался это, но это не совсем работа:

[assembly: UI.Aspects.NullableCallAspect(
    AttributeTargetAssemblies = "UIAppearanceExtensibility", 
    AttributeTargetTypes = "UI.Appearance.Extensibility.*.I*AppearanceManager", 
    AttributeTargetMembers = "handle*" 
)] 

ответ

1

Такого рода аспекты будут требовать вызова сайта перехвата, который не поддерживается PostSharp. И OnMethodBoundaryAspect, и MethodInterceptionAspect модифицируют целевой метод, а не сам сайт вызова - экземпляр по-прежнему требуется при вызове метода, украшенного этими аспектами.

EDIT: Существует хак, как заставить PostSharp перехватывать сайты вызовов. Это когда многоадресный аспект имеет тип в разных сборках. Если все методы реализованы в проекте ClassLibrary1 и называются они просто из MyApplication проекта, то аспект может быть многоадресной в MyApplication проекта, как это:

[assembly: 
    NullableCallAspect(AttributeTargetAssemblies = "ClassLibrary1", AttributeTargetTypes = "ClassLibrary1.*", 
     AttributeTargetMembers = "handle*", AttributeTargetElements = MulticastTargets.Method)] 

Если есть соглашение, что все реализации IAppearanceManager конец имеет имя с суффиксом AppearanceManager то многоадресного должен быть изменен:

[assembly: 
    NullableCallAspect(AttributeTargetAssemblies = "ClassLibrary1", AttributeTargetTypes = "ClassLibrary1.*AppearanceManager", 
     AttributeTargetMembers = "handle*", AttributeTargetElements = MulticastTargets.Method)] 

Если такого соглашения нет, то для многоадресной рассылки может использоваться IAspectProvider.

Это не применимо, если есть призывы к методам, украшенным NullableCallAspect в пределах одной сборки - сайты вызова в этом случае не перехватываются.

+0

Да, каждый интерфейс определен в ** ClassLibrary1 **, и каждый вызов его методов производится из ** MyApplication1 **. Как вы видите [здесь] (http://s16.photobucket.com/user/jeusdi/media/snip3.png.html), ** MyApplication1 ** является 'UI' и ** ClassLibrary1 ** является' UIExtensibility' , Однако это не сработает. Я не знаю, как это решить. – Jordi

+0

Недостаточно иметь все интерфейсы в ClassLibrary1, чтобы заставить работать хак. Все реализации интерфейса также должны быть определены в ClassLibrary1. –

+0

Хорошо. Я не хотел проверять вызовы 'null.method'. Я создал фиктивную реализацию для своих типов, где мой IoC не предоставляет мне никакой реализации. Фиктивная реализация обеспечивается прокси-сервером NSubstitute. Спасибо за все. – Jordi

Смежные вопросы