Search code examples
c#wcfinversion-of-controlsimple-injector

How to inject properly a service in WCF service and other services by using SimpleInjector


If there are two WCF services defined like this:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class WcfService1: IWcfService1
{
     private IService1 _service1;
     public WcfService(IService1 service1){
         _service1 = service1;
     }
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class WcfService2: IWcfService2
{
     private IService2 _service2;
     public WcfService(IService2 service2){
         _service2 = service2;
     }
}

and if the Service2 is injected in Service1, which is the best way to register Service2 with SimpleInjector?

like this

container.RegisterPerWcfOperation<IService1, Service1>();    
container.RegisterPerWcfOperation<IService2, Service2>();

or like this

container.RegisterPerWcfOperation<IService1, Service1>();    
container.Register<IService2, Service2>(Lifestyle.Scoped);

The container is configured like this:

container.Options.DefaultScopedLifestyle = new WcfOperationLifestyle();

Solution

  • First of all, the use of the (old) extension methods such as RegisterPerWcfRequest is discouraged, since the availability of the new Lifestyle.Scoped property. Lifestyle.Scoped gives a simpler, more readable and more flexible model of registering scoped instances, while the same underlying lifestyle is used, since you set that through Options.DefaultScopedLifestyle.

    Furthermore, since each WCF call to a service runs in its own request, a new scope exist and each service will get its own instance of Service2, no matter whether you register it as Transient or Scoped. Only if you register it as Singleton you will see the same instance of Service2 be reused over requests; in fact, with Singleton there will be only one instance of Service2 for the lifetime of your WCF service.

    The real question here is, if WcfService1 or WcfService2 depend on other classes that directly or indirectly depend on Service2 as well, must the same instance of Service2 be used during that request, or is it okay to have multiple instances of Service2 during that single request? If multiple instances is okay, you can register it as Transient, otherwise as Scoped.

    The following registrations will do the trick if you want your components to have the transient lifestyle.

    container.Register<IService1, Service1>();    
    container.Register<IService2, Service2>();