2010-07-09 2 views
7

Я хотел бы расширить IPrincipal в asp.net, чтобы позволить мне получить пользовательский тип, который я определю. Я хотел бы сделать это возможным сделать это в контроллереasp.net extension IPrincipal

string type = User.UserType 

то в моем методе расширения я буду иметь метод, как

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

} 

, как я могу это сделать? Является ли это возможным? Спасибо!

+0

Вы не продлевают интерфейс, вы реализуете его. –

+0

Или, скорее, его можно продлить, но это что-то еще. Это создаст новый интерфейс, который является надмножеством базы. –

ответ

10

Вы можете сделать метод расширения:

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

Это было бы умно, но рискованно. Части «вернуть что-то» на самом деле должны были бы свести его к своей реализации и вызвать некоторое свойство. Это не сработает при выполнении любой другой реализации IPrincpal. –

+0

Что должен выглядеть класс, в котором этот метод расширения найден? – twal

+1

Это должен быть «статический класс». – SLaks

2

Вот пример пользовательского класса, который реализует IPrincipal. Этот класс включает несколько дополнительных методов проверки принадлежности ролей, но показывает свойство с именем UserType в соответствии с вашими требованиями.

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; 
     } 
    } 

    } 

Наслаждайтесь!

+0

Правильно, за исключением того, что они не могут вызывать UserType с ссылкой на IPrincipal. –

2

В принципе, нет. Вы можете реализовать IPrincipal с классом, например MyPrincipal, и этот класс может иметь свойство UserType, но вам нужно будет получить доступ к экземпляру через ссылку своего собственного типа, чтобы достичь его, а не через ссылку на интерфейс.

редактировать метод

Расширение может работать, но только если вы абсолютно уверены, что вы никогда не будете называть это на то, что реализует IPrincipal, но не является экземпляром своего класса.

+0

Спасибо. Я буду думать о шансах внедрения IPrincipal в другом месте. Я не уверен, будет ли это когда-либо в моем заявлении. Я не уверен, какие сценарии вызовут это. Но если это так, то это будет работать и для меня. Спасибо, сэр! – twal

+0

@twal: Зачастую структура передает вам IPrincipal, реализация которого представляет собой некоторый класс из этой структуры. Пока вы уверены, что этого не произойдет, метод расширения будет отвечать вашим потребностям. –

+0

Спасибо, Стивен! – twal

3

Несомненно. Сделайте ваш класс реализует IPrincipal:

public class MyPrinciple : IPrincipal { 
    // do whatever 
} 

метод выдвижения:

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

Такая же проблема, как ответ SLaks: «сделать что-то» будет связано с понижением, которое может потерпеть неудачу. –

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