2013-11-23 4 views
0

У меня есть экземпляр, и я новичок в делегатах C#, Func, Expression и action. Я хочу передать параметр как выражение, которое будет проверять в течение нескольких условий, а затем он будет возвращать или выполнить на основе некоторых условий, при условии, что-то вроде этогоИспользование делегата выражения и действия для структуры принятия решений

var result = Uow.GroupLicense.Set 
         .Join(Uow.UserGroup.Set, x => x.GroupGuid, y => y.GroupGuid, (GL, G) => new { G, GL }) 
         .Join(Uow.Users.Set, x => x.G.UserGuid, y => y.UserGuid, (UG, U) => new { UG, U }) 
         .SingleOrDefault(x => x.U.UserID == Username); 

      if (result != null && result.UG.GL.IsActive && result.U.IsEnabled && !result.U.IsLocked) 
      { 
       SessionStorage.LoginAttempts = UpdateLoginAttempts(Username, true); 
       SessionStorage.SessionID = HttpContext.Current.Session.SessionID; 
       SessionStorage.LoginAttempts = 0; 
       SessionStorage.UserName = Username; 
       SessionStorage.ABBUserName = Username; 
      } 
      else if (!result.UG.GL.IsActive) 
      { 
       result.U.IsEnabled = false; 
       result.U.IsLocked = true; 
       Uow.Users.Update(result.U); 
       Uow.Commit(); 
       ErrorMessage = "User License Expired"; 
      } 
      else if (result.U.IsLocked) 
      { 
       ErrorMessage = "User is locked"; 
      } 
      else if (!result.U.IsEnabled) 
      { 
       ErrorMessage = "User is disabled by administrator"; 
      } 
      else 
      { 
       ErrorMessage = "User doesnt exist "; 
      } 

Теперь это мой исходный код. Я хочу преобразовать это в дерево решений на основе двух условий элемента класса. Что-то вроде этого

if this -> Boolean result = EnsureLicense((x, y) => x.IsEnabled && y.IsActive); 
    then do Action1 
    if This -> Boolean result = EnsureLicense((x, y) => !x.IsEnabled && y.IsActive); 
    then do Action2 
    if This - > Boolean result = EnsureLicense((x, y) => !x.IsEnabled && y.IsLocked); 
    then do Action3. 

Я не хочу включить его в чем-то, как если бы еще структура кода с кратному, если еще и еще, если структура кода. Как продолжить эту стратегию, так как я не могу положить в корпус коммутатора.

Я хочу сделать это с помощью делегаций Actions and Expression и Func. Я хочу узнать, как продолжить эту стратегию.

Пожалуйста направьте меня

ответ

1

Вот решение с действиями и делегатов Func, которые не используют, если ... еще структуры. На самом деле это своего рода Chain of Responsibility:

public class LicenseHandler 
{ 
    private readonly Func<GroupLicense, User, bool> predicate; 
    private readonly Action action; 
    private LicenseHandler nextHandler; 

    public LicenseHandler(Func<GroupLicense,User, bool> predicate, Action action) 
    { 
     this.action = action; 
     this.predicate = predicate; 
    } 

    public LicenseHandler SetNext(LicenseHandler handler) 
    { 
     nextHandler = handler; 
     return this; 
    } 

    public void Handle(GroupLicense license, User user) 
    { 
     if (predicate(license, user)) 
     { 
      action(); 
      return; 
     } 

     if (nextHandler != null) 
      nextHandler.Handle(license, user); 
    } 
} 

Создание обработчиков и приковать их:

var handler1 = new LicenseHandler((l, u) => l.IsEnabled && u.IsActive, Action1); 
var handler2 = new LicenseHandler((l, u) => !l.IsEnabled && u.IsActive, Action2); 
var handler3 = new LicenseHandler((l, u) => !l.IsEnabled && u.IsLocked, Action3); 

handler1.SetNext(handler2.SetNext(handler3)); 

Обработка выглядит

handler1.Handle(licence, user); 

Люди, которые будут поддерживать делегата на основе кода вместо простых если-еще, примите мое глубочайшее сочувствие.

UPDATE: Если вы хотите хороший свободно API, то вы можете создать строитель класс, который будет создавать обработчики цепи:

public class LicenseHandlerBuilder 
{ 
    private LicenseHandler root; 
    private LicenseHandler current; 

    private LicenseHandlerBuilder() { } 

    public static LicenseHandlerBuilder CreateHandler(
     Func<GroupLicense, User, bool> predicate, Action action) 
    { 
     var builder = new LicenseHandlerBuilder(); 
     builder.root = new LicenseHandler(predicate, action); 
     builder.current = builder.root; 
     return builder; 
    } 

    public LicenseHandlerBuilder WithNext(
     Func<GroupLicense, User, bool> predicate, Action action) 
    { 
     var next = new LicenseHandler(predicate, action); 
     current.SetNext(next); 
     current = next; 
     return this; 
    } 

    public LicenseHandler Build() 
    { 
     return root; 
    } 
} 

Использование:

var handler = LicenseHandlerBuilder 
     .CreateHandler((l, u) => l.IsEnabled && u.IsActive, Action1) 
     .WithNext((l, u) => !l.IsEnabled && u.IsActive, Action2) 
     .WithNext((l, u) => !l.IsEnabled && u.IsLocked, Action3) 
     .Build(); 
+0

Его хорошо, но последнее утверждение требует, чтобы быть как логическое, которое снова выполняет какое-либо действие. Так может ли это быть сделано в качестве свободного интерфейса, если требуется? – Joy

+0

@ Джой, какое последнее заявление здесь? –

+0

Извините, извиниться. Я получил вашу мысль. Но можно ли это сделать без просто handler1.SetNext (handler2.SetNext (handler3)); но с плавным интерфейсом? что-то вроде chaning setNext, с которым нужно взаимодействовать как метод с условиями? с исходом одного в зависимости от другого? Я действительно новичок в этой архитектуре. – Joy

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