Ivan Bara
Ivan Bara

Reputation: 795

Injecting dependencies into an IErrorHandler while hosting in IIS

I just read this great answer, how to inject dependencies into WCF service. The solution is pretty neat, but I have a problem.

Solution in this answer uses self-hosting (console application), so it's possible to implement own ServiceHost and ErrorHandler and do:

var logger = new DummyLogger();
var errorHandler = new TestErrorHandler(logger);

ServiceHost host = new TestServiceHost(errorHandler, typeof(TestService), new Uri("net.tcp://localhost:8002"));
 host.Open();

My problem is, how can I do this in ASP.NET Web application host? I'm trying to inject something into Service while hosting via IIS. Any help would be great!

Upvotes: 0

Views: 126

Answers (1)

Scott Hannen
Scott Hannen

Reputation: 29207

Castle Windsor's WCF Integration Facility does this.

Add the nuget package to your WCF project. In your application startup (global.asax or some bootstrap class you create):

using System;
using Castle.Facilities.WcfIntegration;
using Castle.Windsor;
using Castle.Windsor.Installer;

namespace WcfService1
{
    public class Global : System.Web.HttpApplication
    {
        static readonly IWindsorContainer Container = new WindsorContainer();
        protected void Application_Start(object sender, EventArgs e)
        {
            ConfigureContainer();
        }

        private void ConfigureContainer()
        {
            Container.AddFacility<WcfFacility>();
            Container.Install(FromAssembly.This());
        }
    }
}

Then add an installer class. Container.Install(FromAssembly.This()) will execute any installers in your service.

using Castle.Core.Logging;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;

namespace WcfService1
{
    public class WindsorInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(
                Component.For<IYourService,YourService>(),
                Component.For<ILogger,DummyLogger>()
                );
        }
    }
}

Finally, edit the markup for your YourService.svc to specify that Windsor should create service instances:

<%@ ServiceHost Language="C#" 
    Service="WcfService1.YourService" 
    CodeBehind="YourService.svc.cs" 
    Factory="Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration" 
    %>

Now you can have ILogger as an argument in your service's constructor. Windsor will create each instance of the service and will provide that argument for the constructor.

I use this for just about every WCF I create.


Your comment mentioned that you use Ninject. I found this documentation which shows how to wire up Ninject with WCF.

It's nearly identical. The markup for a service looks like this:

<%@ ServiceHost Language="C#" 
    Service="WcfService1.YourService" 
    CodeBehind="YourService.svc.cs" 
    Factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory" 
    %>

Then the Ninject equivalent of a Windsor installer:

public class WCFNinjectModule : NinjectModule
{
    public override void Load()
    {
        Bind<ILogger>().To<DummyLogger>();
    }
}

Then in global.asax

public class Global : NinjectWcfApplication

protected override IKernel CreateKernel()
{
    return new StandardKernel(new WCFNinjectModule());
}

The only thing that seems off is that you have to inherit from NinjectWcfApplication. in global.asax. That seems a little intrusive.

Upvotes: 1

Related Questions