Обработка события домена в контроллере asp.net mvc - PullRequest
3 голосов
/ 13 апреля 2011

Я пытаюсь использовать События домена для передачи информации об операциях, происходящих глубоко внутри моей модели домена, для сигнализации определенных событий на уровне контроллера. К сожалению, я не смог найти пример того, как правильно подключить это на контроллере asp.net mvc.

Короче, вот что я ищу в своем действии:

service.doSomethingComplicated();
var model = new ViewModel();
model.somethingComplicatedCausedSomethingElse = <true-if-my-domain-event-was-raised>;
return View(model);

Может кто-нибудь предложить мне какое-нибудь руководство?

Обновление

Просто для ясности, я понимаю как Я бы вызвал и обработал событие домена в контроллере; Я просто ищу реализацию регистрации для события, которое будет безопасно использовать в контексте, который я описал.

1 Ответ

3 голосов
/ 13 апреля 2011

На основе примера, на который вы ссылались, где автор делает это:

Customer preferred = null;

DomainEvents.Register<CustomerBecamePreferred>(
    p => preferred = p.Customer
        );

c.DoSomething();

Вы должны быть в состоянии сделать это:

    var model = new ViewModel();

    // Register a handler that sets your bool to true if / when the event is raised
    DomainEvents.Register<YourDomainEvent>(e => model.somethingComplicatedCausedSomethingElse = true);
    // EDIT: If using the singleUseActions modification, pass the second parameter
    // DomainEvents.Register<YourDomainEvent>(e => model.somethingComplicatedCausedSomethingElse = true, true);

    // Call the service. If it raises the event, the handler you just registered will set your bool
    service.doSomethingComplicated();

    return View(model);

Редактировать (модификация DomainEvents) Это не проверено и записано в поле редактирования StackOverflow, но это то, с чего я бы начал.Я использую необязательный параметр, чтобы существующие вызовы не нуждались в изменении, и отдельный список «singleUseActions», чтобы оставить существующие кишки как можно более нетронутыми.Надеюсь, это поможет.

public static class DomainEvents
  { 
      [ThreadStatic] //so that each thread has its own callbacks
      private static List<Delegate> actions;

      [ThreadStatic] //so that each thread has its own callbacks
      private static List<Delegate> singleUseActions;

      public static IContainer Container { get; set; } //as before

      //Registers a callback for the given domain event
      public static void Register<T>(Action<T> callback, bool isSingleUse = false) where T : IDomainEvent
      {
         List<Delegate> targetList;
         if (isSingleUse)
         {
             if (singleUseActions == null) singleUseActions = new List<Delegate>();
             targetList = singleUseActions;
         }
         else
         {
             if (actions == null) actions = new List<Delegate>();
             targetList = actions;
         }

         targetList.Add(callback);
     }

     //Clears callbacks passed to Register on the current thread
     public static void ClearCallbacks ()
     {
         actions = null;
         singleUseActions = null;
     }

     //Raises the given domain event
     public static void Raise<T>(T args) where T : IDomainEvent
     {
        if (Container != null)
           foreach(var handler in Container.ResolveAll<Handles<T>>())
              handler.Handle(args);

        if (actions != null)
            foreach (var action in actions)
                if (action is Action<T>)
                    ((Action<T>)action)(args);

        if (singleUseActions != null)
            // Don't foreach because we are going to modify the collection
            for (int index = singleUseActions.Count - 1; index > -1; index--)
            {
                var singleUseAction = singleUseActions[index];
                if (singleUseAction is Action<T>)
                {
                    ((Action<T>)singleUseAction)(args);
                    singleUseActions.RemoveAt(index);
                }
            }


  }
} 
...