如何挂钩到另一个 Orchard 模块的动作

How to hook to action of another Orchard Module

给定: 模块 A 和模块 B 向上和 运行 在 Orchard CMS 中

Objective: 当调用模块 A 的动作时,从模块 B 执行一些代码

详细信息:模块 A 更新 UserPartRecord table,模块 B 应在创建新记录时更新其他 tables

我看到我必须向模块 A 的操作添加一些代码(调用模块 B 的代码),但是我如何在不对依赖项进行硬编码的情况下执行此操作(使用模块的 类模块 A) 中的 B?

在咨询了我的枕头之后,我确实记得 Orchard 用户也是 Orchard 内容项,因此应该使用一些内容管理界面。

这是我的解决方案:

模块 A(更新 Orchard 用户并应通知其他模块)

public class UserController
{
  // public
    public UserController( ... ,
      Orchard.Security.IMembershipService aMembershipService,
      Orchard.ContentManagement.IContentManager aContentManager,
      System.Collections.Generic.IEnumerable<Orchard.ContentManagement.Handlers.IContentHandler> aContentHandlers)
    {
      Logger = Orchard.Logging.NullLogger.Instance;

      mMembershipService = aMembershipService;
      mContentManager = aContentManager;
      mContentHandlers = aContentHandlers;
    }

    ...

    // this method updates Orchard users by utilizing the Orchard content manager / handler 
    // functionality to notify other modules about creation, update or removal of a user
    public System.Web.Mvc.ActionResult Update()
    {
      ...

      foreach (... lUser in lUserQuery)
      {
        // ... check whether a matching orchard user exists
        Orchard.Security.IUser lOrchardUser = mMembershipService.GetUser(lUser.IntranetLogin);
        if (lOrchardUser != null)
        {
          // update user
          ...

          // notify handlers about update (adopted from src\Orchard\ContentManagement\DefaultContentManager.cs)
          Orchard.ContentManagement.Handlers.UpdateContentContext lUpdateContext =
            new Orchard.ContentManagement.Handlers.UpdateContentContext(lOrchardUser.ContentItem);

          mContentHandlers.Invoke(aHandler => aHandler.Updated(lUpdateContext), Logger);            
        }
        else
        {
          // create user

          lOrchardUser = mMembershipService.CreateUser(...);

          // note: 
          //  no notify handling needed as mMembershipService.CreateUser() already notifies content handlers
        }
      }

      ...

      // remove deprecated users
      foreach (int lDeprecatedOrchardUserID in lDeprecatedOrchardUserIDs)
      {   
        // removeuser
        Orchard.Users.Models.UserPart lUserPart =
          mContentManager.Get<Orchard.Users.Models.UserPart>(lDeprecatedOrchardUserID);

        if (lUserPart != null)
        {
          // the following call removes the user (content item) and notifies content handlers about removal
          mContentManager.Remove(lUserPart.ContentItem);
        }
      }

      ...
    }

    public Orchard.Logging.ILogger Logger { get; set; }

  // private
    ...

    private Orchard.Security.IMembershipService mMembershipService;
    private Orchard.ContentManagement.IContentManager mContentManager;
    private System.Collections.Generic.IEnumerable<
      Orchard.ContentManagement.Handlers.IContentHandler> mContentHandlers;
}

模块 B(当出现 Orchard 用户 "change" 时收到通知)

public class TestHandler : Orchard.ContentManagement.Handlers.ContentHandler
{
  // public
    public TestHandler()
    {
      OnCreated<Orchard.Users.Models.UserPart>(UserCreated);
      OnUpdated<Orchard.Users.Models.UserPart>(UserUpdated);
      OnRemoving<Orchard.Users.Models.UserPart>(UserRemoving);
    }

  // private
    private void UserCreated(Orchard.ContentManagement.Handlers.CreateContentContext aContext,
      Orchard.Users.Models.UserPart aUserPart)
    {
      // do Module B specific tasks when a user is created
    }

    private void UserUpdated(Orchard.ContentManagement.Handlers.UpdateContentContext aContext,
      Orchard.Users.Models.UserPart aUserPart)
    {
      // do Module B specific tasks when a user is updated
    }

    private void UserRemoving(Orchard.ContentManagement.Handlers.RemoveContentContext aContext,
      Orchard.Users.Models.UserPart aUserPart)
    {
      // do Module B specific tasks when a user is removed
    }
}