WCF Windsor Integration
Last night I commited WCF Integration to the Castle trunk. This is based in part on the work described here by Orand.
The main idea here is that WCF should get the service instances from Windsor, which gives us all the usual advantages of IoC plus Windsor's interceptors capabilities. It isn't a lot of code, but it makes it much easier to work with WCF services.
Using it on a web application:
- Call this in the beginning of the application (Global.Application_Start):
WindsorServiceHostFactory.RegisterContainer(container); - Create a MyService.svc file and put this in it:
<%@ ServiceHost Service="component name in windsor" Factory="Castle.Facilities.WcfIntegration.WindsorServiceHostFactory, Castle.Facilities.WcfIntegration" %>
Using it from a non-web application:
WindsorContainer windsorContainer = new WindsorContainer(); windsorContainer.AddComponent("operations", typeof (IOperations), typeof (Operations)); Uri uri = new Uri("net.tcp://localhost/WCF.Facility"); WindsorServiceHost host = new WindsorServiceHost(windsorContainer, typeof (Operations), uri); host.Description.Endpoints.Add( new ServiceEndpoint(ContractDescription.GetContract(typeof (IOperations)), new NetTcpBinding(), new EndpointAddress(uri))); host.Open();
Obviously you can cut down on this code significantly using the standard WCF configuration.
Another interesting thing is the ability to apply cross cutting concerns using IServiceBehavior / IEndPointBehavior. Any components that are registered with those interfaces on the container will be applied to all the services that are created this way. You can apply individual behaviors using the standard WCF means.
What is this not?
It is not here to replace WCF configuarion, and it deals specifically just with creating/disposing of services using Windsor. There are already good tools to configure WCF, and this approach takes full advantage of them.
The code has both tests and a sample site, have fun.
Comments
Thanks for that !
Could you provide an example of how to use that in an NHibernate + UoW scenario please.
I've been trying to use your WCF Facility and have been confronted to a recurrent problem in the WindsorServiceHost.cs
the part of the code that resolves and injects the ServiceBehaviors and EndpointBehaviors throws an exception. I haven't been able to trace it doesn't enter in the OnOpening Method.
I'm not familiar with the MicroKernel Implementation have just been using the Windsor API. So the whole concept of handlers and CreationContext is not really clear to me.
I would really appreciate some help here
Thanks a lot !
Here is the Exception:
Field not found: 'Castle.MicroKernel.CreationContext.Empty'.
StackTrace:
[MissingFieldException: Field not found: 'Castle.MicroKernel.CreationContext.Empty'.]
Castle.Facilities.WcfIntegration.WindsorServiceHost.OnOpening() +0
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +236
System.ServiceModel.Channels.CommunicationObject.Open() +30
System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +104
System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +445
[ServiceActivationException: The service '/WebServiceHost/AccountsService.svc' cannot be activated due to an exception during compilation. The exception message is: Field not found: 'Castle.MicroKernel.CreationContext.Empty'..]
System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +962
System.ServiceModel.ServiceHostingEnvironment.EnsureServiceAvailableFast(String relativeVirtualPath) +419
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest() +260
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest() +760
System.ServiceModel.Activation.HostedHttpModuleRequestAsyncResult.BeginRequest() +178
System.ServiceModel.Activation.HttpModule.StartBeginProcessRequest(Object sender, EventArgs e, AsyncCallback cb, Object extraData) +70
System.ServiceModel.Activation.HttpModule.ProcessRequest(Object sender, EventArgs e) +195
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +92
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +64
You don't have the correct versions of the DLLS installed.
Probably mean that you need to rebuild the trunk.
Would you be able to add to the overall Castle NANT build the build of this facility so that we can build trunk of Castle and get this binary to show in the build folder
Yes, I would.
In order to get the demo working I had to change Global.asax
from
<%@ Application Codebehind="Global.asax.cs" Inherits="Global" Language="C#" %>
to
<%@ Application Codebehind="Global.asax.cs" Inherits="Castle.Facilities.WcfIntegration.Demo.Global" Language="C#" %>
Mate, this is so cool. I created an IErrorHandler to log errors, passing in the ILogger from the Windsor facilities. Now the service and the error handler can use the same logger, all done dynamically at runtime.
Thanks!
Comment preview