tags:

views:

238

answers:

3

I'm exposing some CRUD methods through WCF service, for some data objects persisted in a database through NHibernate. Is it a good approach to use NHibernate classes as data contracts, or is it better to wrap them or replace them with some other data contracts? What is your approach?

A: 

I don't have direct experience in doing this, but I have sent Datasets across via WCF before and that works just fine. I think your biggest issue in using NHibernete as data objects over WCF will be a lack of interoperability (as is also the case when using Datasets). Not only does the client have to use .NET, the client must also use NHibernate. This goes against SOA principles, but if you know for sure that you won't be reusing this component then there's not a great reason not to.

It's at least worth a try.

Terry Donaghe
NHibernate objects are typically just POCO objects so they could be serialized to XML quite easily. That XML is portable and can be read by any application. I'm not sure I agree that Datasets are an 'interoperable' method of sending data through a WCF service either.
Jeffrey Cameron
Sorry Jeffrey, I didn't mean to imply that Datasets were interoperable. They aren't. I was trying to say that you ought to be able to use NHibernate across WCF but that wouldn't be interoperable just like use DataSets works, but isn't interoperable. I'll edit to clarify.
Terry Donaghe
+1  A: 

You would not want to expose your domain model directly, but map the domain to some kind of message as it hits the process boundary. You could leverage NHibernate to do the mapping work for you. In this case you would have 2 mappings, one for you domain model and another for your lightweight messages.

Adam Fyles
IF you need to do mapping there is a great tool called Automapper available. to assist.
Jeffrey Cameron
+5  A: 

Our team just went through a good few months debating this design point, so I've got a lot of links to share ;-)

Short answer: You "should" translate from your NHibernate classes into a domain model.

Long answer: I think the answer to this is a matter of principle. If you ever want to be interoperable, you should not use Datasets as your DTOs (I love Hanselman's post on this). I'm not saying that it's never a good idea; clearly people have had success doing so. Just know that you are cutting corners and it's a risky proposition.

If you have complete control over the classes you are pushing the data into, you could build a nice domain model and just map the NHibernate data into those classes. You will more than likely have serious issues doing that, as IList<> (which a <bag> maps to) is not serializeable. You'd have to write your own serializer, or use something like NetDataContractSerializer, but you lose interoperability.

You will need to measure the amount of work involved in building some wrapper classes, and the translation between, but then you have complete flexibility in what your domain model will look like. Then, you're able to do things (as we have done) like code generation for your NHibernate maps and objects. Then, your data contracts serve as an abstraction from your data, as they should.

P.S. You might want to take a look at ADO.NET Data Services, which is a RESTful way to expose your data, which, at this point, seems to be the most interoperable choice to expose your data.

joshua.ewer
The thing that worries me about using wrapper classes, is maintanability of that code. What was you final decision on this (I mean, decision of your team)? Do you always go with wrapping, or it is just a matter of decision at specific situation?
vucetica
Completely understandable; that was the largest debate. Basically, there really nothing to be done about it; it's custom code. However, since our NHibernate classes/maps are gen'd (CodeSmith rocks!) directly from the database, and our domain model is done via MS's Service Factory diagrams, the translation is the *only* thing that has to be handwritten. Given the flexibility, maintaining that tiny bit of custom code is well worth the overhead.
joshua.ewer