Can I call a method in the Self-Hosted WCF Service locally?

I have a WCF service contract, which is basically a subscriber publishing template.

The WCF service is hosted inside the Windows service from which I want to publish. Clients subscribe to messages and when Windows Service does something that it publishes to all clients.

To host the service, I declared the ServiceHost class, and the contract class has a method that is not marked in the interface, but implemented in the class for publication.

I want this method to be called locally (not through WCF), which then posts the message through Callbacks.

I can't seem to get a contract class instance from ServiceHost.

Is this possible, and if so, how? I know that the work around is to have the client embedded in the service, but it seems a bit strange creating a client to connect to itself.

Thanks in advance

DJIDave

app.config

<system.serviceModel> <services> <service behaviorConfiguration="Processor.Wcf.ServiceBehavior" name="Processor.Wcf.ProcessorService"> <endpoint address="net.tcp://localhost:9000/processor/service" binding="netTcpBinding" name="procService" bindingConfiguration="netTcpBindingConfig" contract="Processor.Wcf.IProcessorService"/> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="http://localhost:8732/Design_Time_Addresses/Processor.Wcf/Service1/" /> </baseAddresses> </host> </service> </services> <behaviors> <serviceBehaviors> <behavior name="Processor.Wcf.ServiceBehavior"> <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> <serviceMetadata httpGetEnabled="True"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="False" /> </behavior> </serviceBehaviors> </behaviors> <bindings> <netTcpBinding> <binding name="netTcpBindingConfig" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> <security mode="Transport"> <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" /> </security> </binding> </netTcpBinding> </bindings> </system.serviceModel> 
+9
source share
4 answers

If you do not provide a service instance reference in ServiceHost as a constructor parameter, there is no way that ServiceHost will provide you with a reference to the service instance. If you provide a link to this instance, you are creating a single-user service, which is usually not a good idea.

In order to maintain the service as it is configured, you will need to call it through the client. It is actually easier than you think. Since your host code has access to a service contract, you can use it with the ChannelFactory class to get a proxy server for this service. Besides the service contract, all you need to provide is the endpoint name , and ChannelFactory will do the rest. The following is an example of how to do this:

 private IMyServiceContract GetLocalClient(string serviceEndpointName) { var factory = new ChannelFactory<IMyServiceContract>(serviceEndpointName); return factory.CreateChannel(); } 

UPDATE: Along with this, you should consider providing you a service to pull out the NetNamedPipeBinding endpoint to improve performance. This binding pretty much does everything in memory and is the fastest binding for the same machine service call.

+8
source

To create an instance of the WCF service more than once (not a single one), you can save a list containing each corresponding callback function specified here: mdsn . You can call the CallClients () method (from this MSDN example) from the hosting code directly, since it is a static member of the service class. This is the only other way I've found.

+3
source

If you do not provide a reference to the ServiceHost service instance as a constructor parameter,

This line from Sixto's solution solved everything for me. Credit and thanks to this post .

I am using duplex binding at the moment.


The key concept is that you can pass a Type or instance to the ServiceHost constructor.

So what I had before:

  ServiceHost host = new ServiceHost(typeof(MyService), myUri); 

I needed:

  MyService service = new MyService(foo); // Can now pass a parameter ServiceHost host = new ServiceHost(service, myUri); 

Also, I needed to mark MyService with

 [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 

... and now I can call the node methods inside the service.

However, keep in mind that the instantiated instance will not have an OperationContext if you invoke its methods directly: https://stackoverflow.com/a/167295/

Good luck

+1
source

Old question, but there is another way to call Singleton WCF Service hosted on a Windows Service

Following @Ben’s requirements, Service should be required to be Singleton :

 [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 

Then:

 var host = new ServiceHost(typeof(MyService), myUri); var instance = (MyService)host.SingletonInstance; 

It. In fact, the host already has a property that needs to be "cast" in order to gain access to all the functions of the Service .

0
source

All Articles