Reputation: 795
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
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