信息化基础建设 持续改进框架

持续改进框架

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

clip_image002

于是想到用C# Parser来,自动完成升级工作。分析接口文件的内容,重新生成一遍带Name的Operation,未解决。

用键盘敲Name的方式又容易出错,上面的overload的方法签名,主要是参数不一样,于是做一个小工具,输入方法的参数,自动生成Name属性,问题解决。

clip_image004

左边的窗格中,输入参数的信息,把窗体的KeyPreview设为True,接收快捷键F5用于转换,右边是根据方法的参数生成的Name签名,并且已经调用Clipboard.SetText,现在要做的就是到C#接口文件,Paste.

效果如下

clip_image006

这样的做法,既不容易出错,又达到标准化和统一,所有的代码都看起来像是机器生成的一样。

 

SQL=>ORM语句生成工具

在Milestone 3中,要逐步考虑框架被最终用户的熟悉程度,以进行快速开发。 .NET开发人员熟悉ADO.NET,Enterprise Library,或是NHibernate,还有一项,最熟悉通用的技术:SQL。 要使用户能快速入门框架,读写数据库,熟练ORM操作,充分发挥已经掌握的技能是实现快速开发的前提。请看下面的SQL与ORM语句对照表

clip_image008

我的目的是要实现一个工具,实现SQL与ORM的互相转化,忘记ORM的存在,帮忙程序员快速开发。

在项目的开始,就已经开发了大量的工具程序,以检索SQL与ORM的对应关系,比如

1. 数据库名与实现名对应查询

2. 表字段名称与属性对应查询

3. 实体间的关系对应查询

在查询分析器中写好SQL语句,拷贝到Query Builder窗体中,运行转换

clip_image010

如图中所示,上窗格中的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,放到其他的数据库中运行,以达到简化注释的目的.

clip_image012

这次专注于实现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,效果不错,如下图

clip_image014

后来发现一个问题,无论内容的文字是否超过一屏,它都会显示横向的scrollbar. 而且一直找不到办法不显示。

后来,查阅了其他的大量的.NET 语法高亮控件,基本上都有scrollbar,不管文字是否超出屏幕,始终有些不满意。

Codeproject有一篇文章讲解FastColoredTextBox,这个控件,可以解决横向scrollbar的问题,效果不错

clip_image016

基本的功能都具备,最好的一点是,没有横向的scrollbar.

 

标准窗体Login,Splash,About

请看EPN应用程序的三个窗体

Login窗体

clip_image018

登陆之后的,splash窗体

clip_image020

菜单Help中的About窗体

clip_image022

FormStyle=None, Login窗体的AcceptButton=btnLogin,这三个窗体的背景,是同一幅图片,以达到尺寸相同。

一个软件的窗口,通常是看这三个标准的窗体,字体和字号,尺寸是否相同,风格是否一致。

 

C#,VB语言相互转化

实现VB与C#语言的相互转化,如图

clip_image024

详细内容,请查看《信息化基础建设 多种编程语言开发》中的说明。

 

三种组件通讯方式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,请直接对它进行扩展,这样写出的代码的可扩展性非常好。

posted @ 2011-06-20 08:51  信息化建设  阅读(2201)  评论(0编辑  收藏  举报