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

时间:2016-08-04 18:07:01

标签: orchardcms

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

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

  1. 我需要为我传递的任何内容项返回所有已注册处理程序或处理程序方法的列表。
  2. 根据这是什么类型的事件,我需要为此内容项调用(registered?)事件处理程序方法。
  3. 有没有办法在果园里这样做?

1 个答案:

答案 0 :(得分:2)

一旦掌握了模块,交流模块就不那么难了。还有几种方法可以实现这一目标。 这个答案基于你最后的评论,因为Bertrand指出了你正确的方向。

使用简单的EventHandlers

有关更复杂的示例,请查看 Orchard.Users 中的现有 IUserEventHandler

模块A

服务/ 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

控制器/ 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

处理程序/ 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.Workflows Orchard.Tokens ,您的自定义EventHandler和您的想象力的组合 是处理各种场景的一种非常强大的方法。 模块甚至不必在这个层面上相互了解(这里的高度概括声明)。

让我们看看:

模块A

首先,我们需要定义自定义工作流程活动。

活动/ 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
    }
}

通过我们的自定义活动,我们终于可以完成一些工作流程魔术。 这里的可能性几乎无穷无尽;你可以触发其他工作流程,写电子邮件等。

处理程序/ 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" }
                }
            )
        }
    }
}

我希望这些例子可以帮助你。 我从头顶写下了所有东西,所以我可能忘记了什么。

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