0

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
Wjdavis5
  • 3,952
  • 7
  • 35
  • 63
  • always include the full exception including stacktrace and inner exceptions. Can you check how many `IWebService` there are in the `IEnumerable webServices`? – BatteryBackupUnit Feb 09 '15 at 06:28
  • There are 2 items in the list because there are two services I'm trying to start. The exception mentioned is the inner ex. The outer is an invalid operation. I'll post the stack soon – Wjdavis5 Feb 09 '15 at 16:14
  • 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 – Wjdavis5 Feb 09 '15 at 20:47

1 Answers1

0

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

Wjdavis5
  • 3,952
  • 7
  • 35
  • 63