How to add wcf service at runtime - c#

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?

Related

Organize WCF service to avoid circular references

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!

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.

Endpoint not found exception in a WCF Service

I'm approaching to WCF Service, starting with the tutorial provided by Microsoft. I created a very simple WCF Service (CalculatorService) and I've some doubts about the EndpointAddress of this service.
When I create the WCF Host, I set the Endpoint like this:
Uri baseAddress = new Uri("http://localhost:8000/GettingStarted/");
// Step 2 Create a ServiceHost instance
ServiceHost selfHost = new ServiceHost(typeof(Service1), baseAddress);
// Step 3 Add a service endpoint.
selfHost.AddServiceEndpoint(typeof(IService1), new WSHttpBinding(), "CalculatorService");
Everything works if I debug the entire solution, but, if I launch the WCFHost executing its .exe file, launching also the application of the Client gives me the following exception:
System.ServiceModel.EndpointNotFoundException: No endpoint listening in http://localhost:8732/Design_Time_Address/WcfServiceLibrary/Service1/.
The fact is that if I try to open a browser and search the address http://localhost:8000/GettingStarted/, I get correctly the page of the Service. I suppose that the Service is hosted at one address and the Client tries to access to it via a different one.
Could anyone help me to solve this issue?
If you have, in the client code, hard coded this address http://localhost:8732, then change it there. But your client is probably (you didn't put that info unfortunately in your question) automatically generated. In that case client config is in App.config file(if we are talking about your solution), and in config file of the .exe file when you build your project. You should look into your [ClientApplicationName].exe.config file and update the endpoint address to port 8000.

Can you do NetTcpBinding in code? Should you?

WCF newbie here... I'm trying to self-host a WCF service using NetTcpBinding. Based on the MSDN "how-to" tutorial I have done all the binding in code, which I then changed from WsHttpBinding to NetTcpBinding, and now looks like this:
var baseAddress = new Uri("net.tcp://localhost:8000/MyWebService");
var selfHost = new ServiceHost(typeof(ConcreteWebService), baseAddress);
try {
var binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.Message;
selfHost.AddServiceEndpoint(typeof(IWebService), binding, "TRWebService");
selfHost.Open();
Console.WriteLine("The service is ready at {0}", baseAddress.AbsoluteUri);
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
selfHost.Close();
} catch (CommunicationException ce) {
Console.WriteLine("An exception occurred: {0}", ce.Message);
selfHost.Abort();
}
Thing is, the tutorial then says you have to run svcutil.exe to generate a proxy for the client... but since I switched to NetTcpBinding, svcutil doesn't work anymore - can't detect my service. I googled the issue, and found that every single example out there of NetTcpBinding does the setup in the app.config file, not in code, and they all add an endpoint called "Mex", with binding type of "mexTcpBinding". There doesn't appear to be any equivalent of this in code.
So, do I have to change my project to use app.config, and abandon the code-based approach? Can anyone explain to me what Mex is, why I need it, and why it (apparently) can't be called in code - or if it can, how, or why is it discouraged? In general, when is it better to use app.config, and when code for WCF services?
If you use netTcpBinding - and in a "behind-the-corporate-firewall" LAN environment, it's definitely a great idea to do so - you need to also expose a MEX endpoint (Metadata Exchange) using the mexTcpBinding in order for svcutil to be able to detect and find that service.
MEX = Metadata Exchange is the mechanism that WCF uses to "publicly advertise" what a service looks like. If you have a MEX endpoint, then utilities like svcutil can query and "discover" a service, e.g. find out about all the service methods it exposes, about the parameters it expects to get and so on.
To add a MEX endpoint, you can definitely use code, too! Something like this fragment:
var mexBinding = MetadataExchangeBindings.CreateMexTcpBinding();
selfHost.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, "mex");
Without MEX, you need to somehow "tell" the client trying to consume your service what it is your service offers so that the client can make sure to call the proper methods with the proper parameters.

Programatically configure individual WCF operations with different WCF configurations

I am just getting started with WCF and would like to set up a distributable networked system as follows: (but am not sure if it is possible.)
I have a .net client that has business logic. It will need various data from various sources so I would like to add a 'server' that contains an in-memory cache but also WCF capabilities to send/receive and publish/subscribe from data sources for data that is not cached. I think it should be possible for these server applications to be identical in terms of code, but highly configurable so that requests could be dealt with in a peer to peer fashion, or traditional client-server as required. I think it could be done so that essentially a server sends a request to wherever it has the endpoint configured and gets a response.
Essentially a server would be configured as below:
Server A
========
Operation 1 - Endpoint I
Operation 2 - Endpoint II
Server B
========
Operation 1 - Endpoint IV
Operation 2 - Endpoint III
The configuration would be stored for each server in app.config and loaded into memory at startup. So each WCF operation would have its own WCF config (in terms of endpoints etc.) and it would send particular requests to different places according to that configuration.
From what I have read of WCF I think this is possible. I don't know have enough experience to know if this is a standard WCF pattern that I am describing (if so please let me know). Otherwise, my main question is, how do I programatically configure each operation (as above) in WCF?
Please let me know if I have not explained myself clearly.
Thanks in advance for any help,
Will
I don't know if this exactly will get you what you are looking for, but I this is what I use to add my WCF endpoints to my Windows Service. This is the code that the service runs to load all the wcf services:
IDictionary<string, ServiceHost> hosts;
NetTcpBinding binding;
CustomBinding mexBinding;
private void AddService(Type serviceImp, Type serviceDef, string serviceName)
{
ServiceHost host = new ServiceHost(serviceImp);
string address = String.Format(baseAddress, wcfPort, serviceName);
string endAdd = address;
string mexAdd = address + "/mex";
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
host.Description.Behaviors.Add(behavior);
host.AddServiceEndpoint(serviceDef, binding, endAdd);
host.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, mexAdd);
host.Open();
hosts.Add(serviceDef.Name, host);
}
There's a baseAddress string that I didn't copy in, but it just has the net.tcp address for the endpoint. Likewise for the wcfPort. Different baseAddresses and ports are used for debug, testing and production.
Just in case it isn't clear, serviceImp is the service implementation and serviceDef is the interface that defines the contract. Hope this helps.
EDIT - Here are some references I used to help me figure all of this stuff out:
Creating WCF Service Host Programmatically
Net.Tcp Port Sharing Sample, Part 2
Service Station: WCF Addressing In Depth
As far as I know you can't specify configuration on per operation basis. The lowest level is the interface level. The simplest (ugly) solution would be to put each operation in a separate interface.
Putting each operation in a separate interface is a valid and good design approach. Agatha Request/Response Layer follows this approach. Have a look at this and this is pretty useful and extensible
http://code.google.com/p/agatha-rrsl/

Categories

Resources