WCF and DataContract

Posts   
 
    
tsmith
User
Posts: 38
Joined: 17-Apr-2006
# Posted on: 13-Dec-2006 15:33:24   

We are looking at creating a service that will be accessed from external winform client and a web application hosted on that box. WCF solves this problem in that I can host this service on the IIS with a WSE and Named Pipes endpoints. The service calls returns different Entities that are generated by LLBLGen. For what I have seen you have to decorate the class and fields with DataContract and DataMember. These classes appear to be simple C# objects. I noticed that all the classes in the examples are simple objects. I am not sure if that is required. Is there any upcoming plans to implement this, and is there a good way to implement this now with LLBLGen v2.

jaschag
User
Posts: 79
Joined: 19-Apr-2006
# Posted on: 13-Dec-2006 16:01:35   

You might want to have a (long!) look at http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=8174 and other related threads.

tsmith
User
Posts: 38
Joined: 17-Apr-2006
# Posted on: 13-Dec-2006 19:20:09   

That link seemed to be a more philosophical debate. I am looking for more concrete information. In WCF you create a Interface contract then implement it using an endpoint, be it tcp, http, named pipes. This contract can pass these classes if they are decorated with DataContract and DataMember. What I am looking for is whether I need to create simple objects that are loaded from the Entities or can I use the Entities themselves. If I can use the Entities is there or will there be a change in the LLBL code generator to add these decorators to the Entity.

As I stated we are building this new application and are attempting to use the latest technologies available. This application will have both a Web and Winform client that will access the same Service. This creates the need to have the Service be available thru Http (most likely webservices) and Named Pipes.

jaschag
User
Posts: 79
Joined: 19-Apr-2006
# Posted on: 14-Dec-2006 01:24:52   

tsmith wrote:

That link seemed to be a more philosophical debate. I am looking for more concrete information. In WCF you create a Interface contract then implement it using an endpoint, be it tcp, http, named pipes. This contract can pass these classes if they are decorated with DataContract and DataMember. What I am looking for is whether I need to create simple objects that are loaded from the Entities or can I use the Entities themselves. If I can use the Entities is there or will there be a change in the LLBL code generator to add these decorators to the Entity.

As I stated we are building this new application and are attempting to use the latest technologies available. This application will have both a Web and Winform client that will access the same Service. This creates the need to have the Service be available thru Http (most likely webservices) and Named Pipes.

It is a bit long-winded, however the underlying proposition from Solutions Design is that if you are going to use webservices then you are encouraged to keep the service contract at a high level and leave entities on the server and use data-only dto's or even design your services contract-first. Specifically, certain LLBL support classes (predicates and prefetch paths) will not serialise over webservices and so cannot be used. If you wish your LLBL domain classes (and optionally support classes) to participate in your service contract then you are encouraged to use remoting (possibly over http). IIRC WCF supports remoting and so presumably you just need to configure the binding to use remoting.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 14-Dec-2006 10:15:37   

Our position is: instead of creating webservices which are positioned as horizontal layers in your application, you should use services which are positioned as vertical segments (so contain all layers) in your application. This thus means that data is passed by value and predicates etc. are not passed but messages are passed.

This focus isn't unique, it's one of the core design philosophies of webservices. If you position a webservice as a remote reference to a horizontally positioned tier, you'll run the risk of pulling a lot of data from that tier to process on the client and then send it back. That's not where webservices are good at and you should avoid that.

Frans Bouma | Lead developer LLBLGen Pro
tsmith
User
Posts: 38
Joined: 17-Apr-2006
# Posted on: 14-Dec-2006 20:56:40   

I am not clear on this whole thing. I am gonna restate this with what I am attempting in hopes that I can understand it better. This was a test application that does not use LLBL.

I have a service that exposes 2 methods [CustomerDto GetCustomerById(int id)] and [void SaveCustomer(CustomerDto cust)]. Both methods are defined in the ICustomerContract which is implemented by the CustomerDao. I have a Console Application and a Web Service that I hit with a client. Both host send and receive the CustomerDto with out a problem when it is decorated properly.

So, to accomplish this with LLBL in an Adapter environment, am I going to need to transfer the data from an LLBLEntity to a CustomerDto in order to accomplish this or will there be a change made to solve this.

Chester
Support Team
Posts: 223
Joined: 15-Jul-2005
# Posted on: 17-Dec-2006 02:19:58   

If you want to pass entities around directly, remoting is a better choice than webservices. Why? Because webservices should pass around XML messages that are readable on any platform. If you really NEED webservices because it IS cross-platform, DTO's are a better choice because non-.NET platforms will be able to consume your services.

