Domain Services
[ This document was written for WCF Services Version 1 Service Pack 2 and might not be up to date Please see Release Notes or Changelog for a list of changes since WCF RIA Services ]
Domain services are Windows Communication Foundation (WCF) services that encapsulate the business logic of a Open Ria Services application. A domain service exposes a set of related operations in the form of a service layer. When you define a domain service, you specify the data operations that are permitted through the domain service.
When designing a domain service, you should think of the domain service as a set of related tasks that you expect users to perform in your application. Typically, such tasks involve a small group of closely-related entities. For example, in an expense reporting application, you might expose entities for expense reports, line items, and details. You might, then, place entities for accounts and payments in a separate domain service.
Domain Services and their Data Sources
The DomainService class is the base class for all classes that serve as domain services. To create a domain service that binds to a custom data object, you create a class that derives directly from DomainService. But if you have a domain service either binds an ADO.NET Entity model or that exposes a LINK to a SQL database, there are special abstract classes the derive from DomainService that you use instead.
To create a domain service that binds to an ADO.NET Entity model, you create a class that derives from LinqToEntitiesDomainService\. Open Ria Services provides the LinqToEntitiesDomainService\ class.
If you want to create a domain services that exposes LINQ to SQL classes in your application, you create a class that derives from LinqToSqlDomainService. This class is provided in the Open Ria Services Toolkit. If you want to create a domain services that exposes LINQ to SQL classes in your application using this class, you must download the Open Ria Services Toolkit.
When you use the Add New Domain Service Class dialog box to create a domain service, the type of domain service that is created is based on the entities you expose.
A domain service class must be marked with the EnableClientAccessAttribute attribute to make the service available to the client project. The EnableClientAccessAttribute attribute is automatically applied to a domain service when you select the Enable client access check box in the Add New Domain Service Class dialog box. When the EnableClientAccessAttribute attribute is applied to a domain service, Open Ria Services generates the corresponding classes for the client project. For example, when you apply the EnableClientAccessAttribute attribute to a domain service named HRService that exposes an entity named Employee, Open Ria Services generates a domain context named HRContext in the client project and a client-version of the Employee entity.
WCF and Domain Services
As a Windows Communication Foundation (WCF) service, the domain service builds upon WCF concepts. The domain service preserves the following:
Standard usage of WCF services
Existing WCF programming models constructs, such as operation contracts, operation behaviors, and service behaviors
Standard WCF customization capabilities, such as binding configuration, behavior configuration, and management infrastructure
The domain context communicates with the Open Ria Services domain service by using the WCF ChannelFactory to create a channel and passing to it a service contract that was generated from the domain service.
By default, only the binary endpoint is enabled for domain services. To use the binary endpoint no additional configuration is needed. If you want to use another endpoint (such as OData, JSON, SOAP, or a custom host) you must register an endpoint factory in the Web.config file as shown below:
The System.ServiceModel.DomainServices.Hosting namespace contains the endpoints that are supported in Open Ria Services. The Microsoft.ServiceModel.DomainServices.Hosting namespace contains the endpoints that are supported with the Open Ria Services Toolkit, such as the JsonEndpointFactory shown in the previous example. To create a custom endpoint, you must create a class that derives from the DomainServiceEndpointFactory class, and override the CreateEndpoints(DomainServiceDescription, DomainServiceHost) method.
Data Operations
You add methods to a domain service that perform the data operation you want to expose. For example, you can add methods that perform the following operations:
Query
Update
Insert
Delete
You can also add more complicated operations such as:
Invoke: to implement operations that need to be executed without tracking or deferred execution. This method is used only with non-entity data, and used only when query, update, insert, or delete operations cannot be used instead.
Named Update: to implement custom operations that do not fall into simple modification operations.
When you expose a domain service, an EntitySet object is generated in the domain context with properties that indicate which operations (insert, update, or delete) are permitted from the client. You execute data modifications by modifying the entity collection and then calling the SubmitChanges method.
In almost all scenarios, you should use query operations instead of invoke operations to load data. Query methods return either a single Entity object, an IQueryable\ object, or an IEnumerable\ object. Query methods are an integral part of the data pattern supported by DomainService on the middle-tier and by DomainContext on the client. The Open Ria Services framework generates entities in the client project for only those entities that are returned from query methods in a DomainService.
Invoke operations provide an out-of-band mechanism for returning non-entity data and executing operations with side-effects. For more information about side-effects, see the HasSideEffects property. Invoke operations are usually not appropriate for query methods. Even when an invoke operation returns an entity, the entity is generated for the client project only if it is returned by a query method.
Conventions
When you add methods to perform these operations, the method must match the expected signature for that operation. In addition to matching the signature, the method must include a name prefix that matches the naming convention for that data operation. If the name of the method does not start with the expected prefix, you must apply the corresponding attribute for that operation. The attribute is optional if the name of the operation matches the naming convention. Using the naming convention provides a more consistent experience for developers.
You cannot overload methods that are domain operations. You must specify a unique name for each method that can be called from the client project. All methods that represent domain service operations must be public. The methods must use serializable types for parameters and return types.
You can prevent a method from being exposed by adding the IgnoreAttribute attribute to the method.
The data operation signatures are provided in the following tables.
Query
A query method must return a single instance of an entity, or an IEnumerable\ or IQueryable\ where T is a valid entity type. Because overloaded methods are not allowed, you must provide a unique name for each method that takes different input parameters (for example GetEmployees() and GetEmployeesByLastName(string lastname).
The following table lists the expected signature values for a query operation.
Update
The following table lists the expected signature values for an update operation.
Insert
The following table lists the expected signature values for an insert operation.
Delete
The following table lists the expected signature values for a delete operation.
Invoke
Invoke operations provide an out-of-band mechanism for returning non-entity data and executing operations with side-effects. For more information about side-effects, see the HasSideEffects property. Invoke operations are usually not appropriate for query methods.
The following table lists the expected signature values for an invoke operation.
Named Update
The following table lists the expected signature values for a named update operation.
Adding Application Logic to a Domain Service
After defining the exposed data operation, you can add the required application logic to the domain service class. The code generated by the wizard is intended to only help you start writing the application logic. You can add the logic directly into the operation methods or you add it to methods that are called from the operation methods. You can add parameters to existing methods, customize the implementation of methods, or add new methods to provide the functionality required by your application. For more information about implementing business logic, see How to: Add Business Logic to the Domain Service.
When implementing a domain service, you must carefully consider the security risks of exposing data through a service. For more information about security, see Building Secure Applications with Open Ria Services.
See Also
Concepts
Last updated