介绍 Generic/Dynamic 与 PostSharp 的接口

Introduce Generic/Dynamic Interface with PostSharp

我最近在 PostSharp 的支持论坛上找到 this question。好像这里没有人问过这个问题,所以我现在就问。

原题询问泛型接口。我有兴趣这样做,但我也有兴趣简单地在对象上动态实现接口,同时指向代理实现。

这是我试图完成的,但如您所见,我在下面标记的行中遇到错误,因为 IntroduceInterfaceAttribute 不是 IAspect

public class ApplyInterfaces : TypeLevelAspect, IAspectProvider
{
    readonly Type[] interfaceTypes;
    public ApplyInterfaces( params Type[] interfaceTypes )
    {
        this.interfaceTypes = interfaceTypes;
    }

    public IEnumerable<AspectInstance> ProvideAspects( object targetElement )
    {
        var type = (Type)targetElement;
        var targetTypes = InterfaceTypeProvider.GetInterfacesFor( type ); // pseudo-code.  Get interfaces to implement "somewhere".

        foreach ( var interfaceType in interfaceTypes.Concat( targetTypes ) )
        {
            yield return new AspectInstance( type, new IntroduceInterfaceAttribute( interfaceType ) ); // doesn't work.
        }
    }
}

这可以用 PostSharp 实现吗?

这是我目前解决这个问题的方法,但如果有更好的方法,我绝对乐于接受反馈。另外,我想验证这确实也在使用 the adapter pattern

[IntroduceInterface( typeof(IGenericInterface) )]
public class DynamicInterfaceAspect : InstanceLevelAspect, IGenericInterface
{
    readonly Type parameterType;

    public DynamicInterfaceAspect( Type parameterType )
    {
        this.parameterType = parameterType;
    }

    public override void RuntimeInitializeInstance()
    {
        var type = typeof(GenericInterfaceAdapter<>).MakeGenericType( parameterType );
        Inner = (IGenericInterface)Activator.CreateInstance( type, Instance );
    }

    IGenericInterface Inner { get; set; }
    public void HelloWorld( object parameter ) => Inner.HelloWorld( parameter );
}

public interface IGenericInterface
{
    void HelloWorld( object parameter );
}

public class GenericInterfaceAdapter<T> : IGenericInterface
{
    readonly IGenericInterface<T> inner;

    public GenericInterfaceAdapter( IGenericInterface<T> inner )
    {
        this.inner = inner;
    }

    public void HelloWorld( object parameter ) => inner.HelloWorld( (T)parameter );
}

public interface IGenericInterface<in T>
{
    void HelloWorld( T parameter );
}