One of the common tasks that .NET RIA Services developers have to undertake is testing their mid tier business logic code. Mid tier code typically uses a data access layer (DAL) like Linq to SQL or Linq to Entities for persisting data. However directly coupling the business logic code to the DAL will pose challenges for unit testing and causes tests to depend on the database. One possible solution to avoid this problem is to adopt the repository pattern and write business logic code to go against repository.
The following steps demonstrates an implementation of a domain service class using a repository to make it unit testing friendly. The example code uses the .NET RIA services walkthrough application as its starting point and is modified to use Linq To SQL as DAL.
STEP 1: Create an interface that defines the necessary methods for performing basic CRUD operations on the repository
STEP 2: Provide concrete implementation of IRepository for Linq to SQL. This is done by performing the repository operations on Linq to SQL’s DataContext as shown below.
STEP 3: Implement the DomainService class and use the repository instead directly calling into DAL layer in domain operation implementation.
The code below implements an Organization DomainService which uses an employee repository
As you can notice from above code snippet, there are few things that are different from the original walkthrough sample :
1. OrganizationDomainService doesn't derive from the LinqToEntitiesDomainService, instead it derives from the base DomainService class
2. OrganizationDomainService has been applied with LinqToSqlMetadataProviderAttribute. This adds Linq To SQL’s type descriptor to our domain service class and enables it to reference the Linq To SQL generated entities (Employee entity in this case).
3. Query/Update methods now call into Repository methods instead of directly calling DAL’s context methods.
4. PersistChangeSet method has been overridden to call the Repository’s SubmitChanges method
STEP 4: Write a factory class to create instance of the DomainService class and the repository and register it (in Global.asax.cs). This ensures that our factory method is used for domain service class creation by the framework.
Now the app is ready for execution (there is no change required to the client side code of the walkthrough project).
STEP 5: Creating unit tests
For unit testing the domain service methods, all we need to do is write a mock repository that creates an in-memory instance of employees and pass it to DomainService.
Code below shows creation of a mock employee repository.
and the unit test code would look something like this:
Completed sample source can be downloaded from here (see 'Repository for unit testing sample').