2013-10-04 3 views
2

Возможно ли иметь атрибут Postsharp, который может быть применен к классу, интерфейсу, свойству, полю или методу без использования MulticastAttributeUsage, чтобы пользователь точно определял, какие элементы он применяется против mulitcasting на каждого члена.Использование атрибутов Postsharp для нескольких элементов без их многократного использования

Если я использую MulticastAttributeUsage и использую свой атрибут для класса, он автоматически помещает новый экземпляр моего атрибута во все свойства, методы и т. Д. В сгенерированный IL.

Если я не использую его, он не будет компилироваться, потому что он жалуется, что мне нужно его использовать (я получаю из класса Aspect).

Вот мой сценарий:

Я создаю новый атрибут сериализации, поэтому я хочу, чтобы быть в состоянии сделать это:

[Serialise(ApplyToProperty="Test2", Name="Blah2")] 
public class MyClass { 

    [Serialise(Name="Blah1")] 
    public string Test1 { get; set; } 

    public bool Test2 { get; set; } 
} 

Когда я размышляю во время выполнения с помощью MulticastAttributeUsage я получаю два атрибута Serialise на Test1. Когда я смотрю на IL генерироваться он показывает это:

[Serialise(ApplyToProperty = "Test2", Name = "Blah2")] 
public class Test { 

    [Serialise(ApplyToProperty = "Test2", Name = "Blah2"), Serialise(Name = "Blah")] 
    public string Test1 { get; set; } 

    [Serialise(ApplyToProperty = "Test2", Name = "Blah2")] 
    public bool Test2 { get; set; } 

} 

Я мог бы просто не использовать PostSharp и отражение во время выполнения будет иметь именно то, что мне нужно, но мне нужно использовать PostSharp ввести еще один аспект. Мой SerialiseAttribute код это:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Property | AttributeTargets.Field)] 
[MulticastAttributeUsage(MulticastTargets.Class | MulticastTargets.Interface | MulticastTargets.Property | MulticastTargets.Field, AllowMultiple = true, PersistMetaData = true, Inheritance = MulticastInheritance.None)] 
public class SerialiseAttribute : Aspect, IAspectProvider { 

    public string ApplyToProperty { get; set; } 
    public string Name { get; set; } 

    public override bool CompileTimeValidate(object target) {   
     return false; 
    }  

    IEnumerable<AspectInstance> IAspectProvider.ProvideAspects(object targetElement) { 
     // Code that introduces a different attribute 
    } 

} 

Заметим также, что тот факт, что я возвращаюсь фальшь CompileTimeValidate, кажется, не оказывает никакого влияния на IL генерируемый, кажется, «тихий провал» не означает, что «не примените к нему атрибут "к сожалению. Итак, как я могу предотвратить Messageharp на самом деле многоадресный атрибут для всех участников?

ответ

2

Ваш пользовательский атрибут имеет класс Aspect, который, в свою очередь, получен из MulticastAttribute - вот почему вы получаете поведение многоадресной рассылки.

Вместо этого вы должны получить от System.Attribute и реализовать все необходимые вам интерфейсы. Это будет IAspectProvider и IValidableAnnotation в вашем случае.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Property | AttributeTargets.Field)] 
public class Serialise : Attribute, IAspectProvider, IValidableAnnotation 
{ 
    public string ApplyToProperty { get; set; } 
    public string Name { get; set; } 

    public bool CompileTimeValidate(object target) 
    { 
     return false; 
    } 

    public IEnumerable<AspectInstance> ProvideAspects(object targetElement) 
    { 
     // Code that introduces a different attribute 
    } 
} 

Что касается способа CompileTimeValidate - этот метод будет работать только после того, как мультикастинг был проведен, чтобы определить, следует ли вводить аспекты для каждого данного элемента кода с атрибутом уже применяется.

Смежные вопросы