域服务
域服务是封装 WCF RIA Services 应用程序业务逻辑的 Windows Communication Foundation (WCF) 服务。域服务以服务层形式公开一组相关操作。定义域服务时,请指定通过域服务允许的数据操作。
设计域服务时,应将域服务视为希望用户在应用程序中执行的一组相关任务。通常,此类任务会涉及少量密切相关的实体。例如,在费用报告应用程序中,您可以公开费用报告、行项目和详细信息所对应的实体,然后将帐户和付款的实体放在单独的域服务中。
域服务及其数据源
DomainService 类是用作域服务的所有类的基类。若要创建绑定到自定义数据对象的域服务,请创建一个直接派生自 DomainService 的类。但如果您的域服务绑定了 ADO.NET 实体模型或公开了指向 SQL 数据库的 LINK,则还存在派生自您改用的 DomainService 的特殊抽象类。
若要创建绑定到 ADO.NET 实体模型的域服务,请创建一个派生自 LinqToEntitiesDomainService 的类。RIA Services 提供了 LinqToEntitiesDomainService 类。
若要在应用程序中创建公开 LINQ to SQL 类的域服务,请创建一个派生自 LinqToSqlDomainService 的类。RIA Services 工具包中提供了此类。若要使用此类在应用程序中创建公开 LINQ to SQL 类的域服务,则必须下载 RIA Services 工具包。
在使用**“添加新的域服务类”**对话框创建域服务时,创建的域服务的类型将基于公开的实体。
域服务类必须用 EnableClientAccessAttribute 特性进行标记才能使服务可用于客户端项目。在**“添加新的域服务类”对话框中选中“启用客户端访问”**复选框时,EnableClientAccessAttribute 特性自动应用于域服务。当 EnableClientAccessAttribute 特性应用于域服务时,RIA Services 将为客户端项目生成对应的类。例如,在将 EnableClientAccessAttribute 特性应用于名为 HRService
的域服务(它公开了名为 Employee
的实体)时,RIA Services 将在客户端项目中生成名为 HRContext
的域上下文,并生成客户端版本的 Employee
实体。
WCF 和域服务
作为一项 Windows Communication Foundation (WCF) 服务,域服务是基于 WCF 概念构建的。域服务保留了以下内容:
WCF 服务的标准用法
现有 WCF 编程模型构造,如操作协定、操作行为和服务行为
标准 WCF 自定义功能,如绑定配置、行为配置和管理基础结构
域上下文通过使用 WCF ChannelFactory 与 RIA Services 域服务进行通信,以便创建一个通道,并向该通道传递一个已从域服务生成的服务协定。
默认情况下,仅为域服务启用二进制终结点。不需要其他配置即可使用二进制终结点。若要使用其他终结点(如 OData、JSON、SOAP 或自定义主机),您必须在 Web.config 文件中注册终结点工厂,如下所示:
<configSections>
<sectionGroup name="system.serviceModel">
<section name="domainServices" type="System.ServiceModel.DomainServices.Hosting.DomainServicesSection, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowDefinition="MachineToApplication" requirePermission="false" />
</sectionGroup>
</configSections>
<system.serviceModel>
<domainServices>
<endpoints>
<add name="json" type="Microsoft.ServiceModel.DomainService.Hosting.JsonEndpointFactory, Microsoft.ServiceModel.DomainService.Hosting" />
</endpoints>
</domainServices>
<system.serviceModel>
System.ServiceModel.DomainServices.Hosting 命名空间包含 RIA Services 中支持的终结点。Microsoft.ServiceModel.DomainServices.Hosting 命名空间包含 RIA Services 工具包支持的终结点,如前面的示例中所示的 JsonEndpointFactory。若要创建自定义终结点,您必须创建一个派生自 DomainServiceEndpointFactory 类的类,并重写 CreateEndpoints 方法。
数据操作
您将用于执行要公开的数据操作的方法添加到域服务。例如,可以添加执行以下操作的方法:
Query
Update
Insert
Delete
还可以添加更复杂的操作,例如:
Invoke:用于实现在没有跟踪或延迟执行的情况下需执行的操作。此方法仅用于非实体数据,且只能在不能改用查询、更新、插入或删除操作时使用。
Named Update:用于实现不属于简单修改操作的自定义操作。
在公开域服务时,将在域上下文中生成 EntitySet 对象,该域上下文具有指示允许从客户端执行的操作(插入、更新或删除)的属性。可以通过修改实体集合,然后调用 SubmitChanges 方法来执行数据修改。
在绝大多数方案中,您都应使用查询操作,而不是调用操作来加载数据。查询方法会返回单个 Entity 对象、一个 IQueryable<Entity> 对象或一个 IEnumerable<Entity> 对象。查询方法是由中间层上的 DomainService 以及客户端上的 DomainContext 支持的数据模式的必要组成部分。RIA Services 框架会在客户端项目中仅为那些从 DomainService 中的查询方法返回的实体生成实体。
调用操作提供一种带外机制,用于返回非实体数据和执行具有副作用的操作。有关副作用的更多信息,请参见 HasSideEffects 属性。调用操作通常不适用于查询方法。即使调用操作返回了实体,也只在该实体由查询方法返回时,才会为客户端项目生成该实体。
约定
在添加用于执行这些操作的方法时,这些方法必须与操作的预期签名匹配。除了与签名匹配外,方法还必须包含与该数据操作的命名约定匹配的名称前缀。如果方法的名称不是以预期前缀开头,则必须对该操作应用相应的特性。如果该操作的名称与命名约定匹配,则该特性为可选特性。使用命名约定可为开发人员提供更一致的体验。
您无法重载作为域操作的方法。您必须为可从客户端项目调用的每个方法指定一个唯一名称。所有表示域服务操作的方法都必须是公共方法。这些方法必须使用参数的可序列化类型和返回类型。
可以通过向一个方法添加 IgnoreAttribute 特性来阻止公开此方法。
下表提供了数据操作签名。
查询
查询方法必须返回一个实体实例,或返回一个 IEnumerable 或 IQueryable(其中 T 为有效实体类型)。由于不允许重载方法,因此必须为每个采用不同的输入参数(例如 GetEmployees()
和 GetEmployeesByLastName(string lastname)
)的方法提供一个唯一名称。
下表列出了查询操作的预期签名值。
返回值 |
|
参数 |
任意数量的参数 |
名称前缀 |
任何名称 |
特性 |
- 或 -
有关更多信息,请参见 QueryAttribute。 |
示例 |
- 或 -
|
更新
下表列出了更新操作的预期签名值。
返回值 |
无 |
参数 |
实体 |
名称前缀 |
更新、更改或修改 |
特性 |
- 或 -
有关更多信息,请参见 UpdateAttribute。 |
示例 |
- 或 -
|
插入
下表列出了插入操作的预期签名值。
返回值 |
无 |
参数 |
实体 |
名称前缀 |
插入、添加或创建 |
特性 |
- 或 -
有关更多信息,请参见 InsertAttribute。 |
示例 |
- 或 -
|
删除
下表列出了删除操作的预期签名值。
返回值 |
无 |
参数 |
实体 |
名称前缀 |
删除或移除 |
特性 |
- 或 -
有关更多信息,请参见 DeleteAttribute。 |
示例 |
- 或 -
|
调用
调用操作提供一种带外机制,用于返回非实体数据和执行具有副作用的操作。有关副作用的更多信息,请参见 HasSideEffects 属性。调用操作通常不适用于查询方法。
下表列出了调用操作的预期签名值。
返回值 |
任意 |
参数 |
任意数量的参数 |
名称前缀 |
任意 |
特性 |
- 或 -
有关更多信息,请参见 InvokeAttribute。 |
示例 |
- 或 -
|
命名更新
下表列出了命名更新操作的预期签名值。
返回值 |
无 |
参数 |
实体 任意数量的其他参数 |
名称前缀 |
任何不是以 Insert、Update 或 Delete 前缀作为开头的名称 |
特性 |
- 或 -
有关更多信息,请参见 UpdateAttribute。 |
示例 |
- 或 -
|
向域服务添加应用程序逻辑
定义公开的数据操作后,可以将所需应用程序逻辑添加到域服务类。由向导生成的代码旨在帮助您开始编写应用程序逻辑。您可以直接将逻辑添加到操作方法中,或将逻辑添加到从操作方法调用的方法中。可以将参数添加到现有方法、自定义方法的实现或添加新方法,以提供应用程序所需的功能。有关实现业务逻辑的更多信息,请参见如何:向域服务添加业务逻辑。
在实现域服务时,您必须仔细考虑通过服务公开数据的安全风险。有关安全性的更多信息,请参见 WCF RIA Services 的安全性。