Shell
程序入口继承自SmartClientApplication,WorkItem是CompositeUI默认的WorkItem,ShellForm是普通的Form,在ShellForm中定义了一个Name属性为"LayoutWorkspace"的 Private Microsoft.Practices.CompositeUI.WinForms.DeckWorkspace _layoutWorkspace,
public class ShellApplication : SmartClientApplication<WorkItem, ShellForm> { /// <summary> /// Application entry point. /// </summary> [STAThread] static void Main() { #if (DEBUG) RunInDebugMode(); #else RunInReleaseMode(); #endif } ...
在SmartClientApplication中做了较多工作,代码如下:
public abstract class SmartClientApplication<TWorkItem, TShell> : FormShellApplication<TWorkItem, TShell> where TWorkItem : WorkItem, new() where TShell : Form { protected override void AddBuilderStrategies(Builder builder) { base.AddBuilderStrategies(builder); builder.Strategies.AddNew<ActionStrategy>(BuilderStage.Initialization); } protected override void AddServices() { base.AddServices(); // Authentication services RootWorkItem.Services.AddNew<UserSelectorService, IUserSelectorService>(); RootWorkItem.Services.Remove<IAuthenticationService>(); RootWorkItem.Services.AddNew<SimpleWinFormAuthenticationService, IAuthenticationService>(); RootWorkItem.Services.AddNew<SimpleRoleService, IRoleService>(); // Profile catalog services RootWorkItem.Services.AddNew<ProfileCatalogService, IProfileCatalogService>(); //Add the InfoStore service we want to use //RootWorkItem.Services.AddNew<ProfileCatalogModuleInfoStore, IModuleInfoStore>(); RootWorkItem.Services.AddNew<WebServiceCatalogModuleInfoStore, IModuleInfoStore>(); RootWorkItem.Services.Remove<IModuleEnumerator>(); RootWorkItem.Services.Remove<IModuleLoaderService>(); RootWorkItem.Services.AddNew<XmlStreamDependentModuleEnumerator, IModuleEnumerator>(); RootWorkItem.Services.AddNew<DependentModuleLoaderService, IModuleLoaderService>(); RootWorkItem.Services.AddNew<ActionCatalogService, IActionCatalogService>(); IUIElementAdapterFactoryCatalog catalog = RootWorkItem.Services.Get<IUIElementAdapterFactoryCatalog>(); catalog.RegisterFactory(new LinkLabelPanelUIAdapterFactory()); RootWorkItem.Services.AddNew<WorkspaceLocatorService, IWorkspaceLocatorService>(); RootWorkItem.Services.AddNew<EntityTranslatorService, IEntityTranslatorService>(); } protected override void BeforeShellCreated() { base.BeforeShellCreated(); InitializeWebServiceCatalogModuleInfoStore(); } private void InitializeWebServiceCatalogModuleInfoStore() { IRoleService roleService = RootWorkItem.Services.Get<IRoleService>(); WebServiceCatalogModuleInfoStore store = RootWorkItem.Services.Get<IModuleInfoStore>() as WebServiceCatalogModuleInfoStore; store.Roles = roleService.GetRolesForUser(Thread.CurrentPrincipal.Identity.Name); } protected override void AfterShellCreated() { base.AfterShellCreated(); ShellNotificationService notificationService = new ShellNotificationService(this.Shell); RootWorkItem.Services.Add(typeof (IMessageBoxService), notificationService); } }
加入了一个Stratagey(ActionStrategy)
public override object BuildUp(IBuilderContext context, Type typeToBuild, object existing, string idToBuild) { WorkItem workItem = GetWorkItem(context, existing); if (workItem != null) { IActionCatalogService actionCatalog = workItem.Services.Get<IActionCatalogService>(); if (actionCatalog != null) { Type targetType = existing.GetType(); foreach (MethodInfo methodInfo in targetType.GetMethods()) RegisterActionImplementation(context, actionCatalog, existing, idToBuild, methodInfo); } } private void RegisterActionImplementation(IBuilderContext context, IActionCatalogService catalog, object existing, string idToBuild, MethodInfo methodInfo) { foreach (ActionAttribute attr in methodInfo.GetCustomAttributes(typeof(ActionAttribute), true)) { ActionDelegate actionDelegate = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), existing, methodInfo); catalog.RegisterActionImplementation(attr.ActionName, actionDelegate); // TODO: Add to resources TraceBuildUp(context, existing.GetType(), idToBuild, "Action implementation built for action {0}, for the method {1} on the type {2}.", attr.ActionName, methodInfo.Name, existing.GetType().Name); } }
在ModuleActions中集中写动作代码,在方法上打上“[Action("ActionName")]”标记,ActionStrategy将标记的方法新建代理都注册到ActionCatalogService中的Dictionary<string, ActionDelegate>集合中,这样在其他地方就可以简单的用ActionCatalog.Execute(“ActionNames”, WorkItem, this, null)的方法调用
[Action(ActionNames.ShowCustomerQueueManagementView)] public void ShowCustomerQueueManagementView(object caller, object target) { CustomerQueueManagementView view = WorkItem.Items.AddNew<CustomerQueueManagementView>(); WorkItem.Workspaces[WorkspaceNames.LaunchBarWorkspace].Show(view); WorkItem.RootWorkItem.UIExtensionSites.RegisterSite(UIExtensionSiteNames.CustomerQueueLinks, view.LinksPanel); }
在ModuleController中调用,ModuleController继承自WorkItemController
public override void Run() { ExecuteActions(); ShowDefaultView(); } private void ExecuteActions() { WorkItem.Items.AddNew<ModuleActions>(); ActionCatalog.Execute(ActionNames.ShowCustomerQueueManagementView, WorkItem, this, null); ActionCatalog.Execute(ActionNames.ShowOfficerQueueView, WorkItem, this, null); ActionCatalog.Execute(ActionNames.ServiceCustomerAction, WorkItem, this, null); ActionCatalog.Execute(ActionNames.ShowAddVisitorToQueueCommand, WorkItem, this, null); ActionCatalog.Execute(ActionNames.ShowFindCustomerCommand, WorkItem, this, null); }
服务
在SmartClientApplication中加载的服务:
- UserSelectorService,提供用户登录验证服务,在SelectUser方法中调用UserSelectionForm登录
- SimpleWinFormAuthenticationService,根据登录的用户完成系统认证,使用到了Thread.CurrentPrincipal
public void Authenticate() { IUserData user = _userSelector.SelectUser(); if (user != null) { GenericIdentity identity = new GenericIdentity(user.Name); GenericPrincipal principal = new GenericPrincipal(identity, user.Roles); Thread.CurrentPrincipal = principal; } else { throw new AuthenticationException(Resources.NoUserProvidedForAuthentication); } }
- SimpleRoleService,根据用户名得到角色
- ProfileCatalogService,演示了通过WebService获取用户的Profile的简单实现,
- WebServiceCatalogModuleInfoStore,利用ProfileCatalogService从WebService服务端取得文件字符串的功能取得在服务端定义的模块信息
- XmlStreamDependentModuleEnumerator,解析WebServiceCatalogModuleInfoService返回的Xml字符串取得模块的枚举
- DependentModuleLoaderService,模块加载服务,根据XmlStreamDependentModuleEnumerator的模块信息Load模块
- ActionCatalogService,动作集中管理服务,提供动作的注册、执行等功能
public interface IActionCatalogService { bool CanExecute(string action, WorkItem context, object caller, object target); bool CanExecute(string action); void Execute(string action, WorkItem context, object caller, object target); void RegisterSpecificCondition(string action, IActionCondition actionCondition); void RegisterGeneralCondition(IActionCondition actionCondition); void RemoveSpecificCondition(string action, IActionCondition actionCondition); void RemoveGeneralCondition(IActionCondition actionCondition); void RemoveActionImplementation(string action); void RegisterActionImplementation(string action, ActionDelegate actionDelegate); }
- WorkspaceLocatorService,查找SmartPart所在的Workspace
- EntityTranslatorService,实体翻译