2010-07-09 35 views
7

Tôi muốn mở rộng IPrincipal trong asp.net để cho phép tôi nhận được loại người dùng mà tôi sẽ xác định. Tôi muốn làm cho nó có thể làm điều này trong một bộ điều khiểnasp.net mở rộng IPrincipal

string type = User.UserType 

sau đó trong phương pháp khuyến nông của tôi sẽ có một phương pháp như

public string UserType() 
{ 
    // do some database access 
    return userType 

} 

làm thế nào tôi có thể làm điều này? là nó có thể? Cảm ơn!

+0

Bạn không mở rộng một giao diện, bạn thực hiện nó. –

+0

Hoặc, thay vào đó, nó có thể mở rộng nó, nhưng đó là cái gì khác. Điều đó sẽ tạo ra một giao diện mới, đó là một superset của base. –

Trả lời

10

Bạn có thể thực hiện một phương pháp khuyến nông:

public static string UserType(this IPrincipal principal) { 
    // do some database access 
    return something; 
} 
+0

Đó sẽ là thông minh, nhưng nguy hiểm. Phần "trả lại một cái gì đó" sẽ thực sự phải downcast nó để thực hiện của mình và gọi một số tài sản. Điều này sẽ thất bại nếu được thực thi trên bất kỳ triển khai IPrincpal nào khác. –

+0

lớp học cần phải trông như thế nào trong đó phương pháp mở rộng này được tìm thấy? – twal

+1

Nó cần phải là một 'lớp tĩnh'. – SLaks

2

Dưới đây là một lớp tùy chỉnh ví dụ triển khai IPrincipal. Lớp này bao gồm một vài phương pháp bổ sung để kiểm tra vai trò liên kết nhưng hiển thị thuộc tính có tên UserType theo yêu cầu của bạn.

public class UserPrincipal : IPrincipal 
    { 
    private IIdentity _identity; 
    private string[] _roles; 

    private string _usertype = string.Empty; 


    public UserPrincipal(IIdentity identity, string[] roles) 
    { 
     _identity = identity; 
     _roles = new string[roles.Length]; 
     roles.CopyTo(_roles, 0); 
     Array.Sort(_roles); 
    } 

    public IIdentity Identity 
    { 
     get 
     { 
     return _identity; 
     } 
    } 

    public bool IsInRole(string role) 
    { 
     return Array.BinarySearch(_roles, role) >= 0 ? true : false; 
    } 

    public bool IsInAllRoles(params string[] roles) 
    { 
     foreach (string searchrole in roles) 
     { 
     if (Array.BinarySearch(_roles, searchrole) < 0) 
     { 
      return false; 
     } 
     } 
     return true; 
    } 

    public bool IsInAnyRoles(params string[] roles) 
    { 
     foreach (string searchrole in roles) 
     { 
     if (Array.BinarySearch(_roles, searchrole) > 0) 
     { 
      return true; 
     } 
     } 
     return false; 
    } 

    public string UserType 
    { 
     get 
     { 
     return _usertype; 
     } 
     set 
     { 
     _usertype = value; 
     } 
    } 

    } 

Tận hưởng!

+0

Phải, ngoại trừ việc họ không thể gọi UserType được đưa ra một tham chiếu đến IPrincipal. –

2

Về cơ bản, không. Bạn có thể triển khai IPrincipal với một lớp như MyPrincipal và lớp đó có thể có thuộc tính UserType nhưng bạn phải truy cập cá thể thông qua tham chiếu thuộc loại riêng của nó để tiếp cận nó, không phải thông qua tham chiếu giao diện.

chỉnh sửa

Một phần mở rộng phương pháp có thể làm việc, nhưng chỉ khi bạn hoàn toàn chắc chắn bạn sẽ không bao giờ gọi nó trên một cái gì đó mà thực hiện IPrincipal nhưng không phải là một thể hiện của lớp của riêng bạn.

+0

Cảm ơn bạn. Tôi sẽ suy nghĩ về cơ hội của IPrincipal được thực hiện ở một nơi khác. Tôi không chắc chắn nếu nó sẽ có trên ứng dụng của tôi. Tôi không chắc chắn kịch bản nào sẽ gây ra điều này. Nhưng nếu như vậy việc thực hiện nó cũng sẽ làm việc cho tôi. Cảm ơn ngài! – twal

+0

@twal: Thông thường, khung làm việc cho bạn một IPrincipal mà thực hiện là một số lớp học từ khuôn khổ đó. Vì vậy, miễn là bạn chắc chắn điều này sẽ không xảy ra, một phương pháp mở rộng sẽ đáp ứng nhu cầu của bạn. –

+0

Cảm ơn bạn Steven! – twal

3

Chắc chắn. Làm lớp học của bạn thực hiện IPrincipal:

public class MyPrinciple : IPrincipal { 
    // do whatever 
} 

phương pháp mở rộng:

public static string UserType(this MyPrinciple principle) { 
    // do something 
} 
+0

Cùng một vấn đề như câu trả lời của SLaks: "làm điều gì đó" sẽ liên quan đến downcasting, có thể thất bại. –