WCF and Fluent NHibernate: how can i keep "clean" classes? - wcf

i'm investigating Nhibernate, jquery and WCF at the same time for a in-house project, and i was wondering why i couldn't have "clean" data classes.
From what i've read, a very good point in the nhibernate world is that my business class won't be linked to the framework.
I won't have
<SaveInTable("Thingie")> _
Public Class Thingie
<ColumnName("ThingieId")> _
Public Property Id as Integer
' accessors
End Class
but rather something like
Public Class Thingie
Public Property Id as Integer
' etc
And then
Public Class ThingieMapping
Inherits ClassMap(Of Thingie)
' etc, omitted for brevity's sake
What i don't understand is that if i want to list Thingies in a web page with jQuery, and if i want to use WCF webservices with jquery (it looks like the current trend from what i've seen on various tutorials), i find myself having to add DataContract and DataMember attributes to my Thingie class.
On the other hand, the classic ASMX webservices won't bother me and let me retrieve the Thingie class without worrying about adding attributes.
I have the feeling that i'm missing part of the picture here; it seems logical to try keeping the Thingie class mostly independent, but i haven't found examples so far.
So, do i have to abandon all hopes and stick to the classic webservices, or is there a way to have my WCF cake and eat it too?

I suggest you use DTOs to send over the wire - then you can decorate the DTOs with the necessary attributes.
This means, of course, that you must somehow map your domain classes to the DTOs and vice versa. If the mapping is trivial (+some other cases that satisfies some conventions), you can use AutoMapper for that.
Using DTOs has several benefits, the best being that you have a clear seperation of concerns - your NHibernate-mapped domain model is about modeling stuff in your domain, and your DTOs are for sending data over the wire. Then, if one changes, the other doesn't necessarily need to change as well.

Related

How to use and create DTOs is OOP world?

