4

私は、独自のカスタム属性で装飾できるプロパティ ゲッターとメソッドを持ち、その属性の存在に基づいて、メソッド本体を別の実装に置き換えたいと考えています。また、その別の実装では、メソッドを装飾するカスタム属性に指定されたコンストラクター引数を知る必要があります。

これは明らかに、PostSharp や LinFu などの AOP で実行できますが、ビルド後の処理ステップを必要としない方法があるかどうか疑問に思っています。

4

4 に答える 4

6

実行時に任意のメソッドを動的に変更できるフレームワークがいくつかあります。

  • Harmony Free and Open Source (MIT)!
  • Prig : Free and Open Source (MIT)、Visual Studio 拡張機能とランチャーで実行中のプログラムが必要で、2017 年以降更新されていません。
  • Microsoft Fakes : 商用、Visual Studio Enterprise (古いバージョンの場合は Premium および Ultimate) に含まれていますが、Community および Professional には含まれていません
  • Telerik JustMock : コマーシャル、「ライト」バージョンが利用可能
  • Typemock アイソレーター: 業務用
于 2016-12-07T14:20:08.590 に答える
2

従来の .Net API を使用しても、これを実現する方法はありません。メソッド本体はコンパイル時に固定され、変更できません。

ただし、プロファイラーと ENC API を使用すると、メソッド本体を変更することが技術的に可能であるため、伝統的と言います。ただし、これらの API は制約のある状況で動作するため、汎用 API とは見なされません。

于 2010-06-17T15:04:22.810 に答える
1

実行時に動作する任意の優れた AOP フレームワークで可能です。私は現在、この能力を持つそれらの1つに取り組んでいます。

ここで見つけることができます: NConcern .NET runtime Aspect-Oriented Programming

それがどのように機能するかを示す小さな例...

想定されるカスタム属性:

[AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=true)]
public class MyAttribute1 : Attribute
{
    public string MyAttributeValue;
}

マークされたクラスの例:

public class Calculator
{
    [MyAttribute1(MyAttributeValue="Hello World")]
    public int Add(int a, int b)
    {
        return a + b;
    }
}



public class MyAspect : IAspect
{
    //This code will be executed to create a decorator, not in nominal execution flow (You don't have to stress with performance here)
    public IEnumerable<IAdvice> Advise(MethodInfo method)
    {
        var myattribute1 = method.GetCustomAttributes(typeof(MyAttribute1), true).Cast<MyAttribute1>().SingleOrDefault();

        //If attribute is not defined, do not return an "advice"
        if (myattribute1 == null) { yield break; }

        //Get your attribute property.
        var myattributevalue = myattribute1.MyAttributeValue;

        //define your substitute method
        var signature= new Type[] { method.DeclaringType }.Concat(method.GetParameters().Select(parameter => parameter.Type)).ToArray();
        var dynamicMethod = new DynamicMethod(string.Empty, method.ReturnType, signature, method.DeclaringType, true);
        var body = dynamicMethod.GetILGenerator();

        //TODO : emit your code! maybe use your attribute field value to know what kind of replacement you want to do...
        body.Emit(OpCodes.Ret);

        //define the replacement
        yield return new Advice(dynamicMethod);
    }
}

使用事例 :

static public void main(string[] args)
{
    Aspect.Weave<MyAspect>(method => method.IsDefined(typeof(MyAttribute1), true));
}
于 2016-12-09T16:23:35.320 に答える