如何使用 PostSharp 属性注入属性?

2024-03-03

如何编写 PostSharp 方面以将属性应用于类?我正在考虑的场景是一个 WCF 实体(或域对象),需要用DataContract属性。它还应该有一个Namespace财产。像这样:

using System.Runtime.Serialization;

namespace MWS.Contracts.Search.V1
{
    namespace Domain
    {
        [DataContract(Namespace = XmlNamespaces.SchemaNamespace)]
        public class PagingContext
        {
            [DataMember]
            public int Page { get; set; }

            [DataMember]
            public int ResultsPerPage { get; set; }

            [DataMember]
            public int MaxResults { get; set; }
        }
    }
}

在上面的示例中,您可以看到我想要的输出是什么样子。它具有应用于该类的 DataContract 属性。手动执行此操作既乏味又不独特。我真的只想编写一个可以应用于我的“域”名称空间的单个方面。然后它会为我应用序列化相关的属性。这样我就可以专注于开发实体对象,而不必担心序列化细节。

我在 PostSharp 的网站上找到了在方法之前、之后以及代替方法注入代码的文档。然而,我正在寻找一种将属性注入类型的方法。


这是解决方案!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using PostSharp.Aspects;
using PostSharp.Extensibility;
using PostSharp.Reflection;

namespace MWS.Contracts.Aspects
{
    // We set up multicast inheritance so  the aspect is automatically added to children types.
    [MulticastAttributeUsage(MulticastTargets.Class, Inheritance = MulticastInheritance.Strict)]
    [Serializable]
    public sealed class AutoDataContractAttribute : TypeLevelAspect, IAspectProvider
    {
        private readonly string xmlNamespace;

        public AutoDataContractAttribute(string xmlNamespace)
        {
            this.xmlNamespace = xmlNamespace;
        }

        // This method is called at build time and should just provide other aspects.
        public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
        {
            var targetType = (Type) targetElement;

            var introduceDataContractAspect =
                new CustomAttributeIntroductionAspect(
                    new ObjectConstruction(typeof (DataContractAttribute).GetConstructor(Type.EmptyTypes)));

            introduceDataContractAspect.CustomAttribute.NamedArguments.Add("Namespace", xmlNamespace);

            var introduceDataMemberAspect =
                new CustomAttributeIntroductionAspect(
                    new ObjectConstruction(typeof (DataMemberAttribute).GetConstructor(Type.EmptyTypes)));

            // Add the DataContract attribute to the type.
            yield return new AspectInstance(targetType, introduceDataContractAspect);

            // Add a DataMember attribute to every relevant property.)))
            foreach (var property in
                targetType.GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance)
                    .Where(property =>
                           property.CanWrite &&
                           !property.IsDefined(typeof (NotDataMemberAttribute), false)))
                yield return new AspectInstance(property, introduceDataMemberAspect);
        }
    }

    [AttributeUsage(AttributeTargets.Property)]
    public sealed class NotDataMemberAttribute : Attribute
    {
    }
}

See http://www.sharpcrafters.com/blog/post/PostSharp-Principals-Day-12-e28093-Aspect-Providers-e28093-Part-1.aspx http://www.sharpcrafters.com/blog/post/PostSharp-Principals-Day-12-e28093-Aspect-Providers-e28093-Part-1.aspx

这是一个工作示例。将此方面应用于类会将 XmlIgnore 属性应用于尚未应用 XmlElement 或 XmlAttribute 的任何公共属性。诀窍是使用 Postsharp 内置的 CustomAttributeIntroductioinAspect。您只需实例化一个指定属性类型和构造函数详细信息的实例,然后创建一个提供程序以将其应用到目标。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PostSharp.Extensibility;
using PostSharp.Aspects;
using PostSharp.Reflection;
using System.Xml.Serialization;

namespace ApplyingAttributes
{
    [MulticastAttributeUsage(MulticastTargets.Field | MulticastTargets.Property,
                            TargetMemberAttributes = MulticastAttributes.Public | MulticastAttributes.Instance)]
    public sealed class AddXmlIgnoreAttribute : LocationLevelAspect, IAspectProvider
    {
        private static readonly CustomAttributeIntroductionAspect customAttributeIntroductionAspect =
            new CustomAttributeIntroductionAspect(
                new ObjectConstruction(typeof(XmlIgnoreAttribute).GetConstructor(Type.EmptyTypes)));

        public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
        {
            LocationInfo memberInfo = (LocationInfo)targetElement;

            if (memberInfo.PropertyInfo.IsDefined(typeof(XmlElementAttribute), false) ||
                memberInfo.PropertyInfo.IsDefined(typeof(XmlAttributeAttribute), false))
                yield break;

            yield return new AspectInstance(memberInfo.PropertyInfo, customAttributeIntroductionAspect);
        }
    }

}

要使用属性,指定参数,我使用

 public class MyAspect : TypeLevelAspect, IAspectProvider
{
    public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
    {
        yield return Create<MethodInfo>(mi, "Value");

    }

