DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Windsor WCF Integration

Windsor WCF Integration

Mike Hadlow user avatar by
Mike Hadlow
·
Dec. 15, 08 · News
Like (0)
Save
Tweet
Share
7.67K Views

Join the DZone community and get the full member experience.

Join For Free

I've been playing with the Windsor WCF Integration facility today. I've been using a recent trunk build of the Castle project, and since there's been a lot of work recently on the WCF facility, the docs on the Castle site are somewhat out of date. I had to work out how to use the facility by reading the unit tests and a post by Craig Neuwirt to the Castle Project Development list.

So why would you want to integrate WCF with your IoC container? When you use an IoC container in your application it should be the repository of any service that you consume. The service consumer should not care about how the service is implemented or where it comes from. A service should also not be concerned about how it is consumed. The Windsor WCF facility allows you to use your WCF services and proxies as if they were any other service provided by the container.

Let's think about how this might help us when writing enterprise applications. My eCommerce platform, Suteki Shop, sends the customer an email confirming that they've made an order. It sends them another email when the order is dispatched. I have an interface IEmailSender that defines the contract for sending an email. Currently my Windsor configuration maps the IEmailSender service to a class called EmailSender. The OrderController expects to be given an instance of IEmailSender in its constructor. So now it gets an actual instance of EmailSender that wraps the .NET API for sending emails. When the customer clicks the 'order' button the request blocks while an email is sent. This isn't a very scalable solution, but I'm not worried about it now because the only client I have for Suteki Shop is low volume. If their shop take off and starts to get a lot more traffic, I will want to have a more scalable architecture for sending emails. With the WCF integration I could configure IEmailSender to provide a WCF proxy instead of a concrete class. I could then install EmailSender (the IEmailSender implementation) on another server and configure the local container to expose it as a WCF service. The protocol I use can be configured using WCF. So I could use TCP, SOAP, MSMQ, or whatever fitted the purpose. The key point is that by using the WCF facility I've been able to take a part of my application and move to to a new process or machine without touching a single line of code.

So how do you use the WCF facility?

Service

Let's assume we have a simple service interface:

[ServiceContract(Namespace = "Mike.WindsorWCFIntegration")]
public interface ICustomerService
{
[OperationContract]
Customer GetCustomer(int id);
}

Customer is just some entity in my application. In order to serve this via WCF we have to attribute the service interface with WCF attributes: ServiceContract and OperationContract. We don't have to do anything to the existing Windsor.config file, it looks the same as before:

<component id="customerService"
service="Mike.WindsorWCFIntegration.ICustomerService, Mike.WindsorWCFIntegration"
type="Mike.WindsorWCFIntegration.DefaultCustomerService, Mike.WindsorWCFIntegration">
</component>

We're telling the container that when a component asks for an ICustomerService (or 'customerService' by name) they will be given DefaultCustomerService. Since I'm going to host the service as part of a web application, we can use the WCF IIS integration and create a CustomerService.svc file for the customer service that defines the service host:

<%@ ServiceHost Language="C#" Service="customerService" 
Factory="Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration" %>

Note that the Service attribute specifies the same name as the component id in the Windsor.config. The other important point is that we're asking WCF to use the Castle DefaultServiceFactory. This service factory wraps the Windsor container which it uses to resolve any service requests.

We configure WCF as normal:

<system.serviceModel>
<services>
<service name="customerService">
<endpoint contract="Mike.WindsorWCFIntegration.ICustomerService" binding="basicHttpBinding" />
</service>
</services>
</system.serviceModel>

Finally we have to register the WCF Facility with the container on application start:

protected void Application_Start(object sender, EventArgs e)
{
Container = new WindsorContainer()
.AddFacility<WcfFacility>()
.Install(Configuration.FromXmlFile("Windsor.config"));
}

The nice thing is that we haven't had to alter our Windsor.configuration or our existing service. Although we did have to attribute our service interface with WCF specific concerns which is a bit of a shame.

Client

The client side story is also pretty simple. Here's a client service that uses the customerService:

using System;

namespace Mike.WindsorWCFIntegration.Client
{
public class DoSomethingWithCustomers : IDoSomethingWithCustomers
{
private readonly ICustomerService customerService;

public DoSomethingWithCustomers(ICustomerService customerService)
{
this.customerService = customerService;
}

public void DoIt()
{
WriteClientDetails(customerService);
WriteClientDetails(customerService);
}

private static void WriteClientDetails(ICustomerService customerService)
{
var customer = customerService.GetCustomer(24);
...
}
}
}

It's expecting the customerService to be injected by the container. The Windsor.config has to specify that ICustomerService is provided by WCF:

<component id="customerService"
type="Mike.WindsorWCFIntegration.ICustomerService, Mike.WindsorWCFIntegration"
wcfEndpointConfiguration="customerClient">
</component>

The wcfEndpointConfiguration references the WCF configuration in App.config, note that it's the same as the endpoint name, 'customerClient':

<configuration>
<system.serviceModel>
<client>
<endpoint address="http://localhost:2730/CustomerService.svc"
binding="basicHttpBinding"
contract="Mike.WindsorWCFIntegration.ICustomerService"
name="customerClient">
</endpoint>
</client>
</system.serviceModel>
</configuration>

Once again we have to make sure that the WCF Facility is registered with the container (you can do this in the XML configuration as well):

var container = new WindsorContainer()
.AddFacility<WcfFacility>()
.Install(Configuration.FromXmlFile("Windsor.config"));

I hope I've been able to show that using WCF integration with Windsor can be a big win in extending component oriented application design to include serving and consuming remote services. Note that in none of the code above did I have to change the implementation of any of my services in order to make them work with WCF. You can retain your Dependency Injected, testable components and simply have them served onto the web. WCF allows you to configure the wire format (SOAP, REST, POX, binary) and transport (HTTP, named pipes, TCP-IP) independently of your component design. It's very easy to use and very nifty.

You can download the complete demo solution here.

Windows Communication Foundation Integration Web Service

Published at DZone with permission of Mike Hadlow, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Fraud Detection With Apache Kafka, KSQL, and Apache Flink
  • 2023 Software Testing Trends: A Look Ahead at the Industry's Future
  • What Java Version Are You Running? Let’s Take a Look Under the Hood of the JDK!
  • Cloud-Based Transportation Management System

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: