WCF RIA Services Unity DomainServiceFactory

Note: This post is based on WCR RIA Services PDC beta and changes can be made in a future release. 

In this post I will show you how it’s possible to create your own DomainServiceFactory which has the responsibility to create a DomainService instance. I decided to use Unity as a Dependency Injection framework to create my DomainServices. Why do we even want to create a custom DomainServiceFactory, well, to avoid dependencies inside our DomainServices, for example here is a DomainService which has a dependency to a CustomerRepository:

 
    [EnableClientAccess()]
    public class CustomerService : DomainService
    {

        public CustomerPM GetCustomerByID(int customerID)
        {
            var customerRepository = new CustomerRepository();
            var customer = customerRepository.GetCustomerByID(customerID);

            return new CustomerPM()
                   {
                      CustomerID = customer.CustomerID,
                      FullName = customer.FirstName + " " + customer.LastName,
                      Age = customer.Age
                   };
        }
    }

 

The code above will break the Dependency Inversion Principle, High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend upon details. Details should depend upon abstractions. We can’t use the code above in a unit-test, because it will use the CustomerRepository, so in that case we are doing an integration test. Our DomainService is now tightly coupled with the CustomerRepository. So to remove the detail (CustomerRepository) and use an abstraction, we can use the following solution:

    [EnableClientAccess()]
    public class CustomerService : DomainService
    {
        private ICustomerRepository _customerRepository;

        public CustomerService(ICustomerRepository customerRepository)
        {
            _customerRepository = customerRepository;
        }

        public CustomerPM GetCustomerByID(int customerID)
        {
            var customer = _customerRepository.GetCustomerByID(customerID);

            return new CustomerPM()
                   {
                       CustomerID = customer.CustomerID,
                       FullName = customer.FirstName + " " + customer.LastName,
                       Age = customer.Age
                   };
        }
    }

 

Now the detail is removed, and we work against an abstraction (ICustomerRepository). We can now easily use this DomainServices with different kind of CustomerRepository as long as they implements the ICustomerRepository. We can now create our a test stub for the CustomerRepository when we write our unit-test etc. The problem with the code above, is that WCF RIA Services will throw an exception when it will try to create an instance of the DomainService. It will by default use the default constructor. If we add a default constructor, there is no way for the WCF RIA Services to know that we need to pass in a ICustomerRepository, so our GetCustomerByID method will throw and null reference exception when we try to call the CustomerRepository’s GetCustomerByID method. To solve this we can create our own DomainServiceFactory, where we handle the creation of the DomainService.

To create a DomainServiceFactory we need to create a class that implements the IDomainServiceFactory interface, and implement two methods, CreateDomainService and ReleaseDomainService:

 public class MyDomainServiceFactory : IDomainServiceFactory
 {
        
        public DomainService CreateDomainService(Type domainServiceType, DomainServiceContext context)
        {
            var service = Global.UnityContainer.Resolve(domainServiceType) as DomainService;
            service.Initialize(context);

            return service;
        }


        public void ReleaseDomainService(DomainService domainService)
        {
            domainService.Dispose();
        }
}


The CreateDomainSerivce method will be called when WCF RIA Services will create an instance of our DomainSerivce, and the ReleaseDomainService will be called when WCF RIA Services will release it. To make the factory work, we must call the Initialize method of the DomainService we have created before returning it. The code above will use Unity to create an instance of a DomainService and if they have any dependencies, Unity will inject them if they are registered to the UnityContainter.

To register our IDomainServiceFactory we use the DomainSerivce.Factory property, which is a static property, we can for example use it in Application_Start in global.asax to configure the use of our factory:

    public static UnityContainer UnityContainer = new UnityContainer();


protected void Application_Start(object sender, EventArgs e) { DomainService.Factory = new MyDomainServiceFactory();
UnityContainer.RegisterType<CustomerService>(); UnityContainer.RegisterType<ICustomerRepository, CustomerRepository>(); }


