Applying aspect on constructor in c# using PostSharp
我正在研究Postshap中的各种概念。
更新:
这是我的课程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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)一些跟踪方面类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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.方面;使用系统。反射;
命名空间MyProviders{公共类traceAspectProvider:iaSpectProvider{readOnly someTracingAspectToApply=new someTracingAspect();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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); } |
}}}
我的方面文件
1 2 | "C:\Program Files\PostSharp 2.1 elease\postsharp.4.0-x86-cil.exe""D:\fileaspecttest\myconstructor.exe" /p:AspectProviders=MyProviders.AspectProvider,MyProviders /p:Output="D:\fileaspecttest\myaspect.exe" |
我的错误是
1 2 3 4 5 | 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)上应用方面。你可以看看达斯汀的博客文章,了解如何做到这一点,这可能会对你有所帮助。正式考虑到Postshap不支持这一点。
为了将方面应用到构造函数,您可以使用
当你不能使用
1 2 3 4 5 6 7 8 9 10 11 | [OnMethodEntryAdvice, MethodPointcut("SelectConstructors" )] public void OnConstructorEntry( MethodExecutionArgs args ) { ... } IEnumerable<ConstructorInfo> SelectConstructors( EventInfo target ) { return target.DeclaringType.GetConstructors( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ); } |
在我的博客上可以找到一个更广泛的讨论,我如何应用它来初始化构造函数中的事件。
在GitHub上可以找到此类的最新完整源代码。自博客发布以来,我做了一些修改,但是以构造器为目标的原则仍然是相同的。