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会在生成代理类之前检查已经存在的成员。所有已经存在的成员都不在代理类中生成。

没有评论:

发表评论