如何从PostSharp中的另一个方面调用注入的方法

我正在尝试使用PostSharp在学校应用程序上实现Observer模式。

情况如下:每次进行更改时,我都有一个存储库,我想通知每个TesterForm(允许在存储库中操作数据的表单)。

这是我想用来将Observable部分添加到我的存储库的方面:

[Serializable] class ObservableAspect : InstanceLevelAspect { [IntroduceMember] List LT; [IntroduceMember] public void notifyChange() { foreach (TesterForm x in LT) { x.refreshListBoxBuguri(); } } [IntroduceMember] public void Subscribe(TesterForm t) { LT.Add(t); } } 

然后,此方面应用于存储库中更改数据的每个方法:

 [Serializable] class ObservableNotify : OnMethodBoundaryAspect { public override void OnExit(MethodExecutionArgs args) { ((Repository)args.Instance).notifyChange(); } } 

然后将此方面应用于我的TesterForm构造函数,以便它在创建后立即订阅到我的存储库:

 class ObserverAspect : OnMethodBoundaryAspect { public override void OnExit(MethodExecutionArgs args) { ((TesterForm)args.Instance).controller.repository.Subscribe((TesterForm)args.Instance); } } 

现在,我面临的问题是我不知道如何调用一个方法,我从一个方面注入,从另一个方面(例如:来自TesterForm的repository.Subscribe)或者是否甚至可能。

我在PostSharp网站上做了一些研究,但没有找到关于这种实现的细节。 此外,谷歌没有产生任何有用的结果。

在此先感谢您的帮助!

附加信息:使用VS 2013,PostSharp正常工作,因为我已经构建了其他更简单的方面(日志记录和性能监视),可以按预期完成工作。

干杯!

方面可以使用[ImportMember]属性访问由另一方面引入的方法。 为了使其正常工作,导入方面也必须是实例范围方面,并且您希望为所有涉及的方面指定正确的执行顺序。

因此,您修改后的示例可能如下所示:

 [AspectTypeDependency( AspectDependencyAction.Order, AspectDependencyPosition.Before, typeof( ObservableNotify ) )] [Serializable] class ObservableAspect : InstanceLevelAspect { [IntroduceMember( Visibility = Visibility.Public )] public void notifyChange() { // ... } // other class members... } [Serializable] class ObservableNotify : OnMethodBoundaryAspect, IInstanceScopedAspect { [ImportMember("notifyChange", IsRequired = true, Order = ImportMemberOrder.AfterIntroductions)] public Action notifyChangeMethod; public override void OnExit( MethodExecutionArgs args ) { notifyChangeMethod(); } object IInstanceScopedAspect.CreateInstance( AdviceArgs adviceArgs ) { return this.MemberwiseClone(); } void IInstanceScopedAspect.RuntimeInitializeInstance() { } } 

但是,您也可以使用看起来更清晰的解决方案 – 在单个ObservableAspect使用所有编织代码,并使用简单的ObservableNotify属性标记方法。

 [Serializable] class ObservableAspect : InstanceLevelAspect { private void notifyChange() { // ... } // This is the OnExit advice that previously was in a separate aspect. [OnMethodExitAdvice] [MethodPointcut("SelectMethods")] public void OnMethodExit(MethodExecutionArgs args) { notifyChange(); } // Find all the methods that must be intercepted. public IEnumerable SelectMethods(Type targetType) { foreach (var methodInfo in targetType.GetMethods()) { if (methodInfo.GetCustomAttributes(typeof (ObservableNotify)).Any()) yield return methodInfo; } } } class ObservableNotify : Attribute { // This is just a marker attribute used by ObservableAspect. }