Foundational Modules And Names As Constants (Intro To CAB/SCSF Part 21)

本文探讨了智能客户端软件工厂中的基础模块,并介绍了如何通过继承层次结构使用常量文件夹来统一命名,避免运行时错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Introduction

Part 19 and part 20 of this series of articles looked at business modules in the Smart Client Software Factory.

This article looks at foundational modules briefly, and also discusses the pattern for handling names in the SCSF.

Foundational Modules

In part 18 of this series of articles we saw how we can use one of the Guidance Automation Packages to add a business module to our solution. There’s also a Guidance Automation package that lets us add a ‘foundational module’ to our solution. This is on the same submenu as the ‘Add Business Module (C#)’ option we saw above. So to add a foundational module to our solution right-click the solution folder in Solution Explorer, select Smart Client Factory/Add Foundational Module (C#) and then click through the two setup screens.

A foundational module is identical to a business module except that it does not have a root WorkItem. This is because it is intended to contain supporting functionality rather than core business functionality for our solution. It is not expected that we will create business objects and add them to the various WorkItem collections.

So we are expected to create fairly generic services and supporting code in foundational modules, rather than business code. Of course we could do this in the Infrastructure projects mentioned in part 18, but a foundational module allows us to separate out supporting code into its own CAB module.

Note that we can create an interface component, ‘Module.Interface’, for our foundational module in exactly the same way as for a business module. This allows other components in the solution to use the module’s functionality without referencing it directly, as described above.

Constants Folders

In our examples above we have seen several Constants folders being set up. The main Smart Client solution has a Constants folder in both the Infrastructure.Interface component and the Shell component. Both the foundational modules and the business modules have Constants folders in both their main Module components and their Module.Interface components.

The Constants folders all contain four classes: CommandNames, EventTopicNames, UIExtensionSiteNames, and WorkspaceNames. In the Constants folders mentioned above most of these are empty by default, although Infrastructure.Interface has some constants set up in its classes.

The important thing to notice here is that the individual classes with the same name are arranged in an inheritance hierarchy. So if we have a business module in our Smart Client solution (as in the code example we have already seen) then CommandNames in the Module itself inherits from CommandNames in Module.Interface, which in turn inherits from CommandNames in Infrastructure.Interface. CommandNames in Shell also inherits from Infrastructure.Interface.

The reason these classes exist is to allow us to use standard constants throughout our solution for names, rather than having to use strings. The inheritance hierarchy lets us define these constants at the correct level in the hierarchy, but then to use any of them very simply by just accessing the class at the level the code is at.

The reason we don’t want to use strings in our code as names is they are prone to error in entry (since we can’t use intellisense) and can’t be checked by the compiler at compile-time: if we enter a string name wrongly we will get a run-time error. If we use constants to represent these strings we avoid both of these problems.

This will be clearer in an example:

We might call a Workspace on our Shell form “LeftWorkspace” when we add it to the Workspaces collection of the root WorkItem. Elsewhere in the code we may want to retrieve that workspace and interact with it, for example to call the Workspace’s Show method to display a SmartPart. Normally to do this the syntax would be, for example:

_rootWorkItem.Workspaces["LeftWorkspace"].Show(control);

The obvious difficulty with this is that we are just entering the name “LeftWorkspace” as a string, which is prone to error and the compiler can’t check.

So we add the code below to the WorkspaceNames class in Infrastructure.Interface. We add it to the Infrastructure.Interface component because the Workspace is being defined in the Infrastructure part of the solution, but we want it to be available outside of that:

public const string LeftWorkspace = "LeftWorkspace";

Now suppose we want to use this Workspace name in code in a business module. The WorkspaceNames class in the business module inherits from the WorkspaceNames class in Infrastructure.Interface, and hence the constant is available in that class. All we need do is reference that class to access any Workspace name. So we just import the appropriate namespace:

using SmartClientDevelopmentSolution.Module1.Constants;

And then we can do:

_rootWorkItem.Workspaces[WorkspaceNames.LeftWorkspace].Show(control);

Now intellisense is available when we enter the ‘LeftWorkspace’ name, and the compiler can check that what we have entered is correct.

Note that if we have a Workspace name defined just for the module (say ‘LocalWorkspace’) we can still just do WorkspaceNames.LocalWorkspace to access it.

So these Constants folders provide us with an easy way of using named constants for items in the WorkItem hierarchy throughout our code.

资源下载链接为: https://pan.quark.cn/s/f989b9092fc5 HttpServletRequestWrapper 是 Java Servlet API 中的一个工具类,位于 javax.servlet.http 包中,用于对 HttpServletRequest 对象进行封装,从而在 Web 应用中实现对 HTTP 请求的拦截、修改或增强等功能。通过继承该类并覆盖相关方法,开发者可以轻松地自定义请求处理逻辑,例如修改请求参数、添加请求头、记录日志等。 参数过滤:在请求到达处理器之前,可以对请求参数进行检查或修改,例如去除 URL 编码、过滤敏感信息或进行安全检查。 请求头操作:可以修改或添加请求头,比如设置自定义的 Content-Type 或添加认证信息。 请求属性扩展:在原始请求的基础上添加自定义属性,供后续处理使用。 日志记录:在处理请求前记录请求信息,如 URL、参数、请求头等,便于调试和监控。 跨域支持:通过添加 CORS 相关的响应头,允许来自不同源的请求。 HttpServletRequestWrapper 通过继承 HttpServletRequest 接口并重写其方法来实现功能。开发者可以在重写的方法中添加自定义逻辑,例如在获取参数时进行过滤,或在读取请求体时进行解密。当调用这些方法时,实际上是调用了包装器中的方法,从而实现了对原始请求的修改或增强。 以下是一个简单的示例,展示如何创建一个用于过滤请求参数的包装器: 在 doFilter 方法中,可以使用 CustomRequestWrapper 包装原始请求: 这样,每当调用 getParameterValues 方法时,都会先经过自定义的过滤逻辑。 HttpServletRequestWrapper 是 Java Web 开发中一个强大的工具,它提供了灵活的扩展性,允许开发者
本资源文件包含LeetCode算法题第1至100题的Java完整源码,涉及题目如下:1.两数之和;2.两数相加;3.无重复字符的最长子串;4.寻找两个正序数组的中位数;5.最长回文子串;6.Z字形变换;7.整数反转;8.字符串转换整数(atoi);9.回文数;10.正则表达式匹配;11.盛最多水的容器;12.整数转罗马数字;13.罗马数字转整数;14.最长公共前缀;15.三数之和;16.最接近的三数之和;17.电话号码的字母组合;18.四数之和;19.删除链表的倒数第N个结点;20.有效的括号;21.合并两个有序链表;22.括号生成;23.合并K个升序链表;24.两两交换链表中的节点;25.K个一组翻转链表;26.删除有序数组中的重复项;27.移除元素;28.找出字符串中第一个匹配项的下标;29.两数相除;30.串联所有单词的子串;31.下一个排列;32.最长有效括号;33.搜索旋转排序数组;34.在排序数组中查找元素的第一个和最后一个位置;35.搜索插入位置;36.有效的数独;37.解数独;38.外观数列;39.组合总和;40.组合总和II;41.缺失的第一个正数;42.接雨水;43.字符串相乘;44.通配符匹配;45.跳跃游戏II;46.全排列;47.全排列II;48.旋转图像;49.字母异位词分组;50.Pow(x,n);51.N皇后;52.N皇后II;53.最大子数组和;54.螺旋矩阵;55.跳跃游戏;56.合并区间;57.插入区间;58.最后一个单词的长度;59.螺旋矩阵II;60.排列序列;61.旋转链表;62.不同路径;63.不同路径II;64.最小路径和;65.有效数字;66.加一;67.二进制求和;68.文本左右对齐;69.x的平方根;70.爬楼梯;71.简化路径;72.编辑距离;73.矩阵置零;74.搜索二维矩阵;75.颜色分类.............
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值