C# 如何在PostSharp中从另一个方面调用注入方法

C# 如何在PostSharp中从另一个方面调用注入方法,c#,postsharp,C#,Postsharp,我正在尝试使用PostSharp在学校应用程序上实现Observer模式。 情况如下: 我有一个存储库,我想在每次更改时通知每个TesterForm(允许在存储库中操纵数据的表单) 这是我想用来将可观察部分添加到我的存储库中的方面: [Serializable] class ObservableAspect : InstanceLevelAspect { [IntroduceMember] List<TesterForm> LT; [IntroduceMem

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

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

这是我想用来将可观察部分添加到我的存储库中的方面:

[Serializable]
class ObservableAspect : InstanceLevelAspect
{
    [IntroduceMember]
    List<TesterForm> LT;

    [IntroduceMember]
    public void notifyChange()
    {
         foreach (TesterForm x in LT)
         {
             x.refreshListBoxBuguri();
         }
    }

    [IntroduceMember]
    public void Subscribe(TesterForm t)
    {
        LT.Add(t);
    }
}
然后,这一特性应用于我的TesterForm构造函数,以便它在创建后立即订阅我的存储库:

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

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

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

提前感谢您的帮助

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


干杯

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

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

[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<MethodBase> 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.
}
[可序列化]
类ObservableSpect:InstanceLevel方面
{
私有void notifyChange()
{
// ...
}
//这是OnExit的建议,以前是在一个单独的方面。
[OnMethodExitAdvice]
[方法切入点(“选择方法”)]
MethodExhit(MethodExecutionArgs-args)上的公共无效
{
notifyChange();
}
//查找所有必须拦截的方法。
公共IEnumerable SelectMethods(类型targetType)
{
foreach(targetType.GetMethods()中的var methodInfo)
{
if(methodInfo.GetCustomAttributes(typeof(ObservableNotify)).Any())
收益率-收益率方法信息;
}
}
}
类ObservalEnotify:属性
{
//这只是ObservableSpect使用的标记属性。
}
[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<MethodBase> 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.
}