在 ASP.NET MVC 控制器中处理域事件

发布于 2024-10-31 22:12:36 字数 546 浏览 0 评论 0原文

我正在考虑使用 域事件 来冒泡信息发生在我的域模型深处的操作,以便在控制器级别发出某些事件的信号。不幸的是,我无法找到如何在 ASP.NET MVC 控制器上正确连接它的示例。

简而言之,这就是我在行动中寻找的东西:

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

任何人都可以为我提供一些指导吗?

更新

需要明确的是,我了解如何在控制器中引发和处理域事件;我只是在寻找一种注册事件的实现,该实现可以在我描述的上下文中安全使用。

I'm looking into using Domain Events to bubble information from operations occuring deep inside of my domain model in order to signal certain events at the controller level. Unfortunately, I haven't been able to find an example of how to properly wire this on an asp.net mvc controller.

In short, this is what I'm looking for inside of my action:

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

Can anyone offer me some guidance?

Update

Just to be clear, I understand how I would raise and handle the domain event in the controller; I'm just looking for an implementation of registering for the event that will be safe to use in the context I've described.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

放手` 2024-11-07 22:12:36

根据您链接到的示例,作者在其中执行此操作:

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


  }
} 

Based on the example you linked to, where the author does this:

Customer preferred = null;

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

c.DoSomething();

You should be able to do this:

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

Edit (DomainEvents modification)
This is untested and written in the StackOverflow edit box, but it's where I'd start. I'm using an optional parameter so that existing calls need not be modified, and a separate list "singleUseActions" to leave the existing guts as untouched as possible. Hope it helps.

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


  }
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文