信息化基础建设 持续改进框架
持续改进框架
1. WCF Operation Name
2. SQL=>ORM语句生成工具
3. 数据库注释内容的导出
4. 语法高亮控件
5. 标准窗体Login,Splash,About
6. C#,VB语言相互转化
7. 组件通讯方式
8. 定制Enterprise Library
WCF Operation Name
WCF是一套通讯技术框架,不能免俗,于是将框架代码的通讯部分升级到WCF
如果接口文件,在C#中是这样写的
[ServiceContract]
public interface IMath
{
[OperationContract]
void Add(int a int b);
[OperationContract]
void Add(double a, double b)
}
很不幸,这样的代码不能运行,因为WCF不允许方法overload. 解决方法是给它加上Name
[ServiceContract]
public interface IMath
{
[OperationContract(Name=”AddInt”)]
void Add(int a int b);
[OperationContract(Name=”AddDouble”)]
void Add(double a, double b)
}
这样就可以解决问题,但是,现在是升级,有成千上万个接口和操作需要加Name别名,手动敲Name难免会出错
看下图,一个接口中,就已经有大量的方法已经overload
于是想到用C# Parser来,自动完成升级工作。分析接口文件的内容,重新生成一遍带Name的Operation,未解决。
用键盘敲Name的方式又容易出错,上面的overload的方法签名,主要是参数不一样,于是做一个小工具,输入方法的参数,自动生成Name属性,问题解决。
左边的窗格中,输入参数的信息,把窗体的KeyPreview设为True,接收快捷键F5用于转换,右边是根据方法的参数生成的Name签名,并且已经调用Clipboard.SetText,现在要做的就是到C#接口文件,Paste.
效果如下
这样的做法,既不容易出错,又达到标准化和统一,所有的代码都看起来像是机器生成的一样。
SQL=>ORM语句生成工具
在Milestone 3中,要逐步考虑框架被最终用户的熟悉程度,以进行快速开发。 .NET开发人员熟悉ADO.NET,Enterprise Library,或是NHibernate,还有一项,最熟悉通用的技术:SQL。 要使用户能快速入门框架,读写数据库,熟练ORM操作,充分发挥已经掌握的技能是实现快速开发的前提。请看下面的SQL与ORM语句对照表
我的目的是要实现一个工具,实现SQL与ORM的互相转化,忘记ORM的存在,帮忙程序员快速开发。
在项目的开始,就已经开发了大量的工具程序,以检索SQL与ORM的对应关系,比如
1. 数据库名与实现名对应查询
2. 表字段名称与属性对应查询
3. 实体间的关系对应查询
在查询分析器中写好SQL语句,拷贝到Query Builder窗体中,运行转换
如图中所示,上窗格中的SQL语句,已经被转换为ORM语句,显示在下面的窗格中。
对比上面的SQL与ORM语句对照表,为何两种结果不同?
解释:SQL与ORM语句对照表中显示的是基础的ORM操作,可以独立运行的,上图中用软件转换的结果,是实际项目中最需要的语句。举例,在做BOM的物料时,通常选择物料编号后,自动带出物料名称,物料组别。再请看程序转换的ORM语句,就是我们最需要的代码,把它放到项目文件中,添加BOM物料名称,看起来是这样
IItemManager itemManager = ClientProxyFactory.CreateProxyInstance<IItemManager>();
ExcludeIncludeFieldsList fieldlist = new ExcludeIncludeFieldsList(false);
fieldlist.Add(ItemFields.ItemNo);
fieldlist.Add(ItemFields.Description);
fieldlist.Add(ItemFields.ItemGroup);
ItemEntity item = itemManager.GetItem(this.PartItemNo, null, fieldlist);
轻松的实现了这个功能的99%的代码输入量,工具的目的在于此处。
数据库注释内容的导出
在改进的智能提示支持一节中,我们已经实现了数据库的注释工具,这一节来实现,将注释内容导出为SQL,放到其他的数据库中运行,以达到简化注释的目的.
这次专注于实现Export Description,把注释导出为SQL语句.
大部分的技巧的秘密都在sp_addextendedproperty,例如
sp_addextendedproperty 'Description', '目录编号', 'schema', 'dbo', 'table', 'Categories', 'column', 'CategoryID'
程序的目的,也只是将上面的信息检索出来,存为xml文件,然后选择一个数据库名,再把信息写入到注释内容。
SQL Server 2000提供了三个系统存储过程和一个函数用于操作扩展属性 。它们分别是:
•sp_addextendedproperty (将新扩展属性添加到数据库对象中。)
•sp_updateextendedproperty (更新现有扩展属性的值。)
•sp_dropextendedproperty (除去现有的扩展属性。)
•fn_listextendedproperty (列出扩展属性)
语法高亮控件
在做代码生成工具时,曾经用过ICSharpCode.TextEditor,效果不错,如下图
后来发现一个问题,无论内容的文字是否超过一屏,它都会显示横向的scrollbar. 而且一直找不到办法不显示。
后来,查阅了其他的大量的.NET 语法高亮控件,基本上都有scrollbar,不管文字是否超出屏幕,始终有些不满意。
Codeproject有一篇文章讲解FastColoredTextBox,这个控件,可以解决横向scrollbar的问题,效果不错
基本的功能都具备,最好的一点是,没有横向的scrollbar.
标准窗体Login,Splash,About
请看EPN应用程序的三个窗体
Login窗体
登陆之后的,splash窗体
菜单Help中的About窗体
FormStyle=None, Login窗体的AcceptButton=btnLogin,这三个窗体的背景,是同一幅图片,以达到尺寸相同。
一个软件的窗口,通常是看这三个标准的窗体,字体和字号,尺寸是否相同,风格是否一致。
C#,VB语言相互转化
实现VB与C#语言的相互转化,如图
详细内容,请查看《信息化基础建设 多种编程语言开发》中的说明。
三种组件通讯方式local,Remoting,WCF
在客户端代码没有任何改变的情况下,EPN框架可以灵活的在下面三种通讯方式中切换
public enum CommunicationPlatform
{
Local,
Remoting,
WCF,
}
Local模式是直接以反射的方式,调用接口的实现,
Remoting以.NET Remoting方式,实现客户端与服务器的通信
WCF,以WCF技术,实现客户端与服务器的通信
举例,以ClientProxy为客户端代理接口
public interface IMath
{
void Add(int a int b);
void Add(double a, double b)
}
Local模式下,ClientProxy会直接去找IMath的一种实现,来返回给客户端调用
Remoting模式,ClientProxy以请求的服务名称和配置,构建Remoting客户端代码,向服务器发送请求,WCF模式也是这种工作方式。
Remoting升级到WCF一个大的问题是,overload方法不被支持,除非加Name属性,客户端也要重新生成proxy.
定制Enterprise Library
Enterprise Library无疑已经是很好的ADO.NET最佳实践,在EPN的框架代码,将大量使用Enterprise Library来访问数据库。实际使用时,必须在稍微做一些配置,添加dataConfiguration,添加connectionStrings,如下的代码所示
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data" />
<connectionStrings>
<add
name="Service_Dflt"
providerName="System.Data.SqlClient"
connectionString="server=(local)\SQLEXPRESS;database=Northwind;Integrated Security=true" />
在一个已经高度封装的开发库中,这一点不利。因为数据库的连接字符串可能已经创建,也可能被加密存在数据库中,开发人员不需要知道数据库在哪里,如何写Connection,他只需要知道,传入SQL命令,得到结果
Database m_commonDb;
string SQLGet_ShiftCodeList = @"select * from dbo.Customers ";
DataSet dsShiftCode = m_commonDb.ExecuteDataSet(cmd);
为了达到这个目的,请打开文件DatabaseConfigurationView.cs, 修改方法GetConnectionStringSettings
public ConnectionStringSettings GetConnectionStringSettings(string name)
{
//ValidateInstanceName(name);
ConnectionStringSettings connectionStringSettings;
ConfigurationSection configSection = configurationSource.GetSection("connectionStrings");
if ((configSection != null) && (configSection is ConnectionStringsSection))
{
ConnectionStringsSection connectionStringsSection = configSection as ConnectionStringsSection;
connectionStringSettings = connectionStringsSection.ConnectionStrings[name];
}
else
connectionStringSettings = ConfigurationManager.ConnectionStrings[name];
//By James
if (connectionStringSettings == null || String.IsNullOrEmpty(connectionStringSettings.ConnectionString))
{
connectionStringSettings = new ConnectionStringSettings(name, EnterpriseLibraryShared.ConnectonString, "System.Data.SqlClient");
}
//END
ValidateConnectionStringSettings(name, connectionStringSettings);
return connectionStringSettings;
}
如代码所示,By James是我修改的地方,我添加了一个类型EnterpriseLibraryShared来存放连接字符串,在系统启动时,调用下面的语句初试化连接
EnterpriseLibraryShared.ConnectonString = "server=(local);database=Northwind;uid=sa;pwd=holiday";
如果应用程序需要写日志Log,请直接对它进行扩展,这样写出的代码的可扩展性非常好。