有没有办法将自定义事件处理程序添加到 Orchard 中的某个部分?

Is there a way to add custom event handlers to a part in Orchard?

基本上我有一个模块,它有一个 class,它有一个方法,我将接收不同类型的内容项作为参数,以及一个代表 自定义的字符串 事件类型。根据传入的内容项类型,我想通过调用其自定义处理程序方法来以某种方式处理该项目,无论它是哪种类型的事件。

我试图不惜一切代价避免耦合,因此该模块不应该知道这些内容项或其事件处理方法。

  1. 我需要 return 为我传入的任何内容项列出所有已注册处理程序或处理程序方法的列表。
  2. 根据这是什么类型的事件,然后我需要为此内容项调用(已注册?)事件处理程序方法。

有没有办法在果园里做到这一点???

一旦你掌握了它,跨模块通信并不难。也有几种方法可以实现这一点。 此答案基于您的上一条评论,因为 Bertrand 为您指明了正确的方向。

使用简单的事件处理程序

对于更复杂的示例,请查看 Orchard.Users.

中现有的 IUserEventHandler

模块 A

Services/IMyCustomEventHandler.cs

namespace My.ModuleA.Services
{
    // This is the eventHandler you inject wherever you need it. (e.g. Module B)
    public interface IMyCustomEventHandler : IEventHandler
    {
        // IContent should suit you in this case but you could also pass in 
        // just the contentItem id, or whatever else you need.
        void SomethingHappened(IContent content);
    }
}

模块 B

Controllers/FancyController.cs

namespace My.ModuleB.Controllers
{
    public class FancyController : Controller
    {
        private readonly IMyCustomEventHandler handler;

        public FancyController(IMyCustomEventHandler handler)
        {
            this.handler = handler;
        }

        public ActionResult DoSomething()
        {
            // ...some computation here

            this.handler.SomethingHappened(myContentItem);
        }
    }
}

模块 C

Handlers/BoringCustomEventHandler.cs

namespace My.ModuleC.Handlers
{
    // This is the most basic eventhandler to implement
    public class BoringCustomEventHandler : IMyCustomEventHandler
    {
        public void SomethingHappened(IContent content)
        {
            // Do whatever here.

            // As you can see we handle an Event here in Module C
            // that was dispatched in Module B
            // via a service declared in Module A.
        }
    }
}

使用工作流/活动

好的,现在它变得有趣了。 Orchard.WorkflowsOrchard.Tokens的组合,你的自定义EventHandler和你的想象 是一种处理各种场景的非常强大的方法。 模块甚至不必在此级别上相互了解(此处为高度概括的陈述)。

一起来看看:

模块 A

首先我们需要定义一个自定义工作流程activity。

Activities/SomethingHappenedActivity.cs

namespace My.ModuleA.Activities
{
    public class SomethingHappenedActivity : Event
    {
        // This is a neat convention for avoiding typos.
        public const string EventName = "SomethingHappened";

        // As the name says, this Activity will be able to start a workflow when triggered.
        // There are a lot of existing Activities, so I encourage you to check them out.
        public override bool CanStartWorkflow
        { 
            get { return true; }
        }

        // ... other stuff here
    }
}

有了我们的自定义 activity,我们终于可以做一些工作流魔术了。 这里的可能性几乎是无穷无尽的;您可以触发其他工作流程、编写电子邮件等

Handlers/WorkflowMyCustomEventHandler.cs

namespace My.ModuleA.Handlers
{
    // This implementation of our custom event handler will trigger workflow activities for us.
    public class WorkflowMyCustomEventHandler : IMyCustomEventHandler
    {
        private readonly IWorkflowManager workflowManager;

        public WorkflowMyCustomEventHandler(IWorkflowManager workflowManager)
        {
            this.workflowManager = workflowManager;
        }

        // Should be self-explanatory.
        // When we invoke our IMyCustomEventHandler.SomethingHappened() event,
        // this implementation will trigger our custom workflow activity.
        // Also don't forget that you can do all kinds of magic with *Orchard.Tokens*!
        public void SomethingHappened(IContent content)
        {
            this.workflowManager.TriggerEvent(
                SomethingHappenedActivity.EventName,
                content.ContentItem,
                () => new Dictionary<string,object>
                {
                    { "Content", content.ContentItem },
                    { "OtherStuff", "whatever else you want to provide here" }
                }
            )
        }
    }
}

我希望这些示例对您有所帮助。 我都是从头开始写的,所以我可能忘记了什么。

如果您有任何其他问题,请在评论中告诉我,我会更新我的答案,或者直接转到 orchard gitter 频道。