Organize WCF service to avoid circular references - c#

I have three C# (.NET Framework) projects:
A server project
A client project
A WCF service project
Inside the server project, I host the WCF service like so:
Uri baseAddress = new Uri("http://localhost:8000/");
ServiceHost selfHost = new ServiceHost(typeof(MyService), baseAddress);
// Some additional logic in here, not important...
selfHost.AddServiceEndpoint(typeof(IMyService), new WSHttpBinding(),
selfHost.Open();
Console.WriteLine("The WCF service is ready.");
Where my WCF service looks like this:
public class MyService : IMyService
{
public IEnumerable<ISessionModel> DoWork()
{
// Now I want to call methods on the server project,
// but I can't do that because I can't reference the server project.
// This would create a circular dependency.
}
}
Here's the problem:
I can't reference server methods from the service, as that would require a circular dependency. The service is already referenced by the server because the server needs to host the service.
One solution to this would be to just define the WCF service interface WCF project, and define the implementation of that interface in the server project. But I'm not sure how to do this. As far as I know, the WCF service has to be in its own special service project.
Any help would be greatly appreciated!

Related

Consuming WCF Service (nettcp) from Asp.net core using WCF client library

We have a WCF service hosted as nettcp mode and WCF client library, both services and client has been created using .net framework.
Now we are creating new application using Asp.net core 2.1, still here we need to consume the above created WCF Service using the same old WCF client Library.
Added this WCFClient library reference(.net framework) into our Asp.net core application. Here am using the below proxy constructor to pass my end point details.
public LoggingServiceProxy(Binding binding, EndpointAddress remoteAddress)
: base(binding, remoteAddress)
new LoggingServiceProxy(new EndpointAddress("net.tcp://localhost:9100/LoggingService/Tcp"), new NetTcpBinding(SecurityMode.None));
After adding System.ServiceModel.NetTcp and System.ServiceModel.Primitives NUGET references, resolved all other errors. But code thread aborted abruptly when it executes the proxy code
((ICommunicationObject)this.channel).Open();
No more information, debug message available after this point. No exception raised.So we have no clue on what is it?
Note: When I stop my service to test, I clearly get exception "EndPointNotFound".
Expected behaviour is to able to consume the service from Asp.net Core application -> WCF Client Library(.net framework) -> WCF Service nettcp (.net framework)
After did more dig into the auto generated proxy code, found that this issue is happening in the event of InnerChannel_Opened() and InnerChannel_Closed()
Above event got the following line of code "lock (this.channelLock)" which causes the issue. No exception raised. simply thread aborted/exited. When comment it out these events, it works fine, but am not too sure whether it is ok to comment these auto generated code.
lock (this.channelLock)
{
if (this.IsDisposed)
{
throw new InvalidOperationException("Cannot use disposed object.");
}
if (this.Opened != null)
{
this.Opened(sender, e);
}
}

WCF service in a prism module

First, I created a WCF service (netTcpBinding) hosted by a server application and all work fine (tested with a client application).
Then, I imported the same service class in a prism module (IModule). In the module, I create an instance of the ServiceHost by using the service class type:
public ServiceHost Host = new ServiceHost(typeof(MyService));
In the initialization step, I open the connection:
try
{
host.Open();
}
catch (Exception ex)
{
log.Error(ex, "SAP service starting is failed.");
throw;
}
When I attempt to connect with a client application to the WCF service, no error is occurred: Address, binding and contract are found in the configuration file, the instance of the ServiceHost is correctly created and gets the status "opened", the socket connection is opened. From the client application, I am able to perform a call to a method of the service (no error occured to the socket opened by the server) but the service doesn't receive the call: a break point at the top of the called method is not hit during a debug session of the WCF service.
When I add a service behavior (httpGetUrl and httpGetEnabled to true) in the configuration file to get the WSDL information, the link does NOT occur any error but the page stays blank and its title keeps as information "Loading ..." (no WSDL generated).
If I move the service class and the creation of the service host to the prism executable project (.exe) which initializes the modules, the WCF service works fine !
By adding the diagnostic tools in the configuration file of the service () and by calling the "test" method, I can see the last logs:
Any idea ?
Can we create a service host in a library project working like a prism module ? Is there any contraindications ?
I've found ! But nothing linked to prism or unity.
The application set an notify icon in the right bottom of the screen. This notify icon has a context menu to finish the application. The notify icon is associated to the thread of the application.
Later, I added TopShelf to start the service. It seems that the adding of the context menu occurs a problem. I have no exception but well the problem described above. The removing of the context menu solves the issue.
There is no contraindications to define a WCF service host in a prism module. That works perfectly.

Windows Service hosting WCF - Can I stop Windows Service from within a WCF service?

I have a Windows Service hosting a WCF service. If something goes really wrong in my WCF service I'd like to stop the Windows Service. I could try and force it to stop by shelling out and using net stop but is there a 'nicer' way to do this?
WCF is run the usual way from windows service:
protected override void OnStart(string[] args)
{
if (serviceHost != null)
{
serviceHost.Close();
}
///WCF service hosted
serviceHost = new ServiceHost(typeof(XXXService));
serviceHost.Open();
}
In the past, we have implemented our self-hosted WCF Windows Services with a “Service Host Controller” class that holds references to the ServiceHost objects and is therefore responsible for “starting”/opening and “stopping”/closing the service host object. In addition, the “Service Host Controller” class implements a delegate that allows the hosted objects to call back into the controller and initiate a graceful shutdown.

How to add wcf service at runtime

How can i add wcf service at runtime in my winform UI.
I created a wcf service which return running processes of hosted machine. I want to add the hosted machine service in my winform application.
You need to change endpoints dynamically at runtime, so You need WCF Discovery.
Structure :
WCF Consumer(s) <---> WCF Discovery Service <---> WCF Service(s)
Implementation :
How to: Implement a Discovery Proxy
How to: Implement a Discoverable Service that Registers with the Discovery Proxy
How to: Implement a Client Application that Uses the Discovery Proxy to Find a Service
Topology :
Start Discovery Service [ Structure BackBone ]
Start Service(s) [ Every Service will ANNOUNCE its startup to the Discovery Service ]
Start Client(s) [ Every Client will DISCOVER ( FIND & RESOLVE ) Services' endpoints from the Discovery Service ]
Notes :
Discovery process uses UDP ( Check your Firewall, It can block connections )
Services MUST announce their startup, thus Self-Hosted services is OK, but IIS-Hosted 5/6 ones is NOT because they started automatically when 1st invoke happends !
Solving IIS-Hosted 5/6 Issue :
By Extending Hosting Using ServiceHostFactory
So that you can start your IIS-Hosted 5/6 services manually without being invoked for the first time
You can also use WCF Routing Service.
BROTHER TIP :
Don't go far for a Serverless ( No-BackBone, No-BootleNeck, Fully-Distributed, .. etc ) ideal topology, this'll blowup your head and got you crazy :D
For a beginner, I suggest you this tutorial [ WCF Tutorials ]
not sure what you are trying to do here. But you need to know two things to call the WCF service 1) Service Contract 2) End Point. Now there is no escaping from Service Contract as you need to know what all operations you can consume. However, with WCF 4 there is a new feature called WCF discovery which helps you determine the end point dynamically i.e. at RunTime. Refer to following link http://msdn.microsoft.com/en-us/library/dd456791.aspx
If I understand you question properly you need some code that will add service in run-time without using any configuration in *.config file and *.svc files.
See that sample:
Uri baseAddress = new Uri("http://localhost:8080/hello");
// Create the ServiceHost.
using (ServiceHost host = new ServiceHost(typeof(HelloWorldService), baseAddress))
{
// Enable metadata publishing.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
// Open the ServiceHost to start listening for messages. Since
// no endpoints are explicitly configured, the runtime will create
// one endpoint per base address for each service contract implemented
// by the service.
host.Open();
Console.WriteLine("The service is ready at {0}", baseAddress);
Console.WriteLine("Press <Enter> to stop the service.");
Console.ReadLine();
// Close the ServiceHost.
host.Close();
}
It creates self-hosted service in console app.
http://msdn.microsoft.com/en-us/library/ms731758.aspx
Is that what you asked?