    private AspectInstance Create<T>(T target, string newName)
    {
        var x = new CustomAttributeIntroductionAspect(
            new ObjectConstruction(typeof(NewMethodName).GetConstructor(new Type[] { typeof(string) }), new object[] { newName })
            );

        return new AspectInstance(target, x);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 PostSharp 属性注入属性? 的相关文章

随机推荐

  • 使用 PyQt5 将 qDebug 输出重定向到文件

    我使用 python2 7 Qt5 5 和 PyQt5 实现了一个应用程序 我使用Python记录器工作logging 模块 日志消息都发送到 stderr 和日志文件 但是 Qt 日志消息仅出现在 stderr 中 我找不到将它们重定向到
  • 带有标记和线条的传单

    我将 leafletjs 与 geojson 一起使用 但我无法同时使用标记绘制折线 所以我的解决方案是先绘制折线 然后添加标记 我认为这不是一个好的方法 那么还有其他解决方案吗 这是我的代码 function DrawLine mymap
  • SSRS独特的查找集函数

    我在用着Join Lookupset 查找返回序列号的唯一组值 这是我的功能 Join LookupSet Fields itemId Value Fields UseByDate Value Fields rackId Value Fie
  • Python:如何使用 BeautifulSoup 模拟点击

    我不想使用 selenium 因为我不想打开任何浏览器 该按钮会触发 Javascript 方法来更改页面中的某些内容 我想模拟按钮单击 以便我可以从中获取 输出 示例 不是按钮实际执行的操作 我输入一个名字 例如 John 按下按钮 它会
  • 如何在 Action 类之外将错误消息从 Struts2 发布到 HTML

    我有一个注册程序 当我在数据库中插入一条记录时 我将实例化一个类并调用该方法insert 当我插入相同的记录时 当然会出现重复数据错误和大量错误消息 我想捕捉它try and catch 我能做到 但是 我不知道如何将消息显示到 JSP 据
  • 提高 jQuery 模板性能

    Update 显然 jQuery 模板可以被编译 并且它有助于提高模板的性能if 语句 shown here http jsperf com complex template vs concat 4 但如图所示here http jsper
  • MFC> 将对话框连接到对话框类

    我在现有的资源文件中定义了一个新对话框及其控件 我还创建了一个新文件 它将处理从此对话框生成的事件 但我不确定如何连接这两者 是声明enum IDD IDD NEW DIALOG 连接两者所需的一切 或者我们应该添加一些其他声明 在 MFC
  • 网络调用 /.well-known/openid-configuration/ 和 /.well-known/openid-configuration/jwks

    I have 身份服务器4 具有 OpenId Connect 和混合流的 Mvc 应用程序 WebApi应用程序 假设用户已经获得带有 id token 和访问令牌的 cookie 然后他从 mvc 应用程序调用一个操作 var clie
  • 从列表列表创建 pandas 数据框,但有不同的分隔符

    我有一个列表列表 1 Toy Story 1995 Animation Children s Comedy 2 Jumanji 1995 Adventure Children s Fantasy 3 Grumpier Old Men 199
  • h5py 不遵守分块规范?

    问题 我有现有的 netCDF4 文件 大约 5000 个 通常形状为 96x3712x3712 数据点 float32 这些文件的第一维是时间 每天一个文件 第二维和第三维是空间维 目前 在第一维上制作切片 即使是部分切片 会花费大量时间
  • Angular RouterLink queryParamsHandling 处理可选参数

    是否有一种干净的方法可以将当前可选的 queryParams 与模板中链接上的附加可选 queryParam 合并 当前网址 search brand Trek 所需的转到链接 search brand Trek start 1 start
  • 获取Web层之外的当前Principal

    我有以下 ntier 应用程序 MVC gt 服务 gt 存储库 gt 域 我正在使用表单身份验证 在 MVC 层之外使用 Thread CurrentPrincipal 来获取应用程序当前登录的用户是否安全 或者我应该使用 HttpCon
  • 使用 tampermonkey 获取与页面相关的所有请求的标头

    我正在尝试编写一个 tampermonkey 脚本 该脚本将 document location 和标题收集在字典中 谷歌搜索了一下 发现我应该使用某种全局变量 但它没有按我想要的方式工作 这是脚本 UserScript name My F
  • 性能测量的建模分布

    您如何对重复的现实生活性能测量的分布进行数学建模 现实生活 意味着您不仅仅是循环有问题的代码 而且它只是在典型用户场景中运行的大型应用程序中的一个简短片段 我的经验表明 平均执行时间通常会出现峰值 可以使用高斯分布对其进行充分建模 此外 还
  • 在 sed 表达式中转义替换字符串中的“\”字符

    我正在尝试获取一行文本 例如 13 Check for orphaned Path entries 并将其更改为 我希望 bash 颜色代码对输出进行着色 而不是显示在屏幕上 033 32m 033 0m Check for orphane
  • azure devops 管道 CopyFiles@2 任务从代理 A 复制文件,但 DownloadBuildArtifacts@0 将文件下载到代理 B

    我对来自托管代理的复制文件进行了有线行为 然后将它们下载回同一代理 看起来它从代理 A 复制文件 但相同的管道将它们下载回代理 B with 在另一台机器上执行另一个不相关的构建工作 Upload from ios docker 142 l
  • Spring security:添加“成功登录事件侦听器”

    我是 Spring Security 的新手 如何添加在用户成功登录时调用的事件侦听器 另外 我需要在此侦听器中获取某种唯一的会话 ID 该 ID 应该可以进一步使用 我需要这个 ID 来与另一台服务器同步 您需要定义一个 Spring B
  • Android Studio 新项目文件大小太大

    我刚刚在 Android Studio 2 2 3 中创建了一个新的 android 项目 只有一个空的 Activity 但它仍然在设备上使用了 4 11 MB 我认为这个空间很大 因为它确实包含一个空的 Activity 为什么它占用这
  • 如何禁用 Firefox 开发者版中新的 JSON 查看器/阅读器?

    火狐开发者版 44现在有一个内置的 JSON 查看器 https developer mozilla org en US docs Tools JSON viewer 这是一个很好的举动 但我非常喜欢我使用的第三方 JSON 查看器的可读性
  • 如何使用 PostSharp 属性注入属性?

    如何编写 PostSharp 方面以将属性应用于类 我正在考虑的场景是一个 WCF 实体 或域对象 需要用DataContract属性 它还应该有一个Namespace财产 像这样 using System Runtime Serializ