Note: For demonstartion purpose I simply add a static UnityContainer to the Global.asax file, and in the MyDomainServiceFactory I access the UtnityContainer by writing Global.UnityContainer.

I also register my DomainService and Repositories in Global.asax.

Now when WCF RIA Services wants to create a DomainService, it will use the MyDomainServiceFactory, which will use Unity to create an instance of the DomainService, and CustomerRepository will be injected to the CustomerService.

Something I want to see in the future, is that Microsoft makes sure we can create our own DomainService method Invoker, or at least add two public events, OnOperationExecuting and OnOperationExecuted, so we can simply add pre- and post conditions, or have more possibility to extend the WCF RIA Services.

If you want to know when I publish a new blog post, you can follow me on twitter: http://www.twitter.com/fredrikn

Published Saturday, November 28, 2009 6:11 PM by Fredrik N

Comments

# Twitter Trackbacks for WCF RIA Services Unity DomainServiceFactory - Fredrik Norm??n [asp.net] on Topsy.com

Pingback from  Twitter Trackbacks for                 WCF RIA Services Unity DomainServiceFactory - Fredrik Norm??n         [asp.net]        on Topsy.com

# Interesting Finds: November 29, 2009

Sunday, November 29, 2009 9:10 AM by Jason Haley

Interesting Finds: November 29, 2009

# Dew Drop &#8211; November 30, 2009 | Alvin Ashcraft&#039;s Morning Dew

Pingback from  Dew Drop &#8211; November 30, 2009 | Alvin Ashcraft&#039;s Morning Dew

# Silverlight 4 - MVVM with Commanding and WCF RIA Services

Monday, November 30, 2009 1:38 PM by Fredrik Normén

Note: The code example in this post uses Silverlight 4 PDC Beta and WCR RIA Services PDC Beta, so some

# Silverlight 4 - MVVM with Commanding and WCF RIA Services

Monday, November 30, 2009 1:43 PM by Cornerstones utvecklarblogg

Note: The code example in this post uses Silverlight 4 PDC Beta and WCR RIA Services PDC Beta, so some

# Silverlight 4 - MVVM with Commanding and WCF RIA Services

Monday, November 30, 2009 2:34 PM by ASPInsiders

Note: The code example in this post uses Silverlight 4 PDC Beta and WCR RIA Services PDC Beta, so some

# WCF RIA Services – StructureMap – DomainServiceFactory

Tuesday, December 01, 2009 4:58 AM by Fredrik Normén

Note: The example in this blog post uses the WCF RIA Services PDC Beta, so things can be changed to the

# WCF RIA Services – StructureMap – DomainServiceFactory

Tuesday, December 01, 2009 5:10 AM by Cornerstones utvecklarblogg

Note: The example in this blog post uses the WCF RIA Services PDC Beta, so things can be changed to the

# re: WCF RIA Services Unity DomainServiceFactory

Wednesday, December 09, 2009 4:47 PM by Alexandre Arnaudet

Good article. This example also works with CTP from july

# WCF RIA Services DomainService life-cycle and adding Transactions

Tuesday, December 29, 2009 1:53 PM by Fredrik Normén

Note: This blog post will use the WCF RIA Services PDC Beta and VS2010 Preview, changes to the framework

# WCF RIA Services DomainService life-cycle and adding Transactions

Tuesday, December 29, 2009 2:01 PM by Cornerstones utvecklarblogg

Note: This blog post will use the WCF RIA Services PDC Beta and VS2010 Preview, changes to the framework

# Aspen – A sample app using Silverlight 4 and .Net 4.0 – part 4 of X – DomainService, using DTO and Unity

Sunday, January 17, 2010 7:55 AM by Fredrik Normén

Note: The code in this post is based on the VS 2010 Beta 2, and changes can be made until it hits RTM

Leave a Comment

(required) 
(required) 
(optional)
(required)