SCSF Business Modules: Start Up And The ControlledWorkItem (Introduction To CAB/SCSF Part 20)
来源:互联网 发布:javascript插件是什么 编辑:程序博客网 时间:2024/05/20 06:28
Introduction
Part 19 of this series of articles discussed business modules in a Smart Client solution generated using the Smart Client Software Factory. This article continues that discussion.
The Load Method of a Business Module
As discussed in the previous article, a business module has a class called ‘Module’ which inherits from class ModuleInit. We saw in part 1 of this series of articles that this means the Load method in that class will get called at start up, provided the module has been added to the ProfileCatalog file.
The Load method of Module generated by the Smart Client Software Factory is as below:
public override void Load() { base.Load(); ControlledWorkItem<ModuleController> workItem = _rootWorkItem.WorkItems.AddNew<ControlledWorkItem<ModuleController>>(); workItem.Controller.Run(); }
As we can see, it’s creating a ControlledWorkItem class instance and adding it to the WorkItems collection of the root WorkItem. It’s then calling the Run method on the Controller property of this WorkItem.
ControlledWorkItem
ControlledWorkItem is a class that inherits directly from WorkItem. So a ControlledWorkItem is a WorkItem. The ControlledWorkItem also adds additional functionality to the WorkItem, and, crucially, it is a sealed class (which means we can’t inherit from it).
The idea here is that each business module should have a ControlledWorkItem as a root for its functionality. This is what we are creating in the Load method. In the overall WorkItem hierarchy each business module ControlledWorkItem is immediately below the root WorkItem for the entire solution.
Inheriting WorkItem to add Functionality
The ControlledWorkItem has been created to clarify the situation with regard to adding code to WorkItems. When we start using the CAB we quickly find that we need our WorkItems to be extended in various ways. They are intended to control business use cases, after all. For example we may want specific services instantiated at start up and added to the Services collection. Doing this in the WorkItem itself may seem like a sensible thing to do. Clearly the main WorkItem class is a CAB framework class, but we can inherit from it to give it this additional behaviour.
The reference implementations of both the CAB and the SCSF do this: each WorkItem inherits from the base WorkItem class and extend it to give the use case functionality. If you look at the CustomerWorkItem in the Bank Teller Reference Implementation you’ll see this.
Why Inheriting from WorkItem has been Deprecated
The difficulty with this is that our WorkItem class is acting as both a container for all the various WorkItem collections, as we have discussed before, AND as a place where all the code for a business use case goes.
This breaks the Single Responsibility principle, which is that every class should have just one responsibility in a system to avoid confusion.
As a result the Patterns and Practices team have decided it’s not ideal to have developers inherit from WorkItem and add functionality to the derived class. Instead a second class is created to contain the new code, and that class is associated with the WorkItem class by composition.
How ControlledWorkItem Addresses the Problem
This is what the ControlledWorkItem is doing. The ControlledWorkItem class itself inherits from WorkItem, but also has a member variable that references another class. The type of this class is generic (so the developer provides it), and the class is instantiated when the ControlledWorkItem is created.
So in the line of code below we are creating the ControlledWorkItem and adding it to the root WorkItem’s WorkItems collection. However we are also telling the ControlledWorkItem that its member class should be of type ModuleController, and that class will get instantiated and set up as the member variable.
ControlledWorkItem<ModuleController> workItem = _rootWorkItem.WorkItems.AddNew<ControlledWorkItem<ModuleController>>();
We are not expected to inherit from ControlledWorkItem itself. In fact we can’t because it is sealed: the Patterns and Practices team have done this deliberately to indicate that the pattern has changed. Instead we add our additional functionality for the WorkItem to the ModuleController class.
ModuleController
We can access the ModuleController instance from the ControlledWorkItem using the Controller property. We can then call a Run method on that class. This is the standard pattern that is generated by the Guidance Automation Package: note that the final line in the Load method above is:
workItem.Controller.Run();
So we can add start up code for the WorkItem into the ModuleController class in the Run routine.
The SCSF gives us a default ModuleController whenever we set up a Module, as we have seen. This has a default Run method. There isn’t any code that actually does anything in this method, but four empty methods are set up in ModuleController to indicate to us the sort of things we should be doing:
public class ModuleController : WorkItemController { public override void Run() { AddServices(); ExtendMenu(); ExtendToolStrip(); AddViews(); }...
There are also comments in these routines to describe what we should be doing inthem. To see this in more detail look in any of the ModuleController classes in the sample code.
WorkItemController Class
Note also above that our default ModuleController inherits from a class called WorkItemController, which is an abstract base class intended to be used just of these controllers. Inheriting from this ensures that we have a Run method in our derived class as there is an abstract function of this name in the base class.
The base WorkItemController also gets a reference to the associated WorkItem using our usual dependency injection pattern. This can be accessed via the WorkItem property on the WorkItemController class.
Finally the WorkItemController class has two overloaded ShowViewInWorkspace methods, which can create and show a SmartPart in a named Workspace in the WorkItem.
Obviously we don’t have to make our ModuleController inherit from WorkItemController. However, if we don’t this base class functionality will not be available.
Conclusion
This article has discussed the standard patterns generated by the Smart Client Software Factory for starting up business (and other) modules.
Part 21 of this series of articles will look briefly at foundational modules, and will also discuss the way names are handling in Smart Client Software Factory projects.
- SCSF Business Modules: Start Up And The ControlledWorkItem (Introduction To CAB/SCSF Part 20)
- Business Modules And Interfaces In The SCSF Smart Client Solution (Introduction To CAB/SCSF Part 19)
- Introduction To UIExtensionSites (Introduction To The CAB/SCSF Part 13)
- Commands In The CAB (Introduction To CAB/SCSF Part 10)
- Events In The CAB (Introduction To CAB/SCSF Part 12)
- SCSF - Part 7 Introduction to Services in the CAB
- Workspace Types (Introduction To The CAB/SCSF Part 17)
- More Detail On Workspaces And SmartParts (Introduction To The CAB/SCSF Part 16)
- Introduction To Events In The CAB (Introduction To CAB/SCSF Part 11)
- Introduction To SmartParts And Workspaces (Introduction To CAB/SCSF Part 15)
- Model-View-Presenter: Why We Need It And The Basic Pattern (Introduction To CAB/SCSF Part 23)
- Foundational Modules And Names As Constants (Intro To CAB/SCSF Part 21)
- More On UIExtensionSites (Introduction To CAB/SCSF Part 14)
- Model-View-Controller Explained (Introduction To CAB/SCSF Part 22)
- Introduction To The Smart Client Software Factory (CAB/SCSF Part 18)
- Model-View-Presenter: Variations On The Basic Pattern (Introduction To CAB/SCSF Part 24)
- Model-View-Presenter Using The Smart Client Software Factory (Introduction To CAB/SCSF Part 25)
- SCSF - Part 8 Creating and Using Services in the CAB
- 49个JQuery代码经典片段
- Windows VisualStudio 下使用glog gflags
- Android基础知识资料收集
- linux 笔记 关于struct file 结构下 private_data 数据结构的思考
- ora-12154:tns:无法解析指定的连接标识符(解决办法)
- SCSF Business Modules: Start Up And The ControlledWorkItem (Introduction To CAB/SCSF Part 20)
- 家谱(并查集)
- iOS模仿QQ的折叠
- BufferedImage操作图片笔记
- ViewDragHelper详解
- Spring MVC 框架搭建及详解
- c++内存池实现
- 钿畑的博客
- 使用AChartEngine绘制双Y轴的柱形--曲线图