2010-07-09 16 views
7

Vorrei estendere IPrincipal in asp.net per consentirmi di ottenere l'utente che definirò. Vorrei rendere possibile fare questo in un controlloreasp.net che estende IPrincipal

string type = User.UserType 

poi nel mio metodo di estensione avrò un metodo come

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

} 

come posso fare questo? È possibile? Grazie!

+0

Lei non estendere un'interfaccia, di implementarlo. –

+0

O, piuttosto, è possibile estenderlo, ma è qualcos'altro. Quello sarebbe creare una nuova interfaccia che è un superset della base. –

risposta

10

Si può fare un metodo di estensione:

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

Sarebbe intelligente, ma rischioso. La parte "restituisce qualcosa" dovrebbe effettivamente ridimensionarla alla sua implementazione e chiamare qualche proprietà. Questo fallirebbe se eseguito su qualsiasi altra implementazione IPrincpal. –

+0

come deve essere la classe in cui viene trovato questo metodo di estensione? – twal

+1

Deve essere una 'classe statica'. – SLaks

2

Ecco un esempio di classe personalizzata che implementa IPrincipal. Questa classe include alcuni metodi aggiuntivi per verificare l'affiliazione al ruolo ma mostra una proprietà denominata UserType in base alle proprie esigenze.

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

    } 

Divertiti!

+0

Giusto, tranne per il fatto che non potevano chiamare UserType dato un riferimento a IPrincipal. –

2

Fondamentalmente, no. È possibile implementare IPrincipal con una classe come MyPrincipal e quella classe può avere una proprietà UserType, ma è necessario accedere all'istanza tramite un riferimento del proprio tipo per raggiungerlo, non tramite il riferimento all'interfaccia.

modifica metodo

Un'estensione potrebbe funzionare, ma solo se si è assolutamente certi che non avrete mai chiamare su qualcosa che implementa IPrincipal ma non è un'istanza della propria classe.

+0

Grazie. Penserò alle possibilità che IPrincipal venga implementato altrove. Non sono sicuro che lo sarà mai sulla mia applicazione. Non sono sicuro di quali scenari potrebbero causare questo. Ma se così fosse, l'implementazione funzionerebbe anche per me. Grazie Signore! – twal

+0

@twal: Spesso, il framework ti fornisce un IPrincipal la cui implementazione è una classe di quel framework. Finché sei sicuro che questo non accadrà, un metodo di estensione soddisferà le tue esigenze. –

+0

Grazie, Steven! – twal

3

Sicuro. Fai la tua classe implementa IPrincipal:

public class MyPrinciple : IPrincipal { 
    // do whatever 
} 

metodo di estensione:

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

Lo stesso problema della risposta di SLaks: il "fare qualcosa" sta per coinvolgere il downcasting, che può fallire. –

Problemi correlati