How to notify the host of a WCF service when a client connects?

I have a WCF service that is hosted by a windows service. I can't figure out how to inform the windows service when a client connects to the WCF service. Basically all I have in the windows service to start the WCF service is this:
private ServiceHost sHost;
WCF.WCFService wcfService = new WCF.WCFService();
sHost = new ServiceHost(wcfService);
sHost.Open();
I am able to call methods in the WCF service with the windows service using the wcfService object. Is there some way to have some kind of event that would fire when a client connects to WCF service?
The service runs as an object which is instantiated according to the ServiceBehaviourAttribute property InstanceContextMode
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class MyService : IMyService
{
// ...
The values for InstanceContextMode are
Single - a single instance of the service runs for all sessions and calls
PerSession - an instance of the service runs for each session (i.e. each client)
PerCall - an instance of the service is instantiated for each call, even from a single client
The default value is PerSession, and this makes sense for most scenarios. Assuming you're using PerSession, you can put whatever 'connect logic' you like inside the constructor for the service.
// you don't need to specify PerSession as it is default, but I have for clarity
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class MyService : IMyService
{
public MyService()
{
// constructor will be called for each new client session
// eg fire an Event, log a new client has connected, etc
}
// ...
}
You need to be careful running code in the constructor, because the service will not be available until the constructor has completed. If you want to do anything that may take time, fire an event or send a thread to perform that work.
I found the best answer here: Subscribe to events within a WCF service
As suspected you can create an event handler in the WCF service that can be picked up by the host.

Categories

Resources