Smart Client Software Factory 如何使用Action Catalog

来源:互联网 发布:java 列出n之前的质数 编辑:程序博客网 时间:2024/05/01 19:59

首先需要了解Action Catalog这个玩意是干嘛用的,官网上的解释为,它可以决定程序中一个业务动作是否执行。在网上看了看,它使用最多的情况是权限控制。

下面看看怎么在SCSF中加入Action Catalog

首先在Infrastructure.Module项目中添加一个类 MyActionCondition ,并继承IActionCondition 接口,同时引用两个命名空间

using System.Threading;using Microsoft.Practices.CompositeUI;
然后在MyActionCondition类中,我们需要实现IActionCondition 接口的CanExecute方法

C#
public bool CanExecute(string action, WorkItem context, object caller, object target){  if (action == "ShowMyView" && Thread.CurrentPrincipal.Identity.Name == "Officer")  {    return true;  }  else  {    return false;  }}
接着,需要修改Infrastructure.Module工程中的Module.cs

需要引用命名空间,rootnamespace根据你自己项目的名字来,下面不再复述这个问题。

using rootnamespace.Infrastructure.Interface.Services;

下面的步骤就是在Modules 中注册 MyActionCondition 中的action catalog了,在Module.cs中加入如下方法

public override void AddServices(){  base.AddServices();  IActionCatalogService catalog = _rootWorkItem.Services.Get<IActionCatalogService>();  catalog.RegisterGeneralCondition(new MyActionCondition());}
下一步,需要修改Shell工程中的ShellApplication,首先引用两个命名空间

using rootnamespace.Infrastructure.Library.BuilderStrategies;using Microsoft.Practices.ObjectBuilder;
然后需要重写AddBuilderStrategies方法,把ActionStrategy加入到ObjectBuilder。该策略指定Builder的初始化阶段。这个策略会反射由ObjectBuilder创建的对象方法,并把打上Action属性标签的方法,加入Action catalog中

protected override void AddBuilderStrategies(Builder builder){  base.AddBuilderStrategies(builder);  builder.Strategies.AddNew<ActionStrategy>(BuilderStage.Initialization);}
下面需要修改MyModule工程中Constants文件夹下的ActionNames.cs

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace ActionCatalog.MyModule.Constants{    public class ActionNames    {        public const string ShowMyView = "ShowMyView";      }}
ShowMyView这是给这个Action起了个名字。

接下来在MyModule工程中新建一个类 ModuleActions,里面的ShowMyView方法打上了Action的属性标签,这个方法就被注册到Action Catalog 中,以此来控制这个被注册的方法在满足条件的情况下执行。

C#
public class ModuleActions{  private WorkItem _workItem = null;  [ServiceDependency]  public WorkItem WorkItem  {    get { return _workItem; }    set { _workItem = value; }  }  [Action(Constants.ActionNames.ShowMyView)]  public void ShowMyView(object caller, object target)  {    IMyView view = WorkItem.Items.AddNew<MyView>();    WorkItem.Workspaces[Constants.WorkspaceNames.RightWorkspace].Show(view);  }}
然后在MyModule工程中修改 ModuleController.cs

首先要注册这个Action,添加如下方法

        private void RegisterActions()        {            WorkItem.Items.AddNew<ModuleActions>();        }

然后要执行这个Action,添加如下方法

        private void ExecuteActions()        {            ActionCatalogService.Execute(Constants.ActionNames.ShowMyView, WorkItem, this, null);        }
最后需要在Run方法上加上刚才创建的两个方法

public override void Run(){  RegisterActions();  ExecuteActions();}
到这里就算完成了!

===============================================================

再拿一个老外的文章的例子说说

http://weblogs.asp.net/bsimser/archive/2007/10/26/taming-the-actioncatalog-in-scsf.aspx

这个老外,他有一个ModuleController类,在类中,他有一些权限判断要做,比如只有某个角色的用户才能看到某某菜单

