I have a WCF Service contract which is basically the Publish Subscriber pattern.
The WCF Service is hosted inside the Windows Service that I want to publish from. The Clients subscribe to messages and when the Windows Service does something it publishes to all clients.
To host the service I have declared a ServiceHost class and the Contract Class has a method which is not flagged in the Interface but is implemented in the Class to publish.
I want to be able to call this method locally (not going through WCF) which then publishes the message via Callbacks.
I can't seem to get from ServiceHost to the instance of the Contract Class.
Is this possible and if so how? I know the work around is to have a client built into the service as well, 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>
To open WCF Test Client, open Developer Command Prompt for Visual Studio and execute WcfTestClient.exe. Select Add Service from the File menu. Type http://localhost:8080/hello into the address box and click OK. Make sure the service is running or else this step fails.
This is referred to as a self hosting WCF service, the exact meaning of Self Hosted is that it hosts the service in an application that could be a Console Application or Windows Forms and so on. Earlier we saw what a WCF Service is in the . Net environment. We can host a WCF service in IIS and a Windows service also.
There are three types of hosting environments for WCF services: IIS, WAS, and self-hosting. The term “self-hosting” refers to any application that provides its own code to initialize the hosting environment. This includes console, Windows Forms, WPF, and managed Windows services.
WCF uses the listener adapter interface to communicate activation requests that are received over the non-HTTP protocols supported by WCF, such as TCP, named pipes, and Message Queuing.
Old question, but here is another way to call a Singleton WCF Service hosted on a Windows Service
Following @Ben's requirements, the Service
would need to be forced to be a Singleton
:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
Then:
var host = new ServiceHost(typeof(MyService), myUri);
var instance = (MyService)host.SingletonInstance;
That's it. Basically, the host already has a property that needs to be 'casted' to be able to access all the features from the Service
.
Unless you provide the service instance reference to the ServiceHost as a constructor parameter,
This line from Sixto's solution solved things for me. Credit and thanks to this post as well.
I'm using a duplex binding at the moment.
The key concept is that you can pass in a Type
or an instance to the ServiceHost
constructor.
So what I had before was:
ServiceHost host = new ServiceHost(typeof(MyService), myUri);
What I needed was:
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 host's methods from inside the service.
However, keep in mind that the instance you created will not have an OperationContext
if you call its methods directly: https://stackoverflow.com/a/15270541/385273
Good luck!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With