使用PostSharp在c#中使用构造函数的方面

我正在研究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 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;

namespace MyProviders {public class TraceAspectProvider:IAspectProvider {readonly SomeTracingAspect aspectToApply = new SomeTracingAspect();

  public IEnumerable ProvideAspects(object targetElement) { Assembly assembly = (Assembly)targetElement; List instances = new List(); foreach (Type type in assembly.GetTypes()) { ProcessType(type, instances); } return instances; } private void ProcessType(Type type, List 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) 

等待您的解决方案和响应

我认为你的主要问题是你正试图在第三方库(mscorlib)上应用方面。 你可以看看Dustin的博客文章,了解如何做到这一点 ,这可能对你有帮助。 请正确考虑PostSharp不支持。

为了将方面应用于构造函数,您可以使用TypeLevelAspectMulticastPointcut , 并将其Targets设置为InstanceConstructor

当你不能使用TypeLevelAspect (例如你想将方面应用于事件)我之前使用过OnMethodEntryAdviceMethodPointCut 。 这允许您手动搜索构造函数。

 [OnMethodEntryAdvice, MethodPointcut( "SelectConstructors" )] public void OnConstructorEntry( MethodExecutionArgs args ) { ... } IEnumerable SelectConstructors( EventInfo target ) { return target.DeclaringType.GetConstructors( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ); } 

我可以在我的博客上找到更广泛的讨论,我如何应用它来初始化构造函数中的事件。

可以在github上找到该类的最新完整源代码。 自博客文章发表以来,我做了一些更改,但定位构造函数的原则保持不变。

Interesting Posts