4

PostSharp でさまざまな概念に取り組んでいます。

更新しました:

これは私のプログラムクラスです

namespace myconstructor
{
    class Program
    {
        static void Main(string[] args)
        {
            createfolder();
            streamfolder();
        }
        public static void createfolder()
        {
            File.Create("E:/samplefile.txt");

        }
        public static void streamfolder()
        {
            StreamWriter sw = new StreamWriter("E:/samplestream.txt");
        }
    }

}

そして私のアスペクトクラスとして

1) いくつかのトレース アスペクト クラス:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PostSharp.Extensibility;
using PostSharp.Aspects.Dependencies;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using System.Reflection;
using System.Linq.Expressions;

namespace MyProviders
{
    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Event)]
    [MulticastAttributeUsage(MulticastTargets.Event, AllowMultiple = false)]
    [AspectTypeDependency(AspectDependencyAction.Commute,typeof(SomeTracingAspect))]
    [Serializable]
    public class SomeTracingAspect : EventLevelAspect
    {
        [OnMethodEntryAdvice, MethodPointcut("SelectConstructors")]
        public void OnConstructorEntry(MethodExecutionArgs args)
        {
            args.ReturnValue = "aspectfile"; 
        }

        IEnumerable<ConstructorInfo> SelectConstructors(EventInfo target)
        {
            return target.DeclaringType.GetConstructors(
                        BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
        }

        public override void RuntimeInitialize(EventInfo eventInfo)
        {
            base.RuntimeInitialize(eventInfo);

        }
    }

}

2)TraceAspectProvider クラス:

システムを使用する; System.Collections.Generic の使用; System.Linq を使用します。System.Text を使用します。PostSharp.Aspects の使用; System.Reflection を使用します。

名前空間 MyProviders { public class TraceAspectProvider : IAspectProvider { readonly SomeTracingAspectspectToApply = new SomeTracingAspect();

    public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
    {
        Assembly assembly = (Assembly)targetElement;

        List<AspectInstance> instances = new List<AspectInstance>();
        foreach (Type type in assembly.GetTypes())
        {
            ProcessType(type, instances);
        }

        return instances;
    }

    private void ProcessType(Type type, List<AspectInstance> instances)
    {
        foreach (ConstructorInfo target in type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly))
        {
            instances.Add(new AspectInstance(target, aspectToApply));
        }

        foreach (Type nestedType in type.GetNestedTypes())
        {
            ProcessType(nestedType, instances);
        }

} } }

として与えられた私のアスペクトファイル

 "C:\Program Files\PostSharp 2.1\Release\postsharp.4.0-x86-cil.exe" "D:\fileaspecttest\myconstructor.exe" /p:AspectProviders=MyProviders.AspectProvider,MyProviders /p:Output="D:\fileaspecttest\myaspect.exe"

私はエラーが発生しています

 error PS0125: An unexpected exception occured when executing user code: System.ArgumentNullException: Value cannot be null.
 error PS0125: Parameter name: type
 error PS0125:    at System.Activator.CreateInstance(Type type, Boolean nonPublic)
 error PS0125:    at ^7HtKTJrYMoHj.^kfEQVEmN.^jK8C2yxJ()
 error PS0125:    at PostSharp.Sdk.Utilities.ExceptionHelper.ExecuteUserCode[T](MessageLocation messageLocation, Func`1 userCode, Type[] acceptableExceptions)

解決策と回答を待っています

4

1 に答える 1

3

あなたの主な問題は、サードパーティのライブラリ (mscorlib) にアスペクトを適用しようとしていることだと思います。これを行う方法については、Dustin のブログ投稿を参照してください。これは PostSharp でサポートされていないことを公式に考慮してください。

コンストラクターにアスペクトを適用するには、おそらく aTypeLevelAspectと aMulticastPointcutegTargetsInstanceConstructor設定して使用できます。

を使用できない場合TypeLevelAspect(たとえば、アスペクトをイベントに適用したい場合)、以前はOnMethodEntryAdviceと を使用していましたMethodPointCut。これにより、コンストラクターを手動で検索できます。

[OnMethodEntryAdvice, MethodPointcut( "SelectConstructors" )]
public void OnConstructorEntry( MethodExecutionArgs args )
{
    ...
}

IEnumerable<ConstructorInfo> SelectConstructors( EventInfo target )
{
    return target.DeclaringType.GetConstructors(
        BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
}

コンストラクターからイベントを初期化するためにこれをどのように適用したかについてのより広範な議論は、私のブログで見つけることができます

このクラスの最新の完全なソース コードはgithub にあります。ブログ投稿以降、いくつかの変更を加えましたが、コンストラクターを対象とする原則は変わりません。

于 2012-11-14T18:14:27.520 に答える