2012-04-02 7 views
2

Wir haben einen Dienst, der alle Daten des Clients verfügbar macht, haben alle das Objekt die Schnittstelle IAuthorized.Erstellen Sie eine bessere Möglichkeit zum Filtern von Daten basierend auf Benutzerrolle

Die Daten, die an den Client gesendet werden, müssen basierend auf den Benutzeranmeldeinformationen gefiltert werden.

der Fluss ist wie, dass der Kunde den Service anrufen -> der Dienst der SomeManager Klasse aufruft, die die Daten aus der Datenbank bekommt ...

hier kommt der AuthorizationManager die Daten zu filtern ...

public class SomeManager 
    { 
     public object[] Foo() 
     { 
      var data = Repository.GetData(); 
      return autorizationManager.Filter(data); 
     } 

     public object[] Foo_Else() 
     { 
      var data = Repository.GetOtherData(); 
      return autorizationManager.Filter(data); 
     } 

    } 

wie Sie jede Methode gefiltert werden sehen muss,

so, was ich frage Sie ist: können wir eine Basisklasse erstellen, die Filter jede Methode mit einigen der Ausgangsdaten zurück? ist es schlau? sollen wir es so lassen? einfach wach Methode wir Shell die Autorisierung aufrufen?

können Sie sich einen besseren Weg vorstellen?

etwas, was wie folgt aus:

public class EngineManager :BaseFilterAutho 
{ 
    [AuthorizationCollection] 
    public object[] Foo() 
    { 
     var data = Dao.GetData(); 
     return data; //get filtered 
    } 
     [SingleCollection] 
    public object Foo_Else() 
    { 
     var data = Dao.GetOtherData().First(); 
     return data //get filtered 
    } 

} 

Antwort

1

ich an einem Projekt gearbeitet haben, wo die Daten durch die Autorisierung des Benutzers gefiltert wurde. Die verwendete Methode ähnelt Ihrer "AuthorizationManager" -Methode. Das erforderte viel zu schreiben Code, aber es funktioniert OK und ist einfach zu verstehen.

Es gibt andere Methoden, Ihre Idee ist sicherlich möglich zu implementieren. Worauf Sie sich beziehen, ist Aspect Oriented Programming, AOP. Das ist in der Java-Welt üblich und auch in .Net möglich. PostSharp ist eine 3rd-Party-Bibliothek, die dies ermöglicht. Ich habe PostSharp nie selbst in einem Arbeitsprojekt verwendet, aber ich spiele gerade damit, um AOP selbst zu lernen.

Unten sehen Sie ein Beispiel für einen mit PostSharp implementierten Aspekt, der den Rückgabewert einer Methode zum Filtern der zurückgegebenen Daten ändern würde. Dies ist ein Dummy-Aspekt, bei dem ich mit einer PostSharp demo spiele und die zurückgegebenen Daten so filtriere, dass nur die Kontakte zurückgegeben werden, die den Buchstaben "S" enthalten.

Wie Sie sehen können, erfordert dieser Aspekt, dass der Rückgabewert IQueryable ist. Ich vermute, dass Sie immer ein Grundwissen über den Datentyp Ihrer Rückgabewerte haben müssen, z. wenn Sie mit IQueryable, ICollection, Arrays oder etwas anderem arbeiten.

[Serializable] 
    public class CollectionFilterAspect : OnMethodBoundaryAspect 
    { 
     public override void OnExit(MethodExecutionArgs args) 
     { 
      base.OnExit(args); 
      IQueryable<Contact> retVal = (IQueryable<Contact>)args.ReturnValue; 
      args.ReturnValue = from r in retVal where r.LastName.Contains("S") select r; 
     } 
    } 

diesen Aspekt zu verwenden, können Sie Ihre vorgeschlagene Syntax, setzen Sie ein Attribut auf die Methode verwenden, um anzuzeigen, dass es gefiltert werden soll.

Während diese kurze Demo veranschaulicht, dass dies sicherlich möglich ist, kann es oder nicht eine gute Idee sein. Ich habe keine Erfahrung darin, diese in der realen Software zu verwenden, also kann ich Ihnen dort nicht helfen.

+0

Vielen Dank für Ihren Kommentar, ich mag nicht Post scharf, weil es Code-Injektion. aber deine Idee von 'IQueryable' ist sehr gut, die Filterung kann mit ... – guyl