public class ModuleController : WorkItemController{    public override void Run()    {        ExtendMenu();    }     private void ExtendMenu()    {        ToolStripMenuItem conditionalMenu = new ToolStripMenuItem("Conditional Code");        if (canManageUsers())        {            conditionalMenu.DropDownItems.Add(new ToolStripMenuItem("Manage Users"));        }        if (canManageAdministrators())        {            conditionalMenu.DropDownItems.Add(new ToolStripMenuItem("Manage Administrators"));        }        WorkItem.UIExtensionSites[UIExtensionSiteNames.MainMenu].Add(conditionalMenu);    }     private bool canManageAdministrators()    {        string userName = Thread.CurrentPrincipal.Identity.Name;        return            Thread.CurrentPrincipal.Identity.IsAuthenticated &&            userName.ToLower().Equals("domain\\admin");               }     private bool canManageUsers()    {        string userName = Thread.CurrentPrincipal.Identity.Name;        return            Thread.CurrentPrincipal.Identity.IsAuthenticated &&            userName.ToLower().Equals("domain\\joeuser");    }}
判断的方法虽然可以重用,但是大量的条件判断语句让人感觉不舒服,这个时候就是Action Catalog出场的时候了

下面他定义了几个不同的业务逻辑判断的方法

class AuthenticatedUsersCondition : IActionCondition{    public bool CanExecute(string action, WorkItem context, object caller, object target)    {        return Thread.CurrentPrincipal.Identity.IsAuthenticated;    }}

class UserCondition : IActionCondition{    public bool CanExecute(string action, WorkItem context, object caller, object target)    {        string userName = Thread.CurrentPrincipal.Identity.Name;        return userName.ToLower().Equals("domain\\joeuser");    }}

class AdministratorCondition : IActionCondition{    public bool CanExecute(string action, WorkItem context, object caller, object target)    {        string userName = Thread.CurrentPrincipal.Identity.Name;        return userName.ToLower().Equals("domain\\admin");    }}

上面对三种角色进行了判断。

然后创建一个业务动作类,来处理业务动作

public class ModuleActions{    private WorkItem _workItem;     [ServiceDependency]    public WorkItem WorkItem    {        set { _workItem = value; }        get { return _workItem; }    }     [Action(ActionNames.ShowUserManagementMenu)]    public void ShowUserManagementMenu(object caller, object target)    {        ToolStripMenuItem conditionalMenu = (ToolStripMenuItem) target;        conditionalMenu.DropDownItems.Add(new ToolStripMenuItem("Manage Users"));    }     [Action(ActionNames.ShowAdministratorManagementMenu)]    public void ShowAdministratorManagementMenu(object caller, object target)    {        ToolStripMenuItem conditionalMenu = (ToolStripMenuItem)target;        conditionalMenu.DropDownItems.Add(new ToolStripMenuItem("Manage Administrators"));    }}

最后,我们还需要在ModuleController中对业务动作进行注册到执行

public class ModuleController : WorkItemController{    private ToolStripMenuItem _rootMenuItem;     public override void Run()    {        ExtendMenu();        RegisterActionCatalog();        RegisterActionConditions();        ExecuteActions();    }     private void ExtendMenu()    {        _rootMenuItem = new ToolStripMenuItem("Action Catalog");        WorkItem.UIExtensionSites[UIExtensionSiteNames.MainMenu].Add(_rootMenuItem);    }     private void ExecuteActions()    {        ActionCatalogService.Execute(ActionNames.ShowUserManagementMenu, WorkItem, this, _rootMenuItem);        ActionCatalogService.Execute(ActionNames.ShowAdministratorManagementMenu, WorkItem, this, _rootMenuItem);    }     private void RegisterActionConditions()    {        ActionCatalogService.RegisterGeneralCondition(new AuthenticatedUsersCondition());        ActionCatalogService.RegisterSpecificCondition(ActionNames.ShowUserManagementMenu, new UserCondition());        ActionCatalogService.RegisterSpecificCondition(ActionNames.ShowAdministratorManagementMenu, new AdministratorCondition());    }     private void RegisterActionCatalog()    {        WorkItem.Items.AddNew<ModuleActions>();    }}
最后在ShellApplication中注册这个策略

protected override void AddBuilderStrategies(Builder builder){    base.AddBuilderStrategies(builder);    builder.Strategies.AddNew<ActionStrategy>(BuilderStage.Initialization);}