Given the fact that I have a fully dynamic object model, that is, I have no concrete classes defined anywhere in code, but I still want to be able to create WCF DataContracts for them so I can use them in operations. How can I achieve this?
My concrete class "Entity" implements ICustomTypeDescriptor which is used to present the various properties to the outside world, but my expeimentation with WCF suggests that WCF does not care about ICustomTypeDescriptor. Is this correct or have I missed something?
Is this possible? It cannot be so that the only way to create a DataContract is to actually have a concrete harcoded class, can it?
you may use untyped service and message contract IIRC http://geekswithblogs.net/claeyskurt/archive/2008/09/24/125430.aspx
You might try System.Reflection.Emit.
Its quite tricky, but essentially you will just build a custom run-time type, with decorated data contract attributes. It gets tricky when creating encapsulated properties with PropertyChanged notifications, but in your service layer you can just get away with auto properties which are a lot easier.
This dated, but still very relevant link should get you going in the right direction.
http://drdobbs.com/184416570
Things evolve :-) Thanks to the excellent blog series by Alex D James its very easy to implement this.
Related
I have only ever seen it being used to 'overcome' the diferences between OOP and SOA.
I don't think it's a hack. The only thing that doesn't really sit right with me is that you have to attach the attribute to the base class when using inheritance to tell it what types are derived from it. This is a bit upsidedown but can be done programatically so it's not the end of the world.
It's a mechanism allowing the serializer to be informed of all types used by this web service so that they are correctly emitted in the WSDL and known by the clients. So consider it whatever you want: hack, feature, ... I consider it as a way to make the clients know all possible types.
We use custom type to represent Identifiers in our project. It has TypeConvertor attached and it always helped with serialization.
I've tried to use WCF Data Services to expose some data from our system, but faced a problem. Astoria framework do not recognize class as an entity even though I've decorated it with [DataServiceKey("Id")] attribute. If I change type of property to Guid - it totally works :(.
How could teach WCF Data Services to understand this simple class?
After a bit of research and a ton of Reflector work I've found that it's not possible.
WCF Data Services have monumental external metadata support described in detail by Alex James in very good series of posts.
However primitive data types creation is forbidden and key property of the entity should be of a primitive type. Moreover there is no pre- and post- execution hook available to provide run-time conversion from and to string type.
This and limited support of LINQ from NHibernate makes Astoria pretty unusable for me now. Witch is very sad.
As long as the class has a property Id DataServices should serialize it properly. You don't even need the attribute if the property is named ID. Did you see the example I did here. Also, you will find a complete list of OData related articles on http://www.Odataprimer.com. Maybe one of those will help.
Please note that my experience in Silverlight/.Net and WCF is about two weeks of googling and deciphering tutorials. I need to attempt and provide feedback to a client on if Silverlight will be a possible solution to their application needing a RIA front end.
The client has a rather large .Net based application with a UI layer built which greatly relies on the creation and manipulation of specific (personal) classes and objects from the backend (which would be the server side).
A summery of what I understand to be the general procedure: one can pass simple objects containing simple data types, or more complex .Net type objects. Basically anything which can be understood by both client and server side, after serializing.
But what is the limitation to the complexity of an object I can pass? Or phrased otherwise, would silverlight and WCF be able to support the passing of a personalized object which may contain references to other classes/objects and variables etc?
Additional Info (in case it can help):
I am not allowed direct access to their backend code but with the information I have been given I can safely say their classes heavily use inheritance and overloading of functions/methods in the classes.
As far as I know there is nothing specific to Silverlight. There are some things to keep in mind though.
WCF serialization doesn´t like circular references.
All types need to specified in the contract. So watch out with inheritance etc.
In general using DTO's (Data Transfer Objects) and not exposing your business objects is the way to go.
The metaphor is one of message passing as opposed to passing objects. DTO's as Maurice said.
You can get pretty complex, but each object needs to have its contract defined.
I have a class, ReportDef, which is a concrete class that I've decorated with [DataContract] and [DataMember] attributes as needed. ReportDef is in assembly A1 along with my ServiceContract, IReportService. I then have another class, UiReportDef, which derives from ReportDef and is in assembly A2. UiReportDef has no additional state that the service cares about.
I want to invoke my service with an instance of UiReportDef. Is there any way (short of manually constructing a ReportDef instance from UiReportDef) to do this without having my service know about A2? I know about KnownType. I don't want to reference A2.
EDIT: Here's some context that might make my question easier to understand. My ServiceContract implements IReportService which defines a method, RunReport(ReportDef report). ReportDef is decorated with the DataContract attribute, and has private members decorated with DataMember. UiReportDef is in an assembly that depends on UI-related assemblies, etc. I didn't design the existing class hierarchy. I need to pass ReportDefs and UiReportDefs (as ReportDefs) to the new service. Since ReportDef is concrete, I would expect the serializer to treat UiReportDefs as ReportDefs in the absence of any other information.
I didn't understand you question.
But I think I understand part of it now, you want to deserialize an object in an assembly that has no reference to it?
If so, you can't unless you're willing to do a whole lot of reflection and keep it defined/referenced as "object"
The common way to do this and was trying to explain in my previous answer is that you should use an interface that can be referenced by both client/server.
It is common practice to create stub assemblies consisting of nothing but interfaces for this case.
Or as your comment on your question suggests, you can use DTO objects.
http://en.wikipedia.org/wiki/Data_Transfer_Object
This thread may probably help a lot : WCF Inheritance and DataContract
WCF is not polymorphic because its not object oriented. Hence this is not possible.
I am developing a WCF web service which has become quite bloated. What techniques do you use to split up the implementation of the contract?
Well you have a couple choices:
First, you could leave it all in one class, but split up into different files using the partial class feature of C#.
Second, you could have the main service class just pass requests off to one of a number of other actual classes that are organized logically.
A third alternative is to consider refactoring to reduce the number of operations you have. Is there actually a use to all of the methods you're exposing?
Finally, you could always split up the service into multiple WCF services.
It's hard to answer your question if you don't give any more information.
Do you mean that your service interface is bloated, or the class implementation? It's hard to answer well, if I don't see the code, or have no other information, anyway, I'll try:
Notice that WCF service is basically just a regular class that implements an interface and has some attributes on its methods. So all the other good OO design rules apply to it. Think about what it does, does it have really single responsibility, if not try to outsource some of that responsibility to other classes that your service depends on. If you need a non-default constructor, use IInstanceProvider to create the service class, and supply it with its dependencies (or if you use Windsor Container use WCF Facility).
If you really want to you can streach your inheritance chain, and move some of the code to a base class. I don't do it, however and always prefer to use composition over inheritance.
Inspect your service contract, and think about how cohesive it really is. Maybe what you should do is to split it, into few smaller, more cohesive services.