承蒙4/25上海俱乐部活动组织团队邀请,本人有幸将在本次活动中和大家分享一下“集中化WCF服务配置管理”方面的一些探索。为了让大家对活动当天我讲的话题提前有一个更直观的了解,在这里提前介绍一下到时我会演示的示例程序。
本示例程序具体演示如下内容:
1) 基于SQL Server数据库的集中化WCF服务配置管理;
2) 集中化ConnectingString管理;
3) 集中化AppVariable管理;
4) 基于集中化配置管理的WCF ServiceHostFactory和WCF ServiceLocator;
5) 基于集中化配置管理的跨WCF的LINQ Style分页、排序查询及DataSource控件的使用;
6) 整合本地ServiceLocator的WCF服务发布和消费;
下载地址(请使用SVN客户端下载):
http://nintegrate.googlecode.com/svn/trunk/
安装说明:
请先使用SVN客户端下载所有代码,然后根据samples/setup目录中的readme.txt初始化配置数据库并打开示例的solution。要运行本示例,您需要至少安装了IIS6,VS2008和SQL Server 2005或2008或Express。如果要运行Net.Tcp Binding的演示,需要IIS7。
示例工程:
本示例程序由下面四个C#工程项目组成:
1. SimpleServiceContracts - 定义了ServiceContracts和DataContracts
2. SimpleServiceImpls - 包含了ServiceContracts的实现类
3. SimpleServiceProvider – 服务发布Web程序
4. SimpleServiceConsumer - 服务消费Web程序
这四个示例工程又分别依赖于由NIntegrate, NIntegrate.Query, NIntegrate.Query.Command和NIntegrate.Web这四个工程组成的名为NIntegrate的基于WCF和集中化配置的SOA框架(关于这个框架的更多内容,Teddy的博客以后会有更多介绍,这里让我们还是先关注示例程序本身)。
SimpleServiceProvider程序
本程序使用IIS发布了两个WCF服务QueryService.svc和SimpleService.svc。这两个.svc文件的内容如下:
QueryService.svc - NIntegrate查询服务,由NIntegrate内置实现
SimpleService.svc - 一个简单的SayHello服务,用于演示集中化配置的多Binding,多Endpoint的WCF服务发布和消费
这里值得注意的有两点:
1. 这两个服务的Service指定的是服务的ServiceContract接口类型而非服务的具体实现类。
2. 这两个服务通过由NIntegrate实现的WcfServiceHostFactory自动通过指定的ServiceContract接口类型和基于SQL Server的集中化配置数据库创建相应的ServiceHost,并发布服务。
解析:
WcfServiceHostFactory在内部是如何通过指定的ServiceContract接口类型找到具体的实现类的呢?是通过一个可在Web.config中配置的本地ServiceLocator实现的。NIntegrate内置实现了一个基于SQL Server数据库集中化配置的AppVariableServiceLocator,并提供了方便的接口可以和第三方的ServiceLocator,如Unity,Castle这样的IoC容器进行整合来自动定位接口的实现。在本示例中,ServiceContract接口类型对应的服务实现类,是通过数据库中的AppVariable表进行映射,并使用AppVariableServiceLocator类进行定位的。
在SimpleServiceProvider的Web.config中,只需要设置一个AppCode和一个ConnectionString,无需任何WCF配置信息:
2 < appSettings >
3 < add key ="NIntegrate.Configuration.AppCode" value ="SP_SSP" />
4 <!-- To set service locator wrapper for external IoC container here, by default, the build-in AppVariableServiceLocator is used. -->
5 <!-- <add key="NIntegrate.ExternalServiceLocator" value="NIntegrate.AppVariableServiceLocator, NIntegrate, Version=0.5.0.1, Culture=neutral, PublicKeyToken=e2b9e2165dbdd5e6"/> -->
6 </ appSettings >
7 < connectionStrings >
8 < add name ="NIntegrate.Configuration" connectionString ="Data Source=vista;Initial Catalog=NIntegrateDemo;Persist Security Info=True;User ID=nbear;Password=nbear" providerName ="System.Data.SqlClient" />
9 </ connectionStrings >
10 …
SimpleServiceConsumer程序
本程序也是一个部署在IIS下的Web程序,它只包含一个Default.aspx页面和一个Web.config文件。
他的Web.config和SimpleServiceProvider的Web.config一样,只需要设置一个AppCode和一个ConnectringString:
2 < appSettings >
3 < add key ="NIntegrate.Configuration.AppCode" value ="SP_SSC" />
4 </ appSettings >
5 < connectionStrings >
6 < add name ="NIntegrate.Configuration" connectionString ="Data Source=vista;Initial Catalog=NIntegrateDemo;Persist Security Info=True;User ID=nbear;Password=nbear"
7 providerName ="System.Data.SqlClient" />
8 </ connectionStrings >
9 …
他的Default.aspx页面则演示了QueryService.svc和SimpleService.svc这两个Service的使用。运行Default.aspx页面的界面如下:
从界面可以看到,这里有几个GridView可以排序和编辑QueryService和SimpleService的Binding和Endpoint,他们都是通过使用由NIntegrate提供的QueryDataSource控件基于QueryService.svc实现的。最后一行是SimpleService.svc的调用的输出和当前使用的WCF Binding类型。
当前,QueryService和SimpleService都使用数据库中配置的“Sample - Shared Binding”这个Binding运行的,我们可以直接在GridView中修改Binding的类型和配置信息。修改Binding后,需要recycle IIS中的AppPool使新的配置生效。(注意,只有IIS7支持修改成非HTTP的Binding,并且要自己在IIS中启用相应的net.tcp或net.pipe Binding支持)。
SimpleService有第二个名为“SimpleServiceDemo Binding 2”的NetTcpBinding,如果您使用的是IIS7,并且已经启用了IIS中的net.tcp Binding,可以点击Enable将它激活。recycle IIS中的AppPool并重行运行 Default.aspx的话,您将看到,最后一行的Binding Type变成“NetTcpBinding”。也就是说,如果一个Service有多个激活状态的不同类型的Endpoint,NIntegrate提供的ServiceManager会保证最优的Binding被使用。例如,这里SimpleService有WSHttp和NetTcp这两个Binding,当然NetTcp是最优的。更进一步。假如,这里还配置了本地ServiceLocator,并为SimpleService指定了对应的实现类,那么,您也可以猜到,“更优”的本地Service实现会被使用,而不会走WCF通道。
QueryDataSource控件又是如何通过QueryService.svc实现对Service, Binding和Endpoint这些配置信息的呈现、排序和修改的呢?事实上,QueryService提供的查询语法不仅支持简单的CRUD,还支持LINQ Style的查询语言,多种数据库支持,数据库特有的函数扩展和分页排序,并且查询语言可以跨WCF和COM兼容(也就是说,可以在非.NET应用程序如ASP中使用同样的LINQ Style查询语言访问WCF发布的服务远程进行同样的分页排序查询)。这里容我卖个关子,就不多介绍了。大家可以选择自己看代码(包括NIntegrate核心类库和本示例都是基于BSD协议公开全部源代码的),来参加俱乐部活动和Teddy一起探讨或者等Teddy的博客将来专门的专题来介绍。
好了就先介绍这么多了。有任何意见和建议欢迎通过各种渠道和Teddy交流。如果您来参加4/25的活动,当然更欢迎了。不过,我知道很多朋友周末打算去看上海车展的,没关系,顶顶这个帖子我也知足了。
//我是结尾符