使用PostSharp介绍通用/动态接口

时间:2016-09-18 15:30:53

标签: c# aop 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有可能吗?

1 个答案:

答案 0 :(得分:0)

以下是我目前正在解决此问题的方法,但如果有更好的方法,我绝对愿意接受反馈。另外,我想验证这确实也在使用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 );
}