简体   繁体   中英

A service acting as client of its own

Consider this scenario:

  1. A WCF service is up and running.
  2. The service needs to call itself every once in a while.

What I did now is add a service reference to the same service and added an extra endpoint + client in the service configuration file. Working over net.tcp.

It works fine, but I read somewhere that you can use "in process" hosting to connect to a service without using a proxy. This way you can get rid of the configuration and have much cleaner code.

So instead of this with the accompying configuration settings:

DeliveryOwnClient.DeliveryClient deliveryObject = new DeliveryOwnClient.DeliveryClient("netTcpDeliveryService");

I want to use this without any configuration:

IDelivery deliveryObject = InProcessFactory.CreateInstance<DeliveryService.Delivery, IDelivery>();

But this throws an exception that "The ChannelDispatcher at http://localhost:8003/DeliveryService with contract "IMetadataExchange" can't open the IChannelListener. A registration already exists for Uri net.tcp://localhost:9003/DeliveryService"

The implementation for CreateInstance looks like this:

ServiceHost host = new ServiceHost(typeof(S));
string address = "net.pipe://" + Environment.MachineName + "/" + Guid.NewGuid();

host.AddServiceEndpoint(typeof(I), Binding, address);
host.Open();

So I'm adding a net.pipe baseaddress and it fails because there is something running over net.tcp already.

** edit **

Figured out at least why this is happening.

The service is configured in the app.config with two baseaddresses

<service name="DeliveryService.Delivery">
     <endpoint binding="netTcpBinding" contract="DeliveryService.IDelivery"/>
     <host>
       <baseAddresses>
         <add baseAddress="http://localhost:8003/DeliveryService" />
         <add baseAddress="net.tcp://localhost:9003/DeliveryService" />
       </baseAddresses>
     </host>   
</service>

When the host is constructed

ServiceHost host = new ServiceHost(typeof(S));                

It find that section in the config file and automatically adds net.tcp and http base addresses. I add net.pipe, but that doesnt matter. When the service is opened it finds that net.tcp is already running so it wont continue.

So I guess my question is changed into: Is it possible to construct a ServiceHost without having it read app.config?

Jay managed to figure it out! ServiceHost derives from ServiceHostBase and that class has a virtual function named ApplyConfiguration. So I made a class which derives from ServiceHost and overrides ApplyConfiguration...and leave it empty.

class ServiceHostNoConfig<S> : ServiceHost where S : class
{
    public ServiceHostNoConfig(string address)
    {
        UriSchemeKeyedCollection c = new UriSchemeKeyedCollection(new Uri(address));
        InitializeDescription(typeof(S), c);
    }

    public new void InitializeDescription(Type serviceType, UriSchemeKeyedCollection baseAddresses)
    {
        base.InitializeDescription(serviceType, baseAddresses);
    }

    protected override void ApplyConfiguration()
    {
    }
}

Use it like this:

        ServiceHost host = new ServiceHostNoConfig<S>(address);

        host.AddServiceEndpoint(typeof(I), Binding, address);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM