WCF Extension - NULL Exception using NET.TCP Binding

2,031 views
Skip to first unread message

Cragly

unread,
Mar 27, 2011, 3:05:21 PM3/27/11
to ninject
I have a WCF 4 service with 2 endpoints configured to usewsHttpBinding
and netTcpBinding. I am hosting the service within IIS 7.5 using WAS
and am using the Ninject WCF extension to DI in my service. My service
works fine when I use the wsHttpBinding endpoint to call my service
but fails when I use the netTcpBinding. When I look in my Application
Event Log I get the following error outlined below.

I have tried debugging the problem in VS2010 but am getting nowhere
fast with this. I don’t want to have to remove Ninject from my WCF
service if at all possible. I understand that I could just use
wsHttpBinding but I this is an internal service and I want to get the
performance gains that netTcpBindings provide.

Any help on this one would be much appreciated.

WebHost failed to process a request.
Sender Information: System.ServiceModel.ServiceHostingEnvironment
+HostingManager/30180123
Exception: System.ServiceModel.ServiceActivationException: The
service '/ProfileService.svc' cannot be activated due to an exception
during compilation. The exception message is: Cannot be null
Parameter name: root. ---> System.ArgumentNullException: Cannot be
null
Parameter name: root
at Ninject.Infrastructure.Ensure.ArgumentNotNull(Object argument,
String name) in c:\Projects\Ninject\ninject\src\Ninject\Infrastructure
\Ensure.cs:line 20
at Ninject.ResolutionExtensions.Get[T](IResolutionRoot root,
IParameter[] parameters) in c:\Projects\Ninject\ninject\src\Ninject
\Syntax\ResolutionExtensions.cs:line 37
at
System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(String
constructorString, Uri[] baseAddresses)
at
System.ServiceModel.ServiceHostingEnvironment.HostingManager.CreateService(String
normalizedVirtualPath)
at
System.ServiceModel.ServiceHostingEnvironment.HostingManager.ActivateService(String
normalizedVirtualPath)
at
System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String
normalizedVirtualPath)
--- End of inner exception stack trace ---
at
System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String
normalizedVirtualPath)
at
System.ServiceModel.ServiceHostingEnvironment.EnsureServiceAvailableFast(String
relativeVirtualPath)
Process Name: w3wp
Process ID: 8656

LOBOMINATOR

unread,
Mar 27, 2011, 4:49:09 PM3/27/11
to nin...@googlegroups.com
Hy
This happens when IResolutionRoot is null. What version of wcf extension do yoy have? Are you using the latest? If yes you need to set the kernel by using the static SetKernel method on the ninjectservicehostfactory

See https://github.com/ninject/ninject.extensions.wcf/blob/master/src/Ninject.Extensions.Wcf/NinjectServiceHostFactory

Daniel

> --
> You received this message because you are subscribed to the Google Groups "ninject" group.
> To post to this group, send email to nin...@googlegroups.com.
> To unsubscribe from this group, send email to ninject+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/ninject?hl=en.
>

Cragly

unread,
Mar 28, 2011, 5:40:43 AM3/28/11
to ninject
Thanks for the reply,

Have tried a couple of ways to do the static set but cant get it to
work. Would it be possible to show me how this is done. My original
Global.asax code in my service looks like this and inherits from
NinjectWcfApplication.

protected override IKernel CreateKernel()
{
IKernel kernel = new StandardKernel(new ServiceModule());
return kernel;
}

My ServiceModule inherits from NinjectModule and looks like this:

public override void Load()
{

Bind<IProfilePersistence>().To<EntityProfilePersistence>();
}

My ProfileService.svc file looks like this:

<%@ ServiceHost Language="C#" Debug="true"
Service="MyProject.ServiceImplementations.ProfileService"
Factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory" %>

What do I need to do differently.

Thanks

Cragly



On Mar 27, 9:49 pm, LOBOMINATOR <lobomina...@gmx.ch> wrote:
> Hy
> This happens when IResolutionRoot is null. What version of wcf extension do yoy have? Are you using the latest? If yes you need to set the kernel by using the static SetKernel method on the ninjectservicehostfactory
>
> Seehttps://github.com/ninject/ninject.extensions.wcf/blob/master/src/Nin...