tsmith
User
Posts: 38
Joined: 17-Apr-2006
# Posted on: 18-Dec-2006 15:36:37   

The service we create will only be accessed from .net applications that we write. These application live as browser-based and click-once applications. We are moving to WCF because it allows us to write a single Service Assembly that can be exposed through different end-points. Our browser applications will most likely use named pipes and the click-once will use webservice so we dont have to deal to much with opening up other ports. This works if I decorate the class and properties.

The basic concept is we are going with WCF which allows us to pass these decorated classes, and we do want to decorate all the LLBL entities because they are overwritten even if they don't change. Also, we do not want to create a bunch of Dto class because of the time to translate the information between it and an entity.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 19-Dec-2006 10:54:57   

What I miss is why you need to decorate the entities instead of the service interface? Isn't it so in WCF you need to decorate the service interface and just use the objects you pass over the wire as 'data' which don't need to be decorated? After all: entities are marshalled by value.

Frans Bouma | Lead developer LLBLGen Pro
sami
User
Posts: 93
Joined: 28-Oct-2005
# Posted on: 19-Dec-2006 11:36:16   

I think he is referring to use of data contracts:

In WCF, Data Contracts are defined through classes instead of interfaces like Service Contracts. Those classes are decorated with an attribute named DataContract, and members that should be considered part of the message, should be decorated with DataMember attribute.

Let’s assume you had a service named MembershipService, having an operation named GetUserDetails like this:


public class MembershipService
{
    public User GetUserDetails(int userId)
   {
        //internal logical to get the User details…
    }
}

In order to normalize the User serialization on the wire, you needed to decorate your User class with some attributes like this:


[DataContract]
public class User
{ 
     [DataMember] 
     public string Name;

     [DataMember] 
      public string Address; 

      //..etc..
} 

jaschag
User
Posts: 79
Joined: 19-Apr-2006
# Posted on: 19-Dec-2006 11:44:14   

This may shed some light http://msdn.microsoft.com/msdnmag/issues/06/08/servicestation/default.aspx.

tsmith, it would seem that you can decorate you service contract to force xml serialisation (i.e. no entity decoration is needed) although your message above would suggest your recommended option is NetDataContractSerializer decoration.

Frans, this excerpt from the above may be of interest given this and other recent related threads:

"These new serializers can also maintain object references and deal with issues like circular references (see the constructor with a preserveObjectReferences flag). This is a nice improvement over XmlSerializer, which choked on such object graphs. I can, for example, serialize a circular spouse reference in the previous examples. I've included such an example in the downloadable sample code."

It would seem that some enhancements may be required for LL to become a fully equiped WCF citizen - what are your thoughts on this?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 19-Dec-2006 12:24:53   

(removed: remarks about what serialization methodology will be chosen as that's been clarified)

About decorating entities: Why would decoration be necessary, if serialization is done by the entity itself? After all, you're not decorating a datatable either when it's used in a service.

Edit: so decorating the class IMHO won't make a difference as the class implements IXmlSerializable.

(removed: remarks about datacontract, I was confusing it with service contract) and this:

(see the constructor with a preserveObjectReferences flag).

in the snippet you quoted, Jaschag, makes it even more fuzzy: when an object is returned from a service the serializer is already created and the object in question is simply consumed by the serializer, so INSIDE the object (entity in this case, or entity collection for example) there's no possibility to take over, as that's not the place.

So where is this constructor called? IMHO like the XmlSerializer: behind the scenes by .NET's webservice support code. confused

edit: this is solved in another article on the site Sami linked to below. The code isn't prety though and pretty cumbersome so I doubt a lot people will go this far. However as our IXmlSerializable implementation already takes care of this, it's not a problem.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 19-Dec-2006 12:52:17   

Follow up: when .NET 3.0 was publicly released, I looked into the docs of WCF and was looking for evidence to feed my fear that I had to write a lot of code to get llblgen pro even support this new stuff.

Though all I saw was documentation and examples about decorated interfaces for SERVICES and that using a decorated interface was the preferred way.

I missed the datacontract part, though it's not really interesting, as an entity is more than just the data: additional information is stored inside the entity which isn't included in the datacontract, IMHO.

What's frustrating me a bit is that it's hard (read: impossible without serious problems) to have a data-access solution without knowledge of additional frameworks in which the data objects are used. This is upside down, the consumed object has to know things about the consumer object (wcf code) which should be the other way around: what if another framework which also consumes data / entities gets popular?

If there is essential code needed for W*F in llblgen pro, we'll of course add it in 2.1 with a .NET 3.0 only build, but at the moment I doubt it as several people have successfully used 2.0 entities in WCF scenario's.

Though I want to look broarder: if there has to be support code in the framework which makes it very easy to create DTO graphs from entity graphs and vice versa, we should look into that and see if we can expand our projection code for this.

This WILL give severe problems, which are also plaguing current ADO.NET vNext designs: what to do with an entity which comes from the client and which isn't new? How does the server know this data is of an entity which exists already and therefore an update has to be done, without fetching the data first (inefficient) ?

What I want to focus on is code which supports the best way of working with a technique. If the best way is to send DTO's or messages decorated over the wire, then code to make that happen in the most easiest way is necessary. If it means there's no real consensus what's best, then I'll look at the code and decide what's best, what more can I do? Implement all gazillion ways of how the professional SOA priests think you should design an application today (and tomorrow it's likely different)? I don't think that's even doable left alone workable.

