I am writing a dll that is referencing to some WCF service.
The dll is functioning as a Gateway of the service and all calls are going through it.
Probably there can be concurrent calls .
I have referenced the service but now I cannot decide how to write the wrapper functions correctly.
Is there some example or best practice for this functionality.
I would make wrapper that matches the web service interface. It would also be a good idea to wrap up all of the objects exposed. Basically create a proxy. What I find really useful for this type of thing is to create an interface that matches the API and implement that. That way, you can create a dummy version of the DLL for testing without the overhead (or potential costs) associated with the WCF call. It would also make it much simpler if you need to replace the WCF call with an alternate provider in the future.
As an example, lets assume that we have an WCF service to an external provider for processing a payment. Something like this:
void ProcessPayment(float amount);
We could easily hook this into our code. The problem is that a simple change to the interface would result in us having to make changes everywhere the code is referenced. The same would be necessary if we changed providers to someone else, even if the interface was almost identical. Adding something like a simple interface:
interface IPaymentProvider
{
void ProcessPayment(float amount);
}
Would completely decouple our code from the WCF service. We could easily build a class like this:
class PaymentProviderAWrapper : IPaymentProvider
{
void ProcessPayment()
{
// Call the WCF service
}
}
That we could load dynamically with a factory or dependency injection framework like Spring.NET. Changing to a provider B would be as simple as creating a new wrapper:
class PaymentProviderBWrapper : IPaymentProvider
{
void ProcessPayment()
{
// Call provider B's Native DLL
}
}
Switching your code from provider A to B would be as simple as changing a configuration setting.
Even if we compiled the library directly into our code, all we would need to do is change the construction logic to use the new library. The rest of our application would not change at all. Just a simple recompile.
In response to Graymatter's answer I don't see what the difference is between calling a service wrapper which exposes the same calls and then forwards the calls to the real service, and just calling the service, assuming a one-to-one mapping on individual calls and no change in transport binding.
The only reason you would want to create a wrapper in the first place is that the interface exposed in some way does not meet your requirement on it's own. There are several reasons you may want to do this but a few common ones:
Protocol translation - the service is not exposed across the correct transport binding for your needs
Service Composition - the interface operations are too granular and don't represent business-level operations.
Authentication - perhaps you require an authentication layer on top of the endpoint you are consuming.
So how to wrap the service endpoint depends on why you want to wrap the service...
Related
I am trying to improve the speed of a C# job, let's call it 'WidgetProcessor'. In one run, WidgetProcessor will process about 5,000 widgets and take about 12 hours to complete (about 8 seconds/widget).
WidgetProcessor makes references to 3 different web services and calls them multiple times for each widget processed. There are various performance/design improvements that can be made to the 'WidgetProcessor' program, but I want to test if the multiple web service calls over the network cause the job to run slow.
I have the source code for each of the three web services (and have access to all of the resources those web services use), and I'm wondering if there is a way to easily use the web service interfaces in WidgetProcessor by referencing the web service projects themselves (instead of calling the web service over the network). The web services are implemented in C#.
I would reference the service implementation classes directly, but the main problem I'm running into is that the web services have collectively about 100 data contracts and the public facing names are different than the implementation classes.
[DataContract(Name = "WidgetInfo")]
public class WidgetDataContract
{
// DataMembers
}
Thus, referencing implementations directly means I'd be making many code changes in WidgetProcessor. Rather, I'd like to use the service interfaces, so that code changes can stay at a minimum.
Basically, I want a service in my WidgetProcessor solution that looks and acts like a web service, but doesn't perform its operations over the network.
Is this even possible?
You can add adapter classes which subclass the implementation with the name specified in the datacontract:
public class WidgetInfo : WidgetDataContract { }
If you are finding the overhead of the service call to be overly expensive, you may see benefit of going to a different binding or serialization format. WCF can approach in-process speed when tuned properly.
Edit: If you are intent on not modifying any code, you do have a couple options, but I think they are solutions in search of a problem:
Mono.Cecil or Roslyn to automatically map between the classes pre- or post-build
For only the types, you could use TypeForwardedToAttribute, but property access is problematic. This may be dependent upon placing the svcutil generated classes in another assembly.
Use Castle to build dynamic proxies and map access based off of attributes
I have a WCF service with the service file as - Serivce.svc
Here I can read incoming headers using the WebOperationContext.Current
The code from the Service file access a data access utility layer which makes other calls; I need to to do some work in the data access layer based on the header passed in.
However, the WebOperationContext.Current is null here.
How do I get around this?
From your question, it seems your "data access utility layer" is dependent on information that was passed to the service through the headers. Make this explicit, preferably through an interface so it's easily testable. Something like this:
public class DataAccessLayer(IMetaInfoFromHeaders requiredInfo)
{ /* implementation */ }
(Alternatively you could just have the IMetaInfoFromHeaders be an argument for just one or a few methods in the DAL, if that seems better - this depends on the specifics.)
Your service is responsible for processing the message. It should extract the information from the headers, and pass it to the DAL using an object implementing IMetaInfoFromHeaders.
Bottom line: don't make the DAL dependent on the WebOperationContext.
I've just begun learning WCF, and I'm coming from a total non-web background.
I have built a 3-tier desktop application, which compiles into one exe, which runs locally.
Now I want to move the whole business logics layer to a centric server, and make the GUI a client application.
As far as I understand, WCF should be my solution, as indeed, it helped me achieved what I wanted.
I mange to run remote functions, which is the basic of what I need.
My problem now, is that I don't quite understand the architecture.
For example, one of my services, returns a data type (class), from my Business Logics layer.
This class automatically becomes available to the client through the WCF mechanism.
But the problem is, this class contains some methods, which i definitely do not want to expose to the client.
For example a Save method (saves to the db).
Further more, sometimes I don't even want to allow the client to change all the properties of the class, since this class might be sent to one of my services.
I do not want to re-validate the class instance in the service.
What should I do? Should I build another layer, restricted version of the Business Logics, which I expose to the client? Or is there any way expose only part of my class to the client, without restricting the server it self?
I know this is a basic question, but honestly i've searched a lot before asking here. My problem is I don't quite know what to search.
My second question is then, do you have any recommendation for any resource that can explain me this architecture...?
Typically, if you want to encapsulate your business layer, you would not want to expose the business objects directly. This is because you now have a de-coupled client and you don't necessarily want to have to update the client every time the business logic/properties change.
This is where Data Transfer Objects (DTO) come into play nicely. Usually, you want to have control over your contract (data and methods) that you expose. Therefore, you would explicitly make other objects (DTOs) that make up the transfer layer. Then, you can safely change your client and server code independently (as long as both still fulfill the contract objects).
This usually requires a little more mapping (before you send or receive on each side) but it is often worth it.
For WCF, your interfaces and classes marked with [ServiceContract] and your classes marked with [DataContract] usually make up this transfer layer.
In WCF to expose method to client you have to mark it with OperationContractAttribute. So if you don't want clients to use your Save method, just don't mark them with with this attribute.
More info here: http://msdn.microsoft.com/en-us/library/system.servicemodel.servicecontractattribute.aspx
Pretty much same thing with properties, but different attribute: DataMemberAttribute. If you don't wont client to see it, just don't mark them with it (DataMember attribute)
But the problem is, this class contains some methods, which i definitely do not want to expose to the client.
Are you able to provide an example of your class and interface code? If so I'm sure you might be able to get more specific answers.
For example a Save method (saves to the db).
One possible approach would be to separate your class into 2 classes. Define the properties in the first class and then use that class as the base class of your second class. Then use the second class to define the methods. This would allow you to return only the properties while allowing you to keep your code DRY.
Further more, sometimes I don't even want to allow the client to change all the properties of the class, since this class might be sent to one of my services.
I do not want to re-validate the class instance in the service.
While you are able to define logic in the get and set methods for each property I would highly recommend revalidating any input received between services simply because any future changes or errors in one service could potentially lead to larger problems across your application. In addition this also helps to ensure your application is more secure against any potential attacks.
Should I build another layer, restricted version of the Business Logics, which I expose to the client? Or is there any way expose only part of my class to the client, without restricting the server it self?
I agree with the above answers that you should be able to limit access to the different properties and methods using the data and method attributes within your interfaces.
My second question is then, do you have any recommendation for any resource that can explain me this architecture...?
If you are looking for inexpensive but highly valuable video based training I've found the courses that Pluralsight offers to be quite good for both architecture as well as WFC services (btw, I am not associated with them, just enjoyed their training).
I have some member functions in three custom classes already created in my service. My objective is to use these custom classes on the client side to access the the member functions in the service. How do I expose these classes with all the member methods in them to the client?
I created these three classes in my service and marked them as "DataContract", and the member functions as "OperationContract". I created an Interface that defines these custom classes as OperationContracts returning an object of each of the classes through implementing them on a separate class.
Unfortunately, I couldn't achieve my objective because two of the classes have a constructor that takes some parameters, whereas the class with no constructor was accessible on the client side but I couldn't see the member methods in the class.
I need your hints on what to do.
That won't be easy to do. One way would be to share the DataContract-decorated types between the WCF server and its clients, i.e. add a reference to your service assembly in the client project and bind the service reference to that assembly reference.
However, that breaks contract implementation independence, as the exact same service assembly will need to exist on both the client and the server, and be kept synchronized every time it changes.
See here for more details.
By default and by design, WCF will only share contracts between client and server, e.g. your services ([ServiceContract]), their methods ([OperationContract]) and the data structures they operate on ([DataContract]).
WCF is a message passing system, so all the client and the server share in terms of the data being passed around is a XML serialized message format. When you add a service reference, the client-side proxy will generate a class for each [DataContract] that will look identical in XML serialized format - only the data is being moved back and forth - no behavior (no methods).
Basically, if you want to expose functionality, you need to have a service method decorated with a [OperationContract] attribute. Methods on your data classes will never be visible to the client - and that's by design.
If you control both ends of the communication and both are .NET based, you can "trick" your way around this limitation:
put all your service and data contracts into a separate class library assembly
use a reference to that common, shared assembly to create your service
before you do an Add Service Reference, add a reference to that common assembly on your client
In that case, the WCF runtime will reuse existing types from that common assembly, instead of re-creating them from the service description. And since that assembly contains the shared code that the server also uses, your classes also have their methods present.
It works ok in a .NET only scenario, but it's really kind of a dirty trick behind the proper service separation facade.
My Situation:
The data request chain of my application looks like this:
(Client) -> (WebService) -> (SQL or OLAP Cube)
The client is a Silverlight Application that uses a generated proxy to communicate with a WCF webservice. Which in turn does authorization and accesses SQL DB's and OLAP Cubes using a DAL component, basically it just forwards the requests. Therefore, each method exists in four different places:
// WCF Webservice interface and implementation (used by client)
public interface ICatalogService
public class CatalogService : ICatalogService
// DAL interface and implementation (used by webservice)
public interface ICatalogDataAccessLayer
public class CatalogDataAccessLayer : ICatalogDataAccessLayer
Now my question, where should I put documentation to clearly specify these methods? On class or interface level, on the DAL or on the webservice?
My thoughts so far:
I would say it makes most sense to write the method specs on the interface, because it is the contract that is being consumed. However I don't see an advantage between webservice and DAL in my specific situation:
I am the only developer, there is no separate webservice-guy or client-guy that needs the docs
This is a closed architecture, the webservice is not public
Everyone working on this project in the future, will have access to all components of it (and will find the docs, wherever they are)
So, what do you think about it? Where should I put method-level documentation in this case?
I would think that most people would expect a web service to be documented more heavily than a DAL (especially if the DAL is mostly generated code: I'm guessing so as these are pass-through methods). I would add a pointer to the web service documentation in the DAL comments for those who work with it in the future.
The reason is twofold. First, the Web Service is the real point of interaction (and thus the point where more clients might be added, which means having the service documented is a plus). The second is that the DAL really doesn't sound like it provides "added value" over the Web Service (in the configuration described), so pointing back to the real point of interaction and value makes sense.
If the DAL was ever threatened with reuse by another client without the web service layer... obviously that changes things to lean the other way around (or to automate duplicate comments).