What is the right way to create DTOs from business objects?
Who should be responsible for creating them? BO/DTO itself from BO/some static factory?
Where should they reside in code if I have, f.e. some core library and a specific service API library that I need DTO for? In core library next to BO(which seems incorrect)/in specific library?
If I have encapsulated fields in my BO how do DTO grab them? (obviously in case when BO is not responsible for creating DTOs)
As an example assume that I have some Person BO like this:
class Person
{
private int age;
public bool isBigEnough => age > 10;
}
I want age to be an internal state of Person but still I need to communicate my BO to some api. Or having private field in my class that I want to send somewhere already means that it should be public?
Are there any general considerations of how to use DTOs alongside business classes with encapsulated data?
___ Update:
In addition to approaches that #Alexey Groshev mentioned I came accross another one: we separate data of our BO class into some Data class with public accessors. BO wraps this data with its api(probably using composition) and when needed it can return its state as Data class as clone. So dto converter will be able to access Domain object's state but won't be able to modify it(since it will be just a copy).
There're multiple options available, but it would be difficult to recommend anything, because I don't know the details about your project/product. Anyway I'll name a few.
You can use AutoMapper to map BOs to DTOs and vise versa. I personally dislike this approach, because it's quite difficult (but possible) to keep it under control in medium/large sized projects. People don't usually bother to configure mappings properly and just expose internal state of their objects. For example, your isBigEnough would disappear and age would become public. Another potential risk is that people can map DTOs to/from EF/Hibernate objects. You can find some articles which explain why it's considered to be a bad practice.
As you suggested, a BO can create DTO by itself, but how would you implement this approach? You can add methods or factory methods to your entities, e.g. public PersonDto ToDto(). Or you can add an interface, e.g. public interface IDtoConvertable<T> { T ToDto(); }, and choose which entity or aggregate root will implement it. Your Person class would look like this class Person : IDtoConvertable<PersonDto> {... public PersonDto ToDto() {...} }. In both cases DTO namespace/assembly must to accessible by entities which sometimes can be a problem, but usually it's not a biggie. (Make sure that DTOs cannot access entities which is much worse.)
(C#) Another option is to return a delegate which creates DTO. I decided to separate it from (2), because entity doesn't really create DTO by itself, but rather exposes a functionality which creates DTO. So, you could have something like this public Func<PersonDto> ToDto() {...}. You might want to have an interface as in (2), but you get the idea, don't you? Do I like this approach? No, because it makes code unreadable.
As you see, there are more questions than answers. I'd recommend you to make a few experiments and check what works for you (your project) and what doesn't.
I think the answer to question 5 will address the other questions too.
Are there any general considerations of how to use DTOs alongside business classes with encapsulated data?
Remember, a DTO is solely to transfer data. Do not concern yourself with implementing any kind of rules in the DTO. All it is used for is to move data from one subsystem to another (NOT between classes of the same subsystem). How that data is used in the destination system is out of your control -- although as the God programmer you inherently know how it is going to be used, DO NOT let that knowledge influence your design -- and therefore there should be no assumptions expressed as behaviour or knowledge accessors -- so, no isBigEnough.

Should models be able to access my searcher class?

I have a few questions about "best practices" in my application structure. I make use of skinny models, and have service layers which do most (all) of the database interaction. The models call the service layer when they need a database transaction.
I also have a factory class which can return forms, models, and service layer classes. This factory class may also return a "search" class which acts as a very simple DBAL and is used by my service layer.
This search class has helper methods such as getAll() and getById().
I'm slightly confused about which parts of my application should have access to the search class; currently my model uses the static factory to build the search class when it needs to retrieve an entity by it's ID. Should my models instead be calling my service layer to make this call, thus negating the need to use my factory class to return the searcher?
I guess I don't like the idea that my database can potentially be accessed from multiple parts of my application, when really I'd rather everything need to go through my service layer first.
Tips and feedback are much appreciated!
I would end up creating a SearchService (which implements an interface i.e. ISearchService) class which the model, or any other code, that wants to access the Searcher would interact with.
This way you keep a clear separation from the Searcher class, or factory, which could change in the future. The other benefit is that, by having all the search related code in the SearchService, it becomes a lot easier for devs to understand the code, since they know that search related code is in the SearchService, rather then dotted around the codebase, calling factory methods, etc.
Also, by using an ISearchService, you allow yourself the option to use Dependency Injection, which is a nice way of having your object initialised for you, and not having to worry about implementation changes.
That's just my preference though, rather then this being a right/wrong way to do things.

Serializing Composed Objects

I see Composite Oriented Programming and DCI as interesting techniques
to use within a rest framework, but have run into an issue.
Is it possible to serialize a mixin object and get all it's
properties? For example:
public class IHasOwner
{
string owner();
}
public class HasEngine
{
string engine();
}
Let's say we make a CarComposite object with the two classes above as
mixins. Could I deserialize this CarComposite class to get the
following xml?:
<CarComposite>
<owner></owner>
<engine></engine>
</CarComposite>
I'm curious to how this is handled in general, but with close
attention to .NET, since you canot deserialize Interfaces.
I find that a view- or resource-model is often called for in RESTful services. I.e. a set of dumb data types tailored for the way you want to expose the resource. These do not need to match domain objects. You do need to be able map between the two though. The dumb resource-model is "easy" to serialize.
For the mapping between domain and service model objects AutoMapper can be quite useful.

Reuse classes and objects for both WCF and non-WCF

I have several classes such as Order, Customer, etc. These classes serve for holding data and nothing more. I want to be able to reuse these classes in other projects in the future, but for some reason I don't quite understand, WCF forces me to decorate the data members with the [DataMember] attribute, forcing me to reference WCF plumbing that I will never use in other projects.
I would imagine that WCF lets you take any serializable class and use it as a content type. Am I understanding this correctly?
Yes, with .NET 3.5 SP1, the WCF DataContractSerializer will now serialize any POCO class just the same way as the XmlSerializer will - any public property will be serialized.
I don't know for sure whether that's a good thing - one of the pillars of WCF is being explicit, in order to clearly state your intent. I personally find it a good thing to mark your classes with [DataContract] and your fields and properties you want to have serialized explicitly with [DataMember] - it makes it clearer as to what's going on, and it doesn't hurt your POCO class at all.
And btw: you don't have to reference any "WCF plumbing" to do this - those attributes live in System.Runtime.Serialization - a very generic system assembly.....

WCF Contracts from Entity Framework?

I've been coming up with a lot of dead ends on this question. Supposedly, .NET 3.5 SP1 has Support for ADO.NET Entity Framework entities in WCF contracts. But when I look for solid info on it I'm not getting a lot of answers. I found this one snippet on an MSDN thread. Does anyone have any experience with this? What happened to the [DataContract]? Is this all there is to it? Why is there so little material on this?
This the answer from Tim Mallalieu in Microsoft.
Entity Types that are generated in the Entity Framework are, by default Data Contracts.
If I were to create a simple model in the Entity Designer like the following:
The cart Entity Type is by default a DataContract with all properties annotated as data members. We can then use this in a WCF service as follows:
[ServiceContract]
public interface IService1
{
[OperationContract]
Cart[] AllCarts();
}
public class Service1 : IService1
{
public Cart[] AllCarts()
{
using (MSPetShop4Entities context = new MSPetShop4Entities())
{
var carts = from c in context.Carts select c;
return carts.ToArray();
}
}
}
As the Entities are DataContracts you can now roll your services as you see fit and send these across the wire.
I recommend that you not return Entities directly. Unfortunately, Microsoft chose to include implementation-specific data as part of the DataContract for entities. This will not interoperate with other platforms, and is the sort of thing that might fail to interoperate even between .NET versions.
Instead, I recommend you follow the Data Transfer Object pattern and just return POCO classes that are copies of the data in the entities, with no behavior. You can return List of such classes to represent a table, etc.
The "sharing interfaces and not type" tenet presupposes that you don't own both ends of the wire and/or you're writing a public-facing web service. WCF can be used (and is used) in contexts where this is decidedly not the case. Many enterprise n-tier architectures have a WCF-fronted application tier to facilitate load-balancing among other things. In these cases it is perfectly valid to share type and, in fact, is desired.
You could go the easy way and use ADO.NET Data Services.
Some more detail in response to comments:
There are several problems with the classes generated by EF. I'm looking now at an AdventureWorks example with SalesOrderHeader and SalesOrderDetail. The SalesOrderDetail entity has both "SalesOrderHeader" and "SalesOrderHeaderReference" properties, both marked as DataMembers. This looks like a bug, since the "SalesOrderHeader" property is also marked [XmlIgnore] and [SoapIgnore].
Also, consider whether you want to serialize the link back to the parent SalesOrderHeader in the first place. Besides, what exactly should be serialized? SOAP doesn't support references in an interoperable manner.
Finally, the base classes of the entities are also data contracts. Yet they have nothing to do with the data you are returning - they are purely an implementation artifact.
In short, Microsoft screwed up on this one. They didn't think it through.
About ways to generate the DTO classes, I suggest looking into various code generation tools, like CodeSmith. You can write code to do this yourself; I did so in my previous position. The nice thing about generating the DTO is that you also get to generate the methods to translate to and from the DTO.
As to overhead, the overhead of moving some data around in memory is nothing compared to the amount of time it's going to take to send the data over a network!