LOBOMINATOR

unread,
Mar 28, 2011, 10:11:17 AM3/28/11
to ninject
Hy

When I correctly see it you are using an older version which uses the
KernelContainer. You need to set the kernel on the kernel container.
See:

https://github.com/ninject/ninject.extensions.wcf/blob/52bb83728774701ec42b5f76b096bec934dfe419/src/Ninject.Extensions.Wcf/KernelContainer.cs

Daniel

[DRH] Rick Liddle

unread,
Apr 8, 2011, 2:41:32 PM4/8/11
to ninject
I'm having exactly the same problem Cragly is. Unfortunately,
LOBOMINATOR, I don't quite understand what you mean here:

"You need to set the kernel on the kernel container."

Can you provide a code sample or more information?

Thanks for your help.

- Rick

LOBOMINATOR

unread,
Apr 11, 2011, 3:15:24 PM4/11/11
to nin...@googlegroups.com
Hy

What version are you using? Latest?

https://github.com/ninject/ninject.extensions.wcf/blob/master/src/Ninject.Extensions.Wcf/NinjectServiceHostFactory.cs

Has a setkernel method. You need toset the kernel so that it is known to the servicehostfactory

Daniel

[DRH] Rick Liddle

unread,
Apr 11, 2011, 4:30:16 PM4/11/11
to nin...@googlegroups.com
Daniel -

Thanks for your input. I appreciate the help.


What version are you using? Latest?
We are using Ninject v2.2.1.0 and Ninject.Extensions.Wcf v2.2.0.0.

You need toset the kernel so that it is known to the servicehostfactory
The abstract base for Global.asax (NinjectWcfApplication) instantiates the kernel and sets it on the KernelContainer, so this is already being done.

We have discovered that if the first request to a WCF service is via NET.TCP or NET.PIPE, Global.asax will not fire the Application_OnStart event because Global.asax is derived from System.Web.HttpApplication and a NET.TCP or NET.PIPE request doesn't activate it because it's not an HTTP request. I've found some general workarounds for this type of problem here and I'll try to implement one of those and post back with my results.

In the meantime, if anyone else has a solution, I'd love to hear about it.

Thanks.

- Rick

LOBOMINATOR

unread,
Apr 12, 2011, 12:07:42 AM4/12/11
to nin...@googlegroups.com
Hy

Could you please describe a bit your setting? 

In the meantime I suggest you upgrade to 2.3. Remo has chanced the webapp part. There is now a ninject web common and the activation pipeline is different.

What I don't understand is why it does not work. Could you try to self host the services?

Daniel
--

LOBOMINATOR

unread,
Apr 12, 2011, 12:30:05 AM4/12/11
to nin...@googlegroups.com
By the way you can send me a stripped down solution if you want. Then I can understand your issue.

Lobominator at gmx dot ch

[DRH] Rick Liddle

unread,
Apr 12, 2011, 8:48:03 AM4/12/11
to nin...@googlegroups.com
A little more information (for future reference) and a solution:

The issue was only actually occurring if the Net.Tcp request was the first request to the service or its hosting web application. If the web app was activated via Http, the Global.asax (which derives from NinjectWcfApplication) would fire Application_Start and create the kernel. However, if the first request was via Net.Tcp, Application_Start wouldn't be processed because it's based on Http, not Net.Tcp.

We handled the problem by creating our own ServiceHostFactory in the hosting application and overriding the CreateServiceHost method. Additionally, we specified our new class as the factory in the service's markup. Sample code is below:

public class ApplicationServiceHostFactory : NinjectServiceHostFactory
    {
        protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            lock (this)
            {
                if (KernelContainer.Kernel == null)
                {
                    KernelContainer.Kernel = new StandardKernel(new ServiceModule());
                }

                if (KernelContainer.Kernel.GetBindings(typeof(ServiceHost)).Count() == 0)
                {
                    KernelContainer.Kernel.Bind<ServiceHost>().To<NinjectServiceHost>();
                }
            }
            return base.CreateServiceHost(serviceType, baseAddresses);
        }
    }
}
And in the ServiceHost tag of Service's markup:

Factory="Assembly.ApplicationServiceHostFactory"
Reply all
Reply to author
Forward
0 new messages