2010年2月5日星期五

WCF RIA 服务 (二十一)-- Silverlight 客户端 2

客户端代码生成
当我们使用RIA Services连接中间层和表示层时,RIA Services为客户端项目生成了客户端代理类,这些类是以中间层公开的实体和操作为基础的。因为RIA Services生成了这些类,所以我们不必再复制这些中间层和表示层中的应用逻辑。因为我们对中间层所做的任何修改,在重新生成客户端项目时都会自动与表示层同步的。

生成的代码位于客户端项目的Generated_Code文件夹内。想要看到这个文件夹,必须在客户端项目的解决方案资源管理器的窗口下,选择“显示所有文件”。我们不应直接改动此文件夹内的类,因为在客户端项目重新生成时,文件会被覆盖。然而,我们可以打开生成的文件,查看里面可被客户端项目利用的代码。


生成客户端代码的算法遵循以下规则:

1. 分析所有的程序集,包括生成的,或中间层为Domain service classes,Entity classes,shared code所引用的。

2. 对每个带有EnableClientAccessAttribute属性注释的域服务,都生成一个从DomainContext类派生的类。

3. 对每个域服务类中的查询方法、命名的更新方法或调用的操作,都在域上下文类中生成一个方法。

4. 对每个域服务公开的实体类,生成一个实体代理类。

5. 拷贝标记为共享的代码到客户端项目。

下图显示了一个中间层项目生成的客户端代码


DomainService 和 DomainContext

为每个域服务生成的派生于Domaincontext的类,遵循下面的规则:

1. Domain Context类须与Domain service具有一样的命名空间。

2. domain context类包含3个构造函数:

a. 默认的构造函数,嵌入了必要的URI,使用WebDomainClient(TContract)类在http上与域服务沟通

b. 允许用户指定一个可交替的URI的构造函数。

c. 允许用户提供一个自定义实现的DomainClient的构造函数。

3. 对每个与服务类中的查询方法,在domain context中都会生成一个EntityQuery(TEntity)方法。

4. 对每个命名的更新方法(named update method)或调用的操作,在域上下文中都会生成对应的方法。

5. 在domain service中执行插入、更新、删除的公共方法,会使域上下文中的EntityContainer在生成时带有EntitySetOperations标记,这个标记指定哪个操作在客户端是允许的。

实体类和实体代理类

生成实体代理类时,应遵循如下规则:

1. 代理类应该与中间层中的实体类具有一样的名字和命名空间。

2. 实体类中所有公共成员属性都会在代理类中生成,除非某些类型或成员属性已经在客户端项目中存在。

3. 每个属性设置器都包含执行验证和通知客户属性正在改变和已经改变的代码。

4. 元数据属性是与生成的代码中的实体类连在一起的。客户端不会存在元数据类。

5. 如果可能,定制的属性会传递到代理类。详情参阅下面的内容

定制的属性

如果定制的属性在客户端项目的编译中没有出现错误,那么这个定制的属性就可以传递到代理类中。为了保证属性能被传递,应满足如下条件:

1. 在客户端提供定制的属性的类型。

2. 在定制属性中指定的所有类型,在客户端都应该提供。

3. 这个定制属性必须对它所有的成员属性公开公共设置器,或者公开一个可以设置那些没有公共设置器的成员属性的构造函数。

如果所需的定制属性没有传递到客户端,我们可能需要在客户端中添加一个程序集引用。

共享代码

当在中间层和表示层之间共享代码时,代码被原封不动的拷到客户端项目中。通过命名文件为*.shared.cs来共享文件。

避免成员重复

当生成实体代理类时,有可能在客户端项目中已经定义了相同的类型和成员。我们可能已经在共享代码或只存在于客户端项目中的代码中定义了成员。RIA Service会在生成代理类之前检查已经存在的成员。所有已经存在的成员都不在代理类中生成。

WCF RIA 服务 (二十)-- Silverlight 客户端

Silverlight客户端
使用WCF RIA Services,我们可以创建一个当数据交互时知道中间层应用逻辑的Silverlight客户端。还可以对可见的和可编辑的数据提供用户接口,来在提交数据修改之前应用验证规则。我们的SL控件将会使用从中间层代码自动生成类。次章节介绍SL客户端如何使用domain context, 如何与数据一起工作,以及如何自定义生成的代码.
使用DomainContext
在中间层项目中会对每个domain service都生成一个DomainContext类来公开实体对象。在域上下文中包含着查询和修改等方法,这些方法与在域服务中对应的域操作进行沟通。当我们在SL应用程序中调用域上下文类上的一个查询方法时,这个查询方法会调用返回所需数据的域服务上的对应方法。这些域上下文上的方法都是异步执行的,所以在装载数据的时候,用户界面不会被锁定。
呈现和修改数据
我们使用SL控件,例如DataGrid控件,来呈现通过域上下文检索到的数据。我们把控件和查询结果绑定在一起。
我们也可以通过SL控件更新、插入和修改数据,当这些操作在域服务中公开时。当我们调用域服务上的数据修改操作时,中间层逻辑会处理来自SL客户端的数据,以确保商业规则应用到了修改操作上。
我们还可以使用DomainDataSource控件与来自域服务的数据交互。DomainDataSource控件允许我们使用声明语法来指定分页、排序、分组、和过滤数据。
自定义生成的代码
要想自定义生成的代码,我们不应该修改Generated_Code文件夹下的文件。因为当客户端项目重新生成时,这些文件将会被覆盖。反之,通过提供在域上下文中的局部方法和实体代理类,RIA Services允许我们为客户端自定义生成的代码。通过这些局部方法,我们可以在客户端添加计算性能,或添加当特定动作执行时需要的自定义逻辑。只有在我们已经实施了局部方法的情况下,生成的局部方法在会在运行时被调用。

