InfoQ

News

Injecting Implementation Dependencies into WCF Services

Posted by Hartmut Wilms on Jan 08, 2008 09:00 AM

Community
.NET
Topics
Web Services,
.NET Framework
Tags
Dependency Injection,
WCF

A very popular concept of implementing WCF services is to use a layered approach that consists of a service, a business logic and a data access layer. The dependencies between these layers might be injected at runtime via dependency injection containers.

The Service Architecture Concept Model as outlined by Don Smith proposes a WCF service facade which provides a published interface/contract that is implemented by components of a business (logic) layer. Those components have in turn dependencies with data access components of the resource access layer.

The dependencies between the layers are normally hard-coded within the service and component implementations, complicating unit tests. Pablo M. Cibraro shows how to inject component dependencies by implementing a WCF Dependency Injection Behavior. In Pablo's approach ObjectBuilder is used as the Dependency Injection Container whereas Oran Dennison makes use of Spring.NET in his approach to WCF Service Dependency Injection.

Oran presents the following setup of dependencies within his service implementation code:

[ServiceContract]
public interface IServiceContract {
[OperationContract]
...
}

public class ServiceLayer : IServiceContract {
IBusinessLogic _businessLogic;

public ServiceLayer(IBusinessLogic businessLogic) {
_businessLogic = businessLogic;
}
...
}

public interface IBusinessLogic {
...
}

public class BusinessLogic : IBusinessLogic {
IDataAccess _dataAccess;

public BusinessLogic(IDataAccess dataAccess) {
_dataAccess = dataAccess;
}
...
}

public interface IDataAccess {
...
}

public class DataAccess : IDataAccess {
...
}

The service implementation has a dependency with the business logic component, which has in turn a dependency with the data access component. The hard-wired variant of setting up all dependencies would look like this:

return new ServiceLayer(new BusinessLogic(new DataAccess()));

Dependency injection containers basically inject those dependencies by providing a mapping of interfaces to implementation classes within a configuration. This configuration might be changed at runtime, for instance in order to run unit tests that use mock implementations. Pablo explains:

Quite easy, the only requirement [for a dependency injection container] is the mapping, otherwise the container will not know how to create instances of the interfaces. Now, let's move forward to try configuring this in WCF using a behavior as extensibility point. WCF supports an extension called IInstanceProvider that controls the lifecycle of a WCF service instance. We will use one this provider to hook up our custom code and inject the dependencies at runtime.

public class DIInstanceProvider : IInstanceProvider {   
[...]


public object GetInstance(InstanceContext instanceContext, Message message) {
DependencyContainer container = new DependencyContainer();
foreach (TypeMapping typeMapping in this.typeMappings) {
container.RegisterTypeMapping(typeMapping.TypeRequested, typeMapping.TypeToBuild);
}
return
container.Get(this.serviceType);
}
[...]
}

The DIInstanceProvider has then to be plugged into the dispatcher runtime by an IServiceBehavior. The type mappings are configured within a new WCF configuration section, which is implemented by a BehaviorExtensionElement that reads the mappings from the configuration file and passes them to the DIServiceBehavior instance. Pablo's sample configuration including type mappings looks like this:

<behaviors>

      <serviceBehaviors>

        <behavior name="Behaviors1">

          <dependencyInjection>

            <typeMappings>

              <add name="DataAccess" typeRequested="SampleService.ICustomerDataAccess, SampleService"

                    typeToBuild="SampleService.CustomerDataAccess, SampleService"/>

              <add name="BusinessComponent" typeRequested="SampleService.ICustomerBusinessComponent, SampleService"

                    typeToBuild="SampleService.CustomerBusinessComponent, SampleService"/>

            typeMappings>

          dependencyInjection>

        behavior>

      serviceBehaviors>   

behaviors>

Pablo has published his sample code. It should be fairly easy to adapt the code to Oran's approach or to any other dependency injection container, e.g. Castle Windsor.

1 comment

Reply

There is a Windsor Facility for WCF by Glenn Goodrich Posted Jan 10, 2008 7:24 AM
  1. Back to top

    There is a Windsor Facility for WCF

    Jan 10, 2008 7:24 AM by Glenn Goodrich

    Ayende has already written a WCF facility that registers the service on the Windsor container. Once it's registered, you can (of course) inject all the dependencies you want. Also, if you register any other classes that implement IServiceBehavior, they will be added to all the services registered with Windsor automatically. Very cool. Check it out here. Hope this is useful. Glenn

Exclusive Content

Measuring Agile in the Enterprise: 5 Success Factors for Large-Scale Agile Adoption

Michael Mah analyzes the development process in 5 companies: 2 Agile (one of them BMC) and 3 classic. He presents the factors which contributed to the success of BMC's Agile adoption.

Tom Preston-Werner on Powerset, GitHub, Ruby and Erlang

In this interview filmed at RubyFringe 2008, Tom Preston-Werner talks about how both Powerset and GitHub use Ruby and Erlang, as well as tools like Fuzed, god, and more.

David Laribee on Alt.NET and its Mission

David Laribee discusses the purpose of ALT.NET, its mission and future.

Discover RailsKits and Stop Writing Redundant Code

Ruby on Rails has become a popular Ruby framework for creating web applications in recent years. An aspect of creating a web application is the need to repeatedly create the same base functionality.

A Formal Performance Tuning Methodology: Wait-Based Tuning

Steven Haines talks about tackling web application performance tuning by proposing a method called wait-based tuning.

Shaw and Fowler About Forging a New Alliance

Shaw and Fowler talk about the need for a new relationship between the business department and the IT department. Studies have shown that projects mostly fail due to miscommunication between the two.

How to GET a Cup of Coffee

In this article, Jim Webber, Savas Parastatidis and Ian Robinson show how to drive an application's flow through the use of hypermedia in a RESTful application.

Archaeopteryx: A Ruby MIDI Generator

Eccentric artist turned overnight anti-celebrity, Giles Bowkett captures the heart and soul of RubyFringe as he demonstrates his revolutionary Archaeopteryx MIDI drum pattern generator.