Creating WCF OperationContext works great with DI and testing

I am running a WCF service hosted on a Windows service; WCF service dependencies are injected through Unity, which is good. As a result, the service also easily records unit tests for.

I recently added functionality to a service that uses an OperationContext to check incoming messages. Unfortunately, this rather impacts the testability of the service due to water due to Microsoft's immunity to private and / or static classes, as well as to the lack of interfaces and / or virtual methods.

So, I turned to my favorite .NET tool in this situation, the wrapper class. Since this is a common problem, someone has already done the hard work for us . Thus, this adds a new dependency to my WCF service, an implementation of IOperationContext. This was not a problem for my unit tests, NSubstitute is my layout choice scheme (like Moq, but without the .Object curse).

However, when I try to start the service for real, I have the following problem: the processed OperationContext was not initialized when IoC container registration was completed. My initialization code (using Unity here):

 container.RegisterType<IOperationContext, OperationContextWrapper>(new InjectionConstructor(OperationContext.Current)); 

but at this moment OperationContext.Current is null , so Unity quickly throws an exception, and my dreams of retiring to 40 rise in smoke.

So the question is: how do you get WCF to play well with DI and wrapped OperationContext ?

+4
source share
3 answers

OperationContext.Current is a custom property. Can you change the initialization of the test to

 OperationContext.Current = new OperationContextWrapper(); 

and does he work that way? If you need it in unity, you can also:

 var oc = new OperationContextWrapper(); OperationContext.Current = oc; container.RegisterInstance<IOperationContext>(oc); 
+1
source

I may not understand, but I'm not sure why you want to introduce OperationContext.Current in your shell. If an OperationContextWrapper wraps an OperationContext, then why not just implement it directly with OperationContext.Current, where necessary? I assume that the code you are trying to keep testable is not an OperationContextWrapper, but rather a code that depends on it through the IOperationContext interface? Then who cares what OperationContextWrapper does?

+2
source

You can also use Microsoft Fakes:

 using (ShimsContext.Create()) { ShimOperationContext shimOperationContext = new ShimOperationContext(); shimOperationContext.SessionIdGet = () => "sessionId"; OperationContext.Current = shimOperationContext; } 
+1
source

All Articles