2010年2月4日星期四

WCF RIA 服务 (十九)-- 共享代码 2

如何:通过源文件来共享代码

我们可以通过源文件来在中间层和表示层之间共享代码。当在中间层修改源文件,并重新生成应用程序时,在客户端会自动同步更新了的代码。当代码不属于domain Service或实体类,而且我们不想代码经历客户端代码生成步骤时,我们把代码放在共享的源文件中。

通过使用共享命名规范或文件链接来共享源文件。下面示例使用这两种方法来共享源文件。

使用共享命名规范


  1. 在中间层的解决方案资源管理器中,创建想放置共享文件的目录结构。这个目录结构将会在客户端的Generated_Code文件夹内重新创建。

  2. 在目录结构中添加一个C#文件。

  3. 使用共享命名规范。

  4. 在共享文件中添加代码。

  5. 生成解决方案。

  6. 在客户端项目中,打开Generated_Code文件夹,注意到代码文件已经被拷贝了。



  7. 打开代码文件,注意到在编译期间没有对代码做改动。

使用文件链接



  1. 在中间层项目中,添加一个新的代码文件。

  2. 在文件中添加代码。

  3. 在表示层项目中,右键点击项目。选择添加->已存在项

  4. 选择刚添加到中间层项目中的代码文件。

  5. 在添加按钮上,点击下拉菜单并选择Add As Link。

当编译这个项目时,会返现没有文件被拷贝到客户端项目中。相反,添加了一个文件引用。

WCF RIA 服务 (十八)-- 共享代码 1

共享代码
WCF RIA Services允许我们编写在中间层和表示层之间共享的应用逻辑。可以共享源文件或程序集中的代码。和在客户端代码生成主题中描述的自动代码生成方法不同,共享代码在编译时时不能改动的。相反,代码在层间是逐字地拷贝或共享的。

共享源文件

可以在中间层添加源文件,然后明确指定这些文件在表示层中共享。有两种方法来在层之间共享源文件。第一种方式是根据命名规范来命名源文件:*.shared.cs或*.shared.vb。第二种方法是使用VS中的文件链接特性。

共享命名规范

当对源文件使用共享命名规范(*.shared.cs)时,对共享的源代码文件实施了"push"模型。在编译时,源文件将会从中间层拷贝到客户端。只有在服务端和客户端存在RIA Services 连接时,共享命名规范才会对源文件起作用。



共享命名规范有以下优点

1.内置的支持:不需要程序员来保证共享文件同步。

2.透明性:名字清楚指明了文件想要共享。

3.自我维护:如果添加了一个共享文件,当解决方案编译时,所有与这个中间层联系的客户端项目都会自动更新。

4.易理解的调试经验:可以在服务端或客户端的文件中设置断点。

但它也有如下缺点:

1.新概念: 程序员必须了解共享命名规范。

2.文件被宝贝:共享文件是物理性地拷贝到项目中的,就可能造成程序员编辑了拷贝的文件,却在下次编译时丢失了所做的更改(因为源文件没有更改)。

链接文件

Linked files是VS中已有的特性,并不是只针对RIA Services的。在项目之间可以存在RIA Services链接,但不必使用链接文件。当使用链接文件方法时,就对共享源文件实施了"pull"模型。在客户端没有文件的拷贝。相反,客户端引用服务端的文件。



我们还可以让服务端和客户端都连接到其他项目中的文件。



链接文件方式有以下优点:

1. 已存在的VS特性:不必学习新的规范。

2. 文件不是拷贝的:文件仅存在服务端项目中。因此不可以修改拷贝的文件,在下次解决方案编译时也不会丢失更改。

链接文件方式的缺点:

1. 需要用户明确的指令 : 必须链接每个共享文件。

2. 不能自我维护 :当添加或移除共享文件时,客户端需要更新。

3. 缺乏透明性 : 程序员需要检查文件来确定哪个文件是共享的。

4. 不好的调试体验 : 不容易确定哪个层引起了中断。

共享程序集 - Shared Assemblies

与在项目中共享源文件相反,我们可以报代码编译到类库中,然后再通过程序集引用来共享这个类库。使用WCF RIA Services 类库来确保程序集是兼容的。

下面的图示例了一个使用WCF RIA Services类库的n层结构的应用程序如何共享代码。中间层和客户层对类库使用程序集引用。