首先需要了解Action Catalog这个玩意是干嘛用的,官网上的解释为,它可以决定程序中一个业务动作是否执行。在网上看了看,它使用最多的情况是权限控制。
下面看看怎么在SCSF中加入Action Catalog
首先在Infrastructure.Module项目中添加一个类 MyActionCondition ,并继承IActionCondition 接口,同时引用两个命名空间
using System.Threading; using Microsoft.Practices.CompositeUI;然后在MyActionCondition类中,我们需要实现IActionCondition 接口的CanExecute方法
public bool CanExecute(string action, WorkItem context, object caller, object target) { if (action == "ShowMyView" && Thread.CurrentPrincipal.Identity.Name == "Officer") { return true; } else { return false; } }
需要引用命名空间,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 中,以此来控制这个被注册的方法在满足条件的情况下执行。
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); } }
首先要注册这个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);
}