Referencing with WCF Webservice - c#

I have used web-services before and understand the concept. However now I have set up a WCF Webservice, but I have a question about the use of it. (In how the tutorial is set up.)
I have the following things set up:
WCF Service Library (Called CalculatorService)
Service Host (Called CalculatorServiceHost)
Service Proxy (Called CalculatorServiceProxy, is using ClientBase)
Service Client (Called CalculatorServiceClient)
How I understand it is as follows;
The Service Library contains the service/object that can be used in the webservice. Lets say it is a calculator with the method addition.
The Host makes this class with its functions available to the client side.
The proxy sends and receives the message from the client to the configured endpoint.
The client can call functions from the service through the proxy.
The tutorial sets up the proxy as follows:
public class MyCalculatorServiceProxy : ClientBase<ICalculator>, ICalculator {
public int Add(int num1, int num2){
return base.Channel.Add(num1, num2);
}
}
This means that in the Proxy I have to reference at least to the assembly which contains the ICalculator. The Client also complains of having no reference to the interface if it is missing a reference to the same assembly.
In this tutorial the interface and the class/service, that inherits the interface, are in the same assembly. Thus referencing the assembly for the interface on the client side means that you are also able to create an instance of the 'Calculator' class and don't even need the WCF Service to call the functions.
Does this mean that you always need two assemblies with WCF Services. One with the interfaces and one with the classes/services?
Correct me if I am wrong or if someone has some additional information/comments.

#Tim but what I am wondering is, if you reference an assembly with the
service contracts and implementation. Why use the services over a
webservice through a proxy. If you can call the functions right away
through the reference of the other assembly?
If you do that then instead of having one service that communicates with your database (for example) you've got every possible client of that service talking to your database instead. You'll have connection strings everywhere. If you need to modify the service code, you'll have to deploy the updates to more applications. You lose security, scalability, and maintainability.
But that's great for writing unit and integration tests.

Related

Mocking a WCF service based on a service reference

I have a service reference to a WCF service that is hosted by a customer. The service reference has an interface which defines the service contract. I would like to create a service object which implements this interface so that I can add an instance of this to a local Service Host for testing purposes. This way I can fake the data back while still using the same service definition (though making a local endpoint).
The problem I have so far is this: the service only has one method (right now), GetString. The contract auto-generated two methods, GetString and GetStringAsync. It turns out that when I make a service based on an interface, it automatically generates an async method for each of the defined methods. Which means that my new service now has four methods:
GetString
GetStringAsync
GetStringAsync
GetStringAsyncAsync
If you caught that middle section, there are now two GetStringAsyncs, which prevents the service from starting.
Is there a way I can host a service based on a ServiceReference so that I can keep the same interface? If possible, I would like to prevent just duplicating the defined methods of the service reference in a secondary, as then I can just update the definition and the compiler will notify me when there are new things I need to implement. Also if I do that, my client library (which I want to have as much shared code as possible) will have to have two separate service reference instead of just a configurable endpoint and remote host that I can pass into the client constructor.

WCF Client generation possible based on ServiceContract alone?

I have a Visual Studio Solution in which a WCF server is contained; the service is defined as an interface using the ServiceContract attribute. The service is finally hostes via an instance of ServiceHost using HttpBinding, which is the intended behaviour.
In the same solution, there is a client; currently the hosted service is consumed by starting the server manually and generating a proxy class using "Add Service Reference", which can be updated as soon as the server is running.
While this works in the sense that the outcome is as desired, I wonder if it is possible to remove the manual start of the server to update the service reference in the client. Is it possible to build the client by just sharing the DataContract attributed interface between server and client without actually running the server and importing the service definition manually in the client? If yes, how can it be done?
Another way is to use svcutil to generate proxy, but even that require WSDL metadata to generate proxy and that is usually available by starting service, you can save it once from the running server and you can use that to generate proxy without starting server later on.
see different options http://www.codeproject.com/Articles/33297/WCF-Proxy-Generation-Options
I personally like hand crafted client as I have better control on code/error handling and I can use shared DTOs from common dll.
Yes, you can use a common data contract, shared between the client(s) and host, to maintain the interface between both sides. That's what I do with this big data sync WS built on BasicHttpBinding.
In a nutshell, I have a host project, with a service contract and the functioning/processing code, referencing a very small project (and DLL) containing only the data contract class definition; just class, constructor, variables and in/out parameters.
That same small project containing the data contract is also referenced by a client-side project that handles all of the interaction between our client programs and the Sync WS. We actually have every web service call (from the simplest Ping() function to the most complicated RetryFileUpload() function) running through that data contract. All the string-based parameters and binary data is passed through the data contract class, then seriailized or deserialized on the receiving end.
Having said that, this approach only works when you have .NET code on both the client and host. We also have Android and iOS clients that are forced to emulate this behavior ... which isn't a big deal, obviously. But this is the approach we took.

