C# 在构建期间,PostSharp是否可以访问引入/编织的接口和成员?

C# 在构建期间,PostSharp是否可以访问引入/编织的接口和成员?,c#,.net,aop,postsharp,C#,.net,Aop,Postsharp,我正在设计一个场景,其中两个PostSharp方面相互协作。我有一个方面(FirstAspect,在下面的代码中)是为了引入一个接口,然后另一个方面(SecondAspect,在下面的代码中)应该与第一个方面引入的接口一起工作 然而,第一个方面引入的接口似乎永远无法用于第二个方面 以下是我目前正在使用的代码: public class Tests { [Fact] public void Verify() { // Not really all that

我正在设计一个场景,其中两个PostSharp方面相互协作。我有一个方面(
FirstAspect
,在下面的代码中)是为了引入一个接口,然后另一个方面(
SecondAspect
,在下面的代码中)应该与第一个方面引入的接口一起工作

然而,第一个方面引入的接口似乎永远无法用于第二个方面

以下是我目前正在使用的代码:

public class Tests
{
    [Fact]
    public void Verify()
    {
        // Not really all that significant as the current code does not compile correctly:
        var sut = new MyClass();
        Assert.True( sut is IInterface );
    }

    public interface IInterface
    {
        void HelloWorld();
    }

    [IntroduceInterface( typeof(IInterface) )]
    public class FirstAspect : InstanceLevelAspect, IInterface, IAspectProvider
    {
        public void HelloWorld() {}

        public IEnumerable<AspectInstance> ProvideAspects( object targetElement )
        {
            // Implementing IAspectProvider appears to ensure this aspect is processed first.
            // This may be a bug.
            // Please see: http://support.sharpcrafters.com/discussions/problems/3365-runtimeinitialize-does-not-follow-ordering-rules#comment_40824072
            // for more information.
            yield break;
        }
    }

    [AspectTypeDependency( AspectDependencyAction.Order, AspectDependencyPosition.After, typeof(FirstAspect) )]
    public class SecondAspect : InstanceLevelAspect, IAspectProvider
    {
        public IEnumerable<AspectInstance> ProvideAspects( object targetElement )
        {
            var type = (Type)targetElement;
            if ( !typeof(IInterface).GetTypeInfo().IsAssignableFrom( type ) )
            {
                // This is currently being thrown, as MyClass does not implement 
                // IInterface when the AppDomain is first loaded and initialized:
                throw new InvalidOperationException( $"Does not implement {typeof(IInterface)}" );
            }

            // How to access the weaved elements from FirstAspect? ...

            yield break;
        }
    }

    [FirstAspect, SecondAspect]
    class MyClass {}
}
公共类测试
{
[事实]
公共无效验证()
{
//由于当前代码未正确编译,因此并不十分重要:
var sut=新的MyClass();
Assert.True(sut是接口);
}
公共接口接口
{
void HelloWorld();
}
[介绍界面(类型(界面))]
公共类FirstAspect:InstanceLevel方面、IInterface、iSpectProvider
{
public void HelloWorld(){}
public IEnumerable,这与我正在寻找的内容很接近,但它似乎没有考虑到在调用此API时编织的元素。例如,调用
ReflectionSearch.GetMemberSoftType
不会生成预期的
IInterface.HelloWorld
on
MyClass
(在上面的示例中由
FirstAspect
引入)


在构建期间,我是否应该使用另一个API来访问PostSharp引入/编织的元素?这可能吗?

所以这个问题看起来有点老,但我还有一个类似的问题,我仍然需要答案(即:如何在不将属性应用于实现并复制它的情况下将属性引入引入的方法).也就是说,我可能不得不问我自己的问题,因为对于你所问的模式,有一些常见的步骤可以解决你的困境,但不能解决我的。看起来你已经尝试过其中的一些,但为了其他出现的问题,我将详细说明

简而言之,不要使用“反射”类型来指定方面依赖关系。PostSharp提供了一些属性,您可以使用这些属性来要求应用方面或要求特定的顺序(请参阅:以获取概述),还提供了一种方法来导入其他方面已经提供的成员(,虽然未标记,但它是该用户问题的正确答案,并且还显示了将
ImportMemberAttribute
与方面相关性一起使用的方法)。只要顺序正确,
ImportMemberAttribute
可以从其他方面导入成员;如果成员不存在且不是由方面引入的,则此属性上的
IsRequired
属性将导致生成错误

现在,如果您希望第二个方面能够应用于实现接口的所有类,无论该接口是否由第一个方面应用,您都可以使用
AspectDependencyAction.Order
设置
AspectTypeDependencyAttribute
,但不能使用
Aspec>设置
AspectTypeDependencyAttribute
tDependencyAction.Required
;如果您只希望第二个方面应用于第一个方面建议的目标,则可以应用多个依赖项属性来指定要求和顺序,而不需要方面提供程序(上面的答案还显示了一个替代实现,它将建议应用于单个方面中的多个切入点)。类似地,如果您希望第一个方面始终需要第二个方面,则可以应用另一个
AspectTypeDependencyAttribute
来指定另一个方向的要求(即,如果两者都需要另一个,则您希望在两者上都指定要求)

方面“优先级”也可用于确定应用方面的顺序,尽管只要可能,您应该使用依赖项,因为它们也作为合同文档

这都是假设您实际上不需要使用方面提供程序(因为您的评论暗示它是为了订购而做的)。您不会希望一个方面提供程序依赖于另一个方面提供程序的结果(这将违反关注点分离)但是,您也可以在方面提供程序上使用
AspectTypeDependencyAttribute
,例如,您可以有一个类型级方面提供程序,它在引入接口的类型级方面之后排序,然后在提供程序中排序ou可以循环类型上的方法,并注入依赖于第一个方面的方面(例如,提供者的接口介绍跟随者,该提供者向现在可以调用第一个方面介绍的方法的成员应用方法拦截建议)


希望这能为您(或者,考虑到问题提出后的时间,任何其他遇到此问题的人)澄清问题。其中一些信息可能已经过时或不准确(据我所知,在某些或任何情况下,现在可以在传递给方面提供器的目标类型上检测注入接口),但我相信所表达的模式仍然是PostSharp提出的首选实践。

PostSharp aspects只看到原始类型和方法,无法在构建时看到编织接口。您想在SecondAspect中对引入的接口做什么?感谢您的回复@JakubLinhart。我想确保特定的接口应用于我的类,然后一旦应用了该接口,就可以像通常一样对其应用任意数量的方面。听起来我需要找到另一种方法来实现这一点?检查
FirstAspect
自定义属性besides检查IInterface的存在情况如何?还是要应用