使用PostSharp在C#中的构造函数上应用方面 [英] Applying aspect on constructor in c# using PostSharp
问题描述
我正在研究PostSharp中的各种概念.
I am working on various concepts in 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;
using System; using System.Collections.Generic; using System.Linq; using System.Text; using PostSharp.Aspects; using System.Reflection;
命名空间MyProviders { 公共类TraceAspectProvider:IAspectProvider { readonly SomeTracingAspect AspectToApply = new SomeTracingAspect();
namespace MyProviders { public class TraceAspectProvider : IAspectProvider { readonly SomeTracingAspect aspectToApply = 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)
等待您的解决方案和响应
Waiting for your solution and responses
推荐答案
我认为您的主要问题是您正在尝试在第3方库(mscorlib)上应用方面.您可以查看达斯汀(Dustin)关于如何执行此操作的博客文章,这可能会对您有所帮助.请正式考虑到PostSharp不支持的功能.
I think your main problem is you are trying to apply aspects on 3th party libraries (mscorlib). You can take a look at Dustin's blog post on how to do this which might help you out. Do take into account officially this isn't supported by PostSharp.
为了将方面应用于构造函数,您可能可以使用 MulticastPointcut
与
In order to apply aspects to a constructor you can probably use a TypeLevelAspect
and a MulticastPointcut
with its Targets
set to e.g. InstanceConstructor
.
当您不能使用TypeLevelAspect
时(例如,您要将方面应用于事件),我以前使用过 MethodPointCut
.这使您可以手动搜索构造函数.
When you can't use a TypeLevelAspect
(e.g. you want to apply the aspect to events) I previously used a OnMethodEntryAdvice
and a MethodPointCut
. This allows you to search for the constructors manually.
[OnMethodEntryAdvice, MethodPointcut( "SelectConstructors" )]
public void OnConstructorEntry( MethodExecutionArgs args )
{
...
}
IEnumerable<ConstructorInfo> SelectConstructors( EventInfo target )
{
return target.DeclaringType.GetConstructors(
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
}
A more extended discussion how I applied this to initialize events from the constructor can be found on my blog.
The latest complete source code of this class can be found on github. I've made several changes since the blog post, but the principle of targeting constructors remains the same.
这篇关于使用PostSharp在C#中的构造函数上应用方面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!