我该如何编写一个PostSharp方面来将属性应用于类?我考虑的情况是需要使用
在上面的示例中,您可以看到我希望输出的样子。它应用于类的DataContract属性。手动执行此操作很繁琐且不唯一。我真的只想编写一个可以应用于我的“Domain”命名空间的单个方面。然后它会为我应用序列化相关的属性。这样我就可以专注于开发实体对象,而不必担心序列化细节。
我在PostSharp网站上找到了在方法之前、之后和代替注入代码的文档。然而,我正在寻找一种将Attribute注入到类型中的方法。
以下是解决方案!
DataContract
属性对WCF实体(或领域对象)进行装饰。同时,它还应该具有一个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属性。手动执行此操作很繁琐且不唯一。我真的只想编写一个可以应用于我的“Domain”命名空间的单个方面。然后它会为我应用序列化相关的属性。这样我就可以专注于开发实体对象,而不必担心序列化细节。
我在PostSharp网站上找到了在方法之前、之后和代替注入代码的文档。然而,我正在寻找一种将Attribute注入到类型中的方法。
以下是解决方案!
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
{
}
}