Local and WCF design for a class

I have a class which does stuffs with database, I want it to be used in these two ways:
1: a dll which can be referenced and used locally with direct call.
2: can be hosted as a WCF service.
when it is hosted as a WCF service many clients can connect to it but when it is used as a dll it just has one client.
how should I design my class?
For example I want to use it like this in dll form:
var a = new A();
and then call a.DoSomething()
or host it in WCF service and call server.DoSomething() from my client.
put your class into an assembly of it's own along with any support classes it needs and just reference that assembly from your WCF service.
Put your "api" in an interface, implement it fully in your "work" assembly, then implement it in your WCF service, but just haave that act as a proxy. Using an interface will mean you don't miss anything in your proxy.

Share code between asmx and wcf

I've got wcf service. Also some our clients use delphi7 to consume our sevices. Delphi7 couldn't conusme wcf (even basicHttpBinding) so I have to create asmx analogue of my wcf web service. Now I'm searching better way build wcf and asmx service on the same code base. What is the preferable way to build, maintain two services with ths same code (the same methods,logic)
Thanks Andrew
Use a dynamic link library (*.dll) to house shared code, reference and utilise from both projects.
This way you have two services for appropriate platforms which just call methods exposed by the shared code-base, which, when edited in one place and further deployed, is applicable all callers.
Hi you could create a BusinessManager which encapsulates all the logic then from wcf or asmx you simply create an instance of it and call the proper method passing the actual parameters received from your caller.
I use the word BusinessManager to define the class has something to do with your own business logic, but it's simply a class, either static or not, I usually prefer to do not make such classes static.
You can easily add a plain old ASMX webservice to your existing WCF Service if it's already hosted in an ASP.NET Web Application/Site.
Right-click your project -> Add -> New Item
Select Web -> scroll to bottom -> Web Service.
Then have your web service call your WCF methods.
Delphi 7 supports calling out to COM (ActiveX) objects, does it not?
Why not build a COMVisible .NET client for your WCF service, and consume that in Delphi via a COM interface.
That way you don't have to maintain both an ASMX and a WCF service.

Extending a WCF service and its auto-generated client service reference

I am relatively new to .Net and C# development and am having an issue decoupling WCF services from an app into a network DLL I am creating. The DLL's goal is to offer a simple way to host and access a service from a server and client application and to add some functionality to the basic service for heartbeat and automatic reconnection without each application having to specify heartbeat methods in their WCF services and witho/ut having the apps manage a timer for automatic reconnection.
The DLL offers a ServiceServer and a ServiceClient class that have these goals:
ServiceServer :
Creates and manages the ServiceHost instance.
Host a service from outside the DLL (passed as a generic).
Add heartbeat operations to the service to be hosted, as well as other operations common to all our client/server apps.
ServiceClient :
Creates and makes the client service reference available to the client application. The service reference (auto-generated) is also passed as a generic from the application.
Add heartbeat methods to the service reference for the client, as well as other operations common to all our client/server apps.
Automatic reconnection using a timer or similar.
So far I have tried to use partial classes, generics and static extension methods without success. The issue is that to make my DLL completely decoupled I obtain and create the service reference and service using generics; I am unable to extend the received generic type using any of these approaches.
I am basically trying to extend the client service reference with additional methods to be able to send heartbeats and such without needing another independent connection and service (which would make the heartbeat ineffective), and without the client application having to know anything about sending heartbeats and automatic reconnection. Likewise, I want to extend the service that the server class receives as a parameter to add operations and the implementation of the server heartbeat code and eventually other common-to-all-apps methods too.
You might want to explore this solution for implemeting hearbeats automatically in a wcf services.
http://weblogs.asp.net/cibrax/archive/2010/05/17/enabling-service-availability-in-wcf-services.aspx
The solution also provides an extension method for the client.
Thanks
Pablo.
No it will not work this way.
When you define the service you first create one or more service contracts (best practice is to use interfaces). Service contract interface has to be marked with ServiceContract attribute and each exposed method used in service has to be marked with OperationContract attribute. Then you create service class which implements these interfaces. Such class can be exposed as WCF service with endpoint for each interface (service contract).
No other approach works. You can't add extension methods, use generic or whatever else to "extend" implemented service. What you can is to inherit existing service class and add additional interface. Obviously this is not no code solution unless you create some very advanced code to generate dynamic data type at runtime (= emitting MSIL at runtime).

Categories