Search code examples
c#wcfninjectninject-extensions

A registration already exists for uri


I am working on a Generic WCF Host that scans a plugins folder and loads all assemblies that implement a type "IWebService"

I then use Ninject to start hosting the wcf service. All configurations are in the App.config.

This works great when there is only a single plugin to load.

But when I try to start() the second, it throws an exception stating "A registration already exists for URI"

I have 2 totally different services defined in the App.config so I'm getting really confused.

Here is the App.config

 <services>
      <service name="GenericWebService.WebService" behaviorConfiguration="defaultBehavior">
        <host>
          <baseAddresses>
            <!-- note, choose an available port-->
            <add baseAddress="http://localhost:8092/GenericWebService/service" />

          </baseAddresses>
        </host>
        <endpoint address="http://localhost:8092/GenericWebService/service" name="service1" 
                  binding="basicHttpBinding" bindingConfiguration="soapBinding" contract="GenericWebService.ICalculator"/>
      </service>

      <service name="GenericWebService.WebService2" behaviorConfiguration="defaultBehavior">
        <host>
          <baseAddresses>
            <!-- note, choose an available port-->
            <add baseAddress="http://localhost:8093/GenericWebService2/service"/>
          </baseAddresses>
        </host>
        <endpoint address="http://localhost:8093/GenericWebService2/service" name="service2" 
                  binding="basicHttpBinding" bindingConfiguration="soapBinding" contract="GenericWebService.ICalculator2" />
      </service>
    </services>

Here is how I am loading them and starting the host

private static void StartNinjectSelfHostFromPlugin(IEnumerable<IWebService> webServices )
        {
            foreach (var webService in webServices)
            {
                var ninjectType = (new NinjectServiceSelfHostFactory()).GetType();
                var wcfConfiguration = typeof (NinjectWcfConfiguration)
                    .GetMethod("Create", Type.EmptyTypes)
                    .GetGenericMethodDefinition()
                    .MakeGenericMethod(new[]
                    {webService.GetType(),ninjectType })
                   .Invoke(null, new object[]{});
                var x = new NinjectSelfHostBootstrapper(CreateKernel, wcfConfiguration);
                _selfHostBootstrappers.Add(x);
                x.Start();
            }
        }

Any suggestions would be appreciated.

Update The Exception

System.InvalidOperationException: The ChannelDispatcher at 'http://localhost:809
2/GenericWebService/service' with contract(s) '"ICalculator"' is unable to open
its IChannelListener. ---> System.InvalidOperationException: A registration alre
ady exists for URI 'http://localhost:8092/GenericWebService/service'.
   at System.ServiceModel.Channels.UriPrefixTable`1.RegisterUri(Uri uri, HostNama
eComparisonMode hostNameComparisonMode, TItem item)
   at System.ServiceModel.Channels.HttpTransportManager.Register(TransportChanne
lListener channelListener)
   at System.ServiceModel.Channels.TransportManager.Open(TransportChannelListene
r channelListener)
   at System.ServiceModel.Channels.TransportManagerContainer.Open(SelectTranspor
tManagersCallback selectTransportManagerCallback)
   at System.ServiceModel.Channels.TransportChannelListener.OnOpen(TimeSpan time
out)
   at System.ServiceModel.Channels.HttpChannelListener`1.OnOpen(TimeSpan timeout
)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout)
   --- End of inner exception stack trace ---
   at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open()
   at Ninject.Extensions.Wcf.SelfHost.NinjectWcfSelfHost.Start()
   at Ninject.Web.Common.SelfHost.NinjectSelfHostBootstrapper.Start()
   at TestApp.Program.StartNinjectSelfHostFromPlugin(IEnumerable`1 psoWebService
s) in c:\Users\william.davis\Documents\Visual Studio 2013\Projects\Service\TestA
pp\Program.cs:line 80

Solution

  • After a massive amount of refactoring, I have this working, but I dont know if it is 'correct.' To get it working I had to basically create a new IKernel inside of my webservice class and also have it inherit from NinjectModule and configure bindings in there as well. Why do I need multiple Kernels to make this possible? I should add that if I dont need Ninject this works by using a standard ServiceHost