This project is read-only.

WCF Service Called Using InProcFactory

Topics: Troubleshooting, Writing modules
Mar 14, 2012 at 9:44 PM

I have a module that is leveraving a WCF service using the InProcFactory created by Juval Lowy at iDesign.
I have a helper method that actually does the InProcFactory call and retuns the proxy as an interface for my service.
I have verified that the service gets created and is callable (I did this inside my helper method as I was diagnosing this issue by actually calling the created service instance).
The problem is, somewhere between the return statement of my helper method and the assignment in the caller I am hitting what looks like a deadlock.

I am essentially calling this:
myService = CRServiceInstanceHelper.GetServiceInstance<ConcreteService, IService>();
I can debug all the way through that call, up to the return statement.

Inside of the GetServiceInstance I am able to capture the IService instance and call
service.TestSomeMethod(); So I know this part works fine.

However, I am now stuck on the line where the call to GetServiceInstance is assigned to myervice.
My browser keeps spinning and the debugger won't progress.
It's almost like Orchard is losing the call/return somewhere.

There is nothing in the Visual Studio output, he call never times out, no exceptions thrown. I don't get it.

Any ideas?


Mar 15, 2012 at 9:21 PM

I have narrowed down the scenario by doing a reduction to get to the smallest number of moving parts and still get the error.

Using Orchard, passing a value from a dynamic object to a helper method that returns an instance from InProcFactory is specifically how I get this issue.
If I have the helper method return simply null, (don't create a service intance with InProcFactory) it works.
If I assign the value rom the dynamic dictionary to a string and pass in that new string to my helper method, it works.
If I call my helper from a normal MVC application, passing in the dynamic value (like normal) and returning the InProcFactory object (like normal), it works.

Take away any of the pieces and it works in Orchard. Problem is, I need all of these pieces...
It's like this causes some odd alignment in the universe and somewhere, it chokes and dies (by dies I mean it infinite loops/deadlocks)...


Mar 19, 2012 at 4:22 AM
Edited Mar 19, 2012 at 3:26 PM

Does anyone care to take a look at this issue? Drop the following into any module and add a route to it.

*****EDIT, you don't even need the controller and route. Drop the code into a constructor of an existing module and watch it break. I used the blog module just for grins to make sure it wasn't something specific to my module.

What you should see is that the code will get stuck on returning from the GetServiceInstance call (you will need the ServiceModelEx library from the website to use the InProcFactory call. The odd thing is there is a collection of 3 things required for this to happen.
1) You have to call a method that returns the WCF instance, 2 you have to pass some dynamic value to that method and 3 you have to do it in Orchard.

The code below works fine in a normal MVC application. Works fine if GetServiceInstance returns anything other than something created by InProcFactory. Works fine if I don't pass it a dynamic - for instance, if I pass "InProc" directly instead of anyString variable.

Notice I never even use the anyString, passing it in is enough to make it choke. I also never use the wcf service, creating and returning it is enough to choke. This one is odd.







namespace CR.Core.Controllers
    public class DeadlockController : Controller
        public ActionResult Index()
            dynamic anyString = "InProc";
            IWCFService wcfService = GetServiceInstance(anyString);

            //Debugger never gets here.
            return View();

        public IWCFService GetServiceInstance(string serviceHostType)
            return InProcFactory.CreateInstance<WCFService, IWCFService>();
        } // Debugger gets here.

    public interface IWCFService
        void TestDeadlock();

    [ServiceBehavior(UseSynchronizationContext = false)]
    public class WCFService : IWCFService
        void IWCFService.TestDeadlock()
            throw new NotImplementedException();



Mar 21, 2012 at 6:40 PM
Edited Mar 21, 2012 at 6:59 PM

Crickets... Not what I am used to on this forum. :) Need more info? Or is everyone just as puzzled over this as I am?

I have reduced the code even further. Turns out InProcFactory isn't even needed. The issue presents itself using a straight call to System.ServiceModel objects. Which means the issue is constrained to Orchard, dynamic type and System.ServiceModel.

From the code in my previous post I have changed GetServiceInstance function to this in order to eliminate InProcFactory and the need for ServiceModelEx library:

  public IWCFService GetServiceInstance(string serviceHostType)
     Binding binding = new NetNamedPipeContextBinding();
     EndpointAddress address = new EndpointAddress("net.pipe://localhost/" + Guid.NewGuid());      

     ChannelFactory<IWCFService> factory = new ChannelFactory<IWCFService>(binding, address);
     IWCFService proxy = factory.CreateChannel();
     return proxy;
  } // Debugger gets here.






Mar 21, 2012 at 7:29 PM

I know nothing about that WCF stuff. Sébastien maybe?

Mar 21, 2012 at 7:31 PM

Lesson learned. Culprit was not Orchard or ServiceModelEx but with simple passing a dynamic as a parameter TO a method.

This will cause .NET to treat the return from the method as a dynamic - even if the method specifies a return type..


Cast the value to a specific type before sending it to the method.
dynamic anyString = "InProc";
IWCFService wcfService = GetServiceInstance((string)anyString);

Or treate the return of the method as a dynamic.
dynamic anyString = "InProc";
dynamic wcfService = GetServiceInstance((string)anyString);

Sucks that the default behavior is a DEADLOCK and not a warning/error...


Mar 21, 2012 at 7:47 PM

Black listing WCF question right now ... waiting for Nick explain how to wire Web API ;)

Jun 17, 2012 at 2:46 PM

nick has done