I'm building an application with a Silverlight frontend that communicates with a backend service via WCF. My service has an interface that handles all of the core communication with the frontend.
The backend can be extended with various plugins and I plan on loading custom silverlight modules for configuring these plugins with prism. The problem is, these plugins will add additional functions that aren't part of the base WCF interface. I'd like to maintain a single endpoint for all my communication (i.e. not requiring additional router configuration).
I'm looking for some ideas on how to approach this implementation. My "best" thought at the moment is to have a function in my core interface that accepts a function name and a list of parameters, and using reflection to find the function to call in the specific plugin, I'm not a fan of this for many reasons.
What are your recommendations for building an extensible WCF interface on a single endpoint?
Thanks
I can think of two ways this is typically handled:
XML contracts - basically, your service becomes nothing more than an XML parameter, with an XML return value. Then, you can either parse or serialize/deserialize the command going between the client and the server. Because your contract only exposes the single XML, what you do "inside" is up to you. You can do things like transmit schemas for the new methods to validate calls constructed on the client, etc.
RESTful service - this is another easy way to do it. Because the REST contract is the URL, adding a new extension is as simple as providing a new URL format. You could communicate via a formatter to the client how to invoke new calls for the extension methods and manage these as you build out the application.
Realistically, however, I doubt your font-end is going to be able to handle all edge cases and dynamically build new screens and validations as you extend the server side. In this case, a better approach in my opinion would be to construct the Silverlight application as a module application using MEF. When you have an extension on the server, you can simply provide an extension XAP for the client. You can have the server enumerate XAP files in a directory for plugins and send these to the Silverlight application, so when a new one becomes available it can dynamically load these. The XAP would contain the code to wire to the new WCF contracts for the extended functionality.
Related
I have one ServiceStack application with one class named Performance in this application.
Now, I have another application which is used by my end user. This is a console application, downloaded by end user and run as a background task.
I want to POST the performance data from that application to my REST web service and store it in a database.
For that I need to run this in my client application, which posts the performance data to my ServieStack application in JSON format:
JsonServiceClient client = new JsonServiceClient("http://localhost/RestIntro");
var res = client.Post<Performance>("/Performance", c);
I don't have Performance class in my client application. I don't want the client to have the class so that I can update all clients if I need to make a change.
I want to know, how can I get the Performance class or its DLL in to my client application dynamically? So when the client runs it will have the class in order to make the post to the web service.
I recommend that you keep the DTOs of your ServiceStack web services separate in a dependency-free project as this is what represents the contract or API of your services. If it's in its own assembly than you can easily share it with any of your clients or unit tests, etc.
If you don't like the idea of copying a dll around (even though its less work/friction), you can generate your own DTOs from the xsds on the /metadata page, see this question:
How can i convert XSD file to C# Class
What you are talking about is actually available by using a SOAP service. Or, you need to create a "performance" class on the client and deserialize the JSON result to that class.
My understanding is that a c# based client "prefers" SOAP because when you add a web service reference it creates a proxy class from the wsdl found at the url you specify.
Which almost makes it transparent to the c# client that we are even using a web service, it almost feels like we are using a local class library. you call methods and you use objects.
My question is can REST achieve the same affect. I assume that it can't since it doesn't have wsdl and thus visual studio can't generate a proxy class for it. But Please correct me if I'm wrong?
A "run of the mill" REST service cannot achieve the same kind of tight integration with C# - mostly because it lacks the metadata that a SOAP service will provide (with a list of methods and their parameters and all that stuff).
The WCF Data Services (built on top of REST) do work much the same way as SOAP services, since the OData protocol contains extensions for pure REST services that provide metadata information needed to create a good, useful client-side proxy.
REST can be used to generate client side class libraries. For Example You can create proxy classes for MS generated REST services. In fact MS is actively pushing this model for Entity Framework based WCF DATA Services, e.g. those used by Silverlight and RIA applications. check out MS ODATA framework for REST which involves creating client objects out of standard REST queries.
http://msdn.microsoft.com/en-us/library/dd673930.aspx
I've recently discovered a way to implement RESTful services using Global.asax (by handling the Application_BeginRequest event). Basically, I am saying it is possible (and easy) to implement a RESTful web service in classic ASP.NET, without any need for WCF.
It takes approximately 30 lines of code to figure out which method you want to call (from the URL) and pass it parameters (from the query string, via reflection) as well as serialize the result using XmlSerializer. It all leads to a web service that can be accessed through HTTP GET requests, and returns standard XML data.
So with that in mind, is there any reason to use WCF when creating a RESTful web service that will be invoked only through HTTP GET requests? WCF introduces a lot of overhead and restrictions, whereas the Global.asax approach I described above is much easier to implement, customize, and deploy.
Note - JSON endpoints can also be implemented without WCF by using the JavaScriptSerializer.
Also - HTTP POST requests can be handled by Global.asax in a similar way.
So in the end, what would be the reason to use WCF in such a case? Is there better scalability or performance?
You can also use Asp.Net MVC to implement REST quite easy.
What you don't get for free with this approach is:
non-HTTP bindings.
support for multiple message formats.
non-IIS hosting.
control over the process activation.
control over the instance creation.
object pooling.
message queueing.
transactions.
scalability and reliability.
additional technologies built on top of WCF like the OData support.
If none of these applies to your scenario - you don't need WCF.
The answer is, 2 different pipelines, but the WCF pipeline was built specifically for services, and ASP.Net was built for rendering content via HTTP. Both have their pluses and minuses.
If you are comfortable with the ASP.net stack, and don't have to worry about things like standards, then ASP.Net is fine.
But if you want the best of both worlds, try WCF Data Services, all the cool built-in features of WCF, with none of the hassles. Currently, MVC does not have a view engine to generate OData.
Following the KISS principle, I suddenly realised the following:
In .NET, you can use the Entity Model Framework to wrap around a database.
This model can be exposed as a web service through WCF.
This web service would have a very standardized definition.
A client application could be created which could consume any such RESTful web service.
I don't want to re-invent the wheel and it wouldn't surprise me if someone has already done this, so my question is simple: Has anyone already created a simple (desktop, not web) client application that can consume a RESTful service that's based on the Entity Framework and which will allow the user to read and write data directly to this service?
Otherwise, I'll just have to "invent" this myself. :-)Problem is, the database layer and RESTful service is already finished. The RESTful service will only stay in the project during it's development phase, since we can use the database-layer assembly directly from the web applications that are build around it. When the web application is deployed, the RESTful services are just kept out of the deployment.
But the database has a lot of data to manage over nearly 50 tables. When developing against a local database, we can have straight access to the database so I wouldn't need this tool for this. When it's deployed, the web application would be the only way to access the data so I could not use this tool. But we're also having a test phase where the database is stored on another system outside the local domain and this database is not available for developers. Only administrators have direct access to this database, making tests a bit more complex.
However, through the RESTful service, I can still access the data directly. Thus, when some test goes wrong, I can repair the data through this connection or just create a copy of the data for tests on my local system. There's plenty of other functionality and it's even possible to just open the URL to a table service straight in Excel or XMLSpy to see the contents. But when I want to write something back, I have to write special code to do just that. A generic tool that would allow me to access the data and modify it would be easier. Since it's a generic setup around the ADO.NET Data services, this should be reasonable easy too.
Thus, I can do it but hoped someone else has already done something similar. But it appears that there's no such tool made yet...
You are referring to ADO.Net Data Services. It basically creates an Entity Database Model and adds a REST frontend to the service using ASMX. There is a How To article availble from MSDN here on consuming the service using .Net. I have also done the same thing using the normally WebClient class in .Net in the past.
You can also look at the WCF REST Starter Kit if you want to roll your own based on Entity Framework. The starter kit also contains a handy new WebClient class that can be used to communicate with REST services.
Clarification
There is no prebuilt application client that I am aware off which will talk to these service, since they are pretty much accessing the data using Web Services. There is the Microsoft Smart Client Factory which is most likely the closest thing I have worked with.
I mentioned the above 2 options since they already have libraries in .Net that work with them directly, either as a referenced Web Service, or for the more adventurious, myself included, using the WebClient library or alternatively the new HTTPClient library in the WCF REST Starter kit.
I have used both, in Windows, Web, Silverlight and WCF. The latter being the easiest since they are focussed at REST.
We are currently investigating Prism which strongly leans to using this method when using WCF for front-end development.
Assumption
With regards to this question, you are making a generic assumption that wrapping ADO Entity Framework with a WCF service it will be generic. ADO.Net Data Services is the closest you will get, however the structure of the database will fundamently change the way you interact with it. Going a level higher in a "generic" way would be dangerous, as these 2 technologies, individually or together, are already as generic as possible.
In addition to Data Services (+1), consider RIA Services. It's like a domain-specific version of data services for Silverlight or WPF clients. Less flexible, but easier, than Data Services.
I have all my entities in a seperate project in my edmx file and I expose them to my client application using a WCF service.
That means I don't have to give my client app a direct link to the project that contains the edmx file. That would be bad because it contines the object to query the database with.
But only the entities that my WCF service uses can be accessed from my client app. So for example because I have the following code in my service:
public MyClass GetMyClass()
{
return new MyClass();
}
.. I can use access MyClass in my client app with something like:
myServiceInstance.MyClass cls = new myServiceInstance.MyClass()
What about if I have an entity called MyClass2 in my edmx file that I want to use in my client app! How to I instansiate it without giving my client a direct link to my edmx file project or making a usless method in my service layer that returns MyClass2
What are other people doing?
Thanks a lot
We created a separate project with Domain Transfer Object Classes that served as Data Contracts for our various internal WCF services. We then shared the contracts project with those internal services. We had one data service; those methods would translate these domain objects to/from entity objects before/after storing/retrieving. Meanwhile, the external services made use of the standard proxies generated from XSD and WSDL files, and translated to/from the shared domain transfer model.
We had to do this because the object context is not (yet) portable over WCF, unfortunately.
Some considerations for your situation:
If your client app is external to your system, it should not know anything about your EDMX or its classes. It should only know about your WSDL and XSD.
If your client app is internal, then it is no use trying to share the entity classes in EF v1 because it is not supported properly, yet. You need to transfer more than just the classes/objects - you need the context too, which maintains change tracking, and it cannot be done via WCF directly right now.
If the WCF service doesn't use it, what would you want it for? A WCF service (itself) is purely for data transport - the "mex" approach for metadata doesn't share code, so your MyClass2 would be impotent. If you want, you can use assembly sharing at the client, but I really don't recommend this in this case; EF objects at the client is a mess... (plus it won't work on the lightweight frameworks like Silverlight, Client Profile, Compact Framework, etc)
Another option is ADO.NET Data Services; this works over WCF, but gives you a more LINQ-friendly API than the regular WCF approach - and any domain objects that your model exposes should be available on the client data-context.
If you want to do it the "proper" way, you should be creating special classes for your messages that are going across the wire, rather than trying to reuse business entities or data objects as messages. The value in this is that you are then free to change your business entities and data objects without worrying about the contract you have exposed to consumers changing. Every change to your service is a bit more deliberate since it happens independently of changes to data and business logic.
Another way to handle this is simply to use svcutil (or "Add service reference..." though svcutil works better for multiple service endpoints) to generate all the classes that the client will be using instead of adding a reference to the server project. That way, the only classes your client will ever see are the ones exposed by the service.