2012-11-26 15 views
6

Tôi đang cố gắng để thiết lập một khía cạnh PostSharp RunOutOfProcessAttribute để nó áp dụng cho:Áp dụng một khía cạnh quan đến các phương pháp duy nhất mà có một thuộc tính cụ thể

  1. tất cả các phương pháp công
  2. bất kỳ phương pháp đánh dấu bằng DoSpecialFunctionAttribute, bất kể khả năng truy cập của thành viên (công khai/được bảo vệ/riêng tư/bất kỳ điều gì).

Cho đến nay, tôi RunOutOfProcessAttribute được định nghĩa thusly:

[Serializable] 
[MulticastAttributeUsage(MulticastTargets.Method, TargetMemberAttributes = MulticastAttributes.Public)] 
[AttributeUsage(AttributeTargets.Class)] 
public class RunOutOfProcessAttribute : MethodInterceptionAspect 
{ 
    public override void OnInvoke(MethodInterceptionArgs args) 
    { 
     ... 
    } 
} 

Các MulticastAttributeUsageAttribute đã được tại chỗ nên thực hiện tiêu chí 1 ở trên, nhưng tôi đã không có ý tưởng làm thế nào để hoàn thành chỉ tiêu 2, mà không chỉ đơn giản là nhân đôi hành vi của khía cạnh hiện có thành thuộc tính mới.

Làm cách nào để áp dụng phương pháp này cho bất kỳ phương pháp nào được đánh dấu bằng DoSpecialFunctionAttribute, bất kể khả năng truy cập của thành viên (công khai/bảo vệ/riêng tư/bất kỳ điều gì)?

+0

im bối rối là tại sao này là bắt buộc. Nếu bạn đã có một 'DoSpecialFunctionAttribute' tại sao không chỉ bao gồm các chức năng để làm điều này trong thuộc tính đó? thay vì tạo ra khía cạnh nào KHÁC. – caesay

+0

Tôi muốn có thể đặt 'RunOutOfProcessAttribute' vào một lớp, vì nó định nghĩa một hành vi lớp hơn là một hành vi của phương thức. 'RunOutOfProcessAttribute' sẽ hoạt động trên * tất cả các phương thức lớp công khai ngoài bất kỳ phương thức được bảo vệ nào được đánh dấu bằng' DoSpecialFunctionAttribute'. 'DoSpecialFunctionAttribute' sẽ không phải là một khía cạnh. –

Trả lời

6

Dưới đây là giải pháp:

  • Target tất cả các phương pháp với [MulticastAttributeUsage(MulticastTargets.Method)]
  • Override CompileTimeValidate(MethodBase method). Thiết lập giá trị trả lại sao cho số CompileTimeValidate trả về true trên các mục tiêu thích hợp, false trên các mục tiêu để bỏ qua âm thầm và ném ngoại lệ khi người dùng được cảnh báo rằng việc sử dụng Aspect không phù hợp (chi tiết trong PostSharp documentation).

Trong mã:

[Serializable] 
[MulticastAttributeUsage(MulticastTargets.Method)] 
[AttributeUsage(AttributeTargets.Class)] 
public class RunOutOfProcessAttribute : MethodInterceptionAspect 
{ 
    protected static bool IsOutOfProcess; 

    public override void OnInvoke(MethodInterceptionArgs args) 
    { 
     ... 
    } 

    public override bool CompileTimeValidate(MethodBase method) 
    { 
     if (method.DeclaringType.GetInterface("IDisposable") == null) 
      throw new InvalidAnnotationException("Class must implement IDisposable " + method.DeclaringType); 

     if (!method.Attributes.HasFlag(MethodAttributes.Public) && //if method is not public 
      !MethodMarkedWith(method,typeof(InitializerAttribute))) //method is not initialiser 
      return false; //silently ignore. 

     return true; 
    } 
}