当前位置: 首页 > 知识库问答 >
问题:

使用PostSharp在c中的构造函数上应用aspect

江仲渊
2023-03-14

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

}

我的aspect类为

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)TraceAscape Provider类:

使用系统;使用系统。集合。通用;使用系统。Linq;使用系统。文本;使用PostSharp。方面;使用系统。反思;

命名空间MyProviders{公共类TraceAspectProvider:IAspectProvider{只读SomeTracingAspectToApply=新建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)

等待您的解决方案和响应

共有1个答案

訾俊名
2023-03-14

我认为您的主要问题是您正在尝试将方面应用于第三方库(mscorlib)。你可以看看达斯汀关于如何做到这一点的博客文章,这可能会对你有所帮助。请正式考虑这一点,PostSharp不支持这一点。

为了将方面应用于构造函数,您可能可以使用类型级方面和多播切入点,并将其目标设置为,例如InstanceConstructor。

当您不能使用类型级别方面(例如,您想将方面应用于事件)时,我以前使用了方法建议(methodentryadvice)和方法切入点(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上找到。自从这篇博文发布以来,我已经做了一些更改,但以构造函数为目标的原则保持不变。

 类似资料:
  • 本文向大家介绍C++中拷贝构造函数的应用详解,包括了C++中拷贝构造函数的应用详解的使用技巧和注意事项,需要的朋友参考一下 一、C++中拷贝构造函数的定义: 有一个参数的类型是其类类型的构造函数是为拷贝构造函数。 如下所示: 二、拷贝构造函数的应用: 当一个类对象以另一个同类实体作为初值时,大部分情况下会调用拷贝构造函数。 一般是这三种具体情况: 1.显式地以一个类对象作为另一个类对象的初值,形如

  • 问题内容: 如果我有一个像这样的构造函数: 然后,我如何在与构造函数相同的类中的方法中使用变量c和d,因为尝试仅在方法中使用变量名似乎不起作用? 问题答案: 实际上,您的代码将无法编译- 无效。 我认为您的意思是:- 。 然后我如何在与构造函数相同的类中的方法中使用变量c和d 您不能这样做,因为您已将它们声明为局部变量,其范围在构造函数结束执行时终止。 您应该将它们声明为实例变量。

  • 所以我正在我的Java项目(Google Guice)中实现一个依赖注入框架,一切都很好,我喜欢它,但是有一个小问题;我想为我的主项目的类创建一个静态实例(实例化依赖项等)。但是我不知道使用Guice实例化它的任何方法,我不能手动实例化它,因为我在它的构造函数中使用DI(我在构造函数中有对象),这意味着我不能访问实例化该类所需的类的非静态变量。我试着使用一个提供者,但是我真的不明白在哪里绑定它,因

  • 主要内容:1、实例构造函数,2、静态构造函数,3、私有构造函数在 C# 中,构造函数就是与类(或结构体)具有相同名称的成员函数,它在类中的地位比较特殊,不需要我们主动调用,当创建一个类的对象时会自动调用类中的构造函数。在程序开发的过程中,我们通常使用类中的构造函数来初始化类中的成员属性。 C# 中的构造函数有三种: 实例构造函数; 静态构造函数; 私有构造函数。 1、实例构造函数 构造函数是类中特殊的成员函数,它的名称与它所在类的名称相同,并且没有返回值。当

  • 主要内容:构造函数的重载,默认构造函数在 C++中,有一种特殊的成员函数,它的名字和类名相同,没有返回值,不需要用户显式调用(用户也不能调用),而是在创建对象时自动执行。这种特殊的成员函数就是 构造函数(Constructor)。 在《 C++类成员的访问权限以及类的封装》一节中,我们通过成员函数 setname()、setage()、setscore() 分别为成员变量 name、age、score 赋值,这样做虽然有效,但显得有点

  • 问题内容: 我读过一些文章和书籍,几乎总是避免使用它。我知道为什么会这样,但是使用String(String)构造函数有什么用吗?我不认为有,也没有其他证据,但是我想知道SO社区中的任何人是否知道使用。 问题答案: 这是一篇很好的文章:认为无用的String构造函数毕竟是有用的! 事实证明,在至少一种情况下,此构造函数实际上可以有用。如果您曾经看过String源代码,就会发现它不仅包含用于char