Moving forward So please work with me here. I'm not here to whine about you all being wrong as I don't know if I'm even understanding enough about webservices to be allowed to be in this thread, so please don't get me wrong. simple_smile

What I need is feedback about what has to be CHANGED to make things WORK in the case that it DOESN'T WORK TODAY. (so you want to use WCF and llblgen pro and it is impossible for you to create your software)

If it works TODAY, then there's no necessary change required and it falls in the 'nice to have' category (which is very crowded wink ).

Again, please understand that a SOA application can be written in a lot of different ways. All these different ways ask for different approaches towards services, what's send across the wire etc. What I need is a generic approach which can work with the code available in .NET 3.0.

So let's start with a simple question: DOES llblgen pro v2.0 code work with WCF today or doesn't it work? (and with 'doesn't work' I mean: you can't use llblgen pro in wcf applications TODAY).

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 19-Dec-2006 13:10:09   

(btw: datacontracts, can be defined on interfaces right? So one could generate these interfaces in a partial class of the entities using a simple template? Or does that make things fall apart because the entity class implements IXmlSerializable and ISerializable?

(edit) what I also thought was: with a DataContract, you can't have change tracking, you simply have data. Passing around an entity is only useful if you want to utilize the change tracking so you can easily persist changes.

With a datacontract, there's no space for change tracking, just the data. So in that situation, it's not necessary to use an entity, just create the DTO classes, decorate them (do this with a small template and generate them) and use projections to project resultsets on DTO's.

Frans Bouma | Lead developer LLBLGen Pro
sami
User
Posts: 93
Joined: 28-Oct-2005
# Posted on: 19-Dec-2006 13:56:04   

Here is a nice recourse (wcf developer blog) for those who are interested:

http://blogs.msdn.com/sowmy/archive/2006/02/22/536747.aspx

http://blogs.msdn.com/sowmy/default.aspx

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 19-Dec-2006 14:08:51   

sami wrote:

Here is a nice recourse (wcf developer blog) for those who are interested:

http://blogs.msdn.com/sowmy/archive/2006/02/22/536747.aspx

http://blogs.msdn.com/sowmy/default.aspx

Thanks, Sami! sunglasses

So looking at that list: it will pick IXmlSerializable over ISerializable, which is unfortunate, in the case of entities. (IXmlSerializable implementation is slower)

Using that info, I can write a class like: (warning: completely bogus simple_smile )


public enum CommandType
{
    Get,
    Save
}

[DataContract]
public class Command
{
    [DataMember]
    public CustomerEntity ToProcess;
    
    [DataMember]
    public CommandType Action;
}

which then is serialized to XML using the IXmlSerializable implementation of CustomerEntity and the rest is done by the serializer at hand. Correct?

If so: I definitely need to optimize IXmlSerializable implementations. This is already on the v2.1 list, as I have found out how to decrease the XML size and also how to optimize the code.

(edit) it also means that it does work today. The datacontract approach is IMHO though not that suitable for entities, as the entity xml contains change tracking information and db values for example to be able to properly perform all features expected from the runtime lib.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 19-Dec-2006 14:47:42   

tsmith wrote:

The basic concept is we are going with WCF which allows us to pass these decorated classes, and we do want to decorate all the LLBL entities because they are overwritten even if they don't change. Also, we do not want to create a bunch of Dto class because of the time to translate the information between it and an entity.

Btw, a couple of templates for this exist: http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=6261

these templates generate teh DTO's and the fill code for filling them. The original template is for v1.0.2005.1, so it doesn't use projections. It gives you an idea how code generation can be of help here.

Looking at the article Sami linked to, I don't really understand why a plain entity doesn't work in your scenario, as it does implement IXmlSerializable. Decorating the entities will make them lose change tracking information IMHO.

Frans Bouma | Lead developer LLBLGen Pro