I'm looking at new architecture for my site and was wondering if pairing NHibernate with a web service core is a good idea. What I want to do is make my webservice the core of my business, from the site front ends to the utilties I write. I'm trying to make all of my UIs completely ignorant of anything but my service API's.
In a simple strawman experiement, I'm running into issues with Serialzing my Iesi ISets....this is causing me to rethink the strategy altogether.
I know I could just develop a core Library (dll) and reference that in each of my applications, but maintaining that dll's version over a minimum of 6 applications seems like it's going to cause me much pain.
With NHibernate, what are the pro's and con's of those two approaches?
I see no problem in using NHibernate and webservices together - I just don't think it's a good idea to send the entities themselves over "to the other side".
A better approach is to use a set of DTOs that are made for the service - then you won't be running into issues like that of serializing unknown types and such.
You can use a library like AutoMapper to do the mapping from the entities to the DTOs.
There's a lot of stuff written about this, some of it:
http://martinfowler.com/bliki/FirstLaw.html
http://ayende.com/Blog/archive/2009/05/14/the-stripper-pattern.aspx
http://elegantcode.com/2008/04/27/dtos-or-serialized-domain-entities/
DTOs vs Serializing Persisted Entities
As a side note for the service it self, you could design wise use an approach like Davy Brion describes here: http://davybrion.com/blog/2009/11/requestresponse-service-layer-series/
I don't know NHibernate, but want to remind you that you should be using WCF for new web service development, unless you are stuck in the past (.NET 2.0). Microsoft now considers ASMX web services to be "legacy technology", and you can imagine what that means.
Related
The OP in this question asks about using an WCF/OData as an internal data access layer.
Arguments of using WCF/OData as access layer instead of EF/L2S/nHibernate directly
The resounding reply seems to be don't do it. I'm in similar position to the OP, but have a concern not raised in the original question. I'm trying to develop (natively) for a lot of different platforms but want to keep as much of the data and business logic server side as possible. So I'll have iOS/Android/Web (MVC)/Desktop applications. Currently, I have a single WinForms applications with an ORM data access layer (LLBLGen Pro).
I'm envisioning moving most of my business / data access logic (possibly still with LLBLGen or other ORM) behind a WCF / OData interface. Then making all my different clients on the different platforms very thin (basically UI and WCF calls).
Is this also overengineered? Am I missing a simpler solution?
I cannot see any problem in your architecture or consider it overengeenered as a OData is a standard protocol and your concept conforms the DRY principle as well.
I change the question: Why would you implement the same business logic in each client to introduce more possible bugs and loose the possibility to fix the errors at one single and centralized place. Your idea makes you able to implement the security layer only once.
OData is a cross-platform standard and you can find a OData libraries for each development platform (MSDN, OData.org, JayData for JavaScript). Furthermore, you can use OData FunctionImports/Service methods and entity-level methods, which will simplify your queries.
If you are running multiplatform development, then you may find more practical to choose platform-agnostic communication protocol, such as HTTP, rather than bringing multiple drivers and ORMs to access your data Sources directly. In addition since OData is a REST protocol, you don't need much on the Client side: anything that can format OData HTTP requests and parse HTTP responses. There are however a few aspects to be aware of:
OData server is not a replacement for an SQL database. It supports batches but they are not the same as DB transactions (although in many cases can be used to model transactional operations). It supports parent-child relations but it does not support JOINs in classic SQL sense. So you have to plan what you expose as OData entity. It's too easy to build an OData server using WCF Data Services wrapping EF model. Too easy because People often expose low Level database content instead of building high level domain types.
As for today an OData multiplatorm clients are still under development, but they are coming. If I may suggest something I am personally working on, have a look at Simple.Data OData adapter (https://github.com/simplefx/Simple.OData, look at its Wiki pages for examples) - it has a NuGet package. While this a Client Library that only supports .NET 4.0, part of it is being extracted to be published as a portable class Library Simple.OData.Client to support .NET 4.x, Windows Store, Silverlight 5, Windows Phone 8, Android and iOS. In fact, if you check winrt branch of the Git repository, you will find a multiplatform PCL already, it's just not published on NuGet yet.
I need to evaluate SOA architecture between WCF Data Services vs WCF RIA Services. Following are some of my parameters:
Multiple Client (HTML5/iOS/Android/Windows 8 Metro/Windows Phone 7)
Disconnected and offline operation
Validation engine
Performance
Network data compression
Support for Cloud Environment
Could anyone help me to gather some data for my evaluation. Also, is there any other good option available for SOA implementation.
I am aware of DevForce.
I'm intimately familiar with RIA Services and know where it falls short. I know little about data services and DevForce, but I know that DevForces advertises to be better than RIA Services in exactly those areas where it annoys me, which is:
RIA can't do group-by or joins of any sort. (Interestingly, the DevExpress toolkit can
do some trickery to group on a RIA Services source in some cases.)
It does understand relationships, but not of the many-to-many kind where it would have to
handle a translation to a bridge table transparently. (EDIT: this is planned for Open Ria Services)
The change tracking works through a context (unit of work) which can only be submitted or
rejected as a whole (out-of-the-box anyway). That usually leads to an application with
many contexts and weird copy operations to transfer entities. The RIAServicesContrib
project helps with that.
It appears to be no longer maintained. I base this on the fact that when Entity Framework 4.1 released their new DbContext API (for code first), Microsoft released a compatibility library with which you could use RIA and EF code first. That library has a version lock on EF 4.1 though, and Microsoft now just states that RIA Services doesn't support DbContext in the form of an Orwellian note to Visual Studio 2012. (EDIT: DbContext is now supported again - EF is currently supported up to version 5, with 6 being likely only supported in Open Ria Services)
Some tasks such as observing changes of related entities programatically (rather than
through data binding) are hard.
Some things which should be really simple, such as getting the context from an attached
entity, are hard.
All queries are single requests, only the remaining CUD (of the CRUD) is batched.
Custom methods to invoke along with normal CUD operations are very limited. In
particular, it's not
possible to cancel one that is scheduled without cancelling the whole context. That has
made them almost useless in most cases where I wanted to use them.
You will have to decide whether or not to use the DomainDataSource, which is a beast
that does too much and too little. You can fetch everything programatically too, but
some things are really quick to wire up with this xaml helper.
There is no built-in support for serializing entities to isolated storage.
Silverlight (and Javascript I believe) are the only supported platforms - no WPF.
(EDIT: this is planned for Open Ria Services - in particular, it should be able to serve BreezeJS)
Since Data Services is older (I think), I didn't care to ever look closely at it. I did however recently skim over the feature list of DevForce and I believe that sounds exciting, although I can't say anything about it from experience.
(EDIT: I found a very knowledgeable comparison of RIA Services and WCF by Colin Blair here.)
The architect compares his product to RIA Services here. I covered some of his points, but not all.
Altogether I can say that RIA Services is clearly better than raw WCF, but it's also clear there has to be something better than that. I hope that's DevForce.
Both expose entities via OData, but RIA Services is specifically targeted to:
Silverlight consumption
Poor man's services - they're easier to get up and running with little effort
WCF Data Services are far more powerful and configurable. The biggest difference (IMO) is that RIA services require one host type per entity, whereas WCF Data Services can automatically host an entire content (a type with multiple IQueryable properties).
That said, both implementations are pretty half baked (again IMO only) and not really well thought out or implemented. ...You may be better off with traditional WCF operations hosted with WebGet/WebInvoke attributes...or using the WCF Web API.
I wouldn't go with DevForce only because it mainly really target Silverlight implementations (if I recall correctly). That said, they're package is pretty cool and far more feature complete than RIA or WCF Data Services.
I want to know if using Self Tacking Entities (in Entity Framework) is recommended with WCF services? If yes, then can you guide me to a tutorial which may guide how to do that?
Actually, I am going to develop a WPF application using Prism with MEF and MVVM. I have decided to use Entity Framework. I want suggestions and advices regarding this approach.
Any help will be appreciated.
I want to know if using Self Tacking Entities (in Entity Framework) is
recommended with WCF services?
It depends who you ask. If you ask MS they will tell you Yes because they simply don't have anything better to offer. STEs were response to this very old MS Connect suggestion. The problem is that EF itself has terrible bad support for merging changes between two entity graphs (you must do it completely yourselves) and developers working on MS platform (sometimes including me) share some common behaviors:
They are lazy to develop their own solution to problem and they expect some magic directly in APIs provided by MS.
Most of the time they are not trained / skilled / competent in the technology they have to use, because they have to move to a new one too often.
The only APIs they know are part of .NET Framework. They don't look for other options neither they compare features.
First two points are result of MS strategy where RAD become synonym for designer (or newly also T4 templates).
I share #Richard opinion about STEs. I would add one additional drawback of STEs - they move large datasets between participants. If you decide to get an entity graph from the server, change a single entity in the graph and push data back they will transfer again the whole graph. Transferring only changed entities results in fighting with STE's core logic. I'm also afraid that they track changes completely on per entity level instead of per property level. In case of modification to entities with large binary or string data it can result in transferring too much unneeded data between the service and the database and between the service and the client.
Anyway for a simple application with low data traffic and small entities they can do a good job and allow you building your application quickly but without strict separation of concerns. You will get entities from service and bind them directly to WPF UI and they will be able to track changes for you. Later you will push entities back to service and they will be able to persist changes. Your client and service will be tightly coupled but in some scenarios it can be good enough.
I would avoid self tracking entities in general - I blogged about it here.
Create your own DTOs and use them to manage the transfer of data - then biuold your POCO objects in the service and use them with entity framework for persistence
If you want self tracking then there is a slightly cleaner approach here
There seems to be quite a bit of information regarding using NHibernate and WCF Web Services but I'm struggling to find a definitive guide on how to implement the two technologies together in a efficient, thread safe way.
Specifically I want to grab the ISession object and uses that to get and save data through my existing repositories. My Business Objects, Unit Tests and ASP.NET Web Application all use the NHibernate framework and it works just great (it's my first hobby project using an ORM). My big question is how to combine this great framework with WCF Web Services.
I've read that version 3.0 NHibernate has NHibernate.Context.WcfOperationSessionContext but I'm unsure of it's implementation (see this question). From what I understand, one option is to store the ISession object in the OperationContext?
Can anyone point me in the direction of a implementation example?
Many thanks.
Here is a post describing, in detail, all the steps for registering and using the WcfOperationSessionContext. It also includes instructions for using it with the agatha-rrsl project.
WCF and Nhibernate work together in Sharp Architecture project. You can have a look at their implementation
In our layered application, we are accessing database via WCF calls. We are creating and disposing contexts per request. Also we are using POCO approach.
My question is, in pure POCO model (completely persistent ignorant POCOs) is it possible to track the changes, while we are creating and disposing context per request (as previous context is disposed in that service call)? If yes how EF handles this situation? As far as I can see 2 mechanisms (snapshot based change tracking and notification based change tracking with proxies) will not be able to handle this? If not, how should we handle context so that we are able to track the changes?
I'd say:
Do not use self-tracking entities in a pure SOA environment:
The self-tracking entities only work when your clients use
the generated proxy classes.
When you're doing SOA by the book, you cannot expect your clients
to be .Net, or even more, .Net 4.0; Which is the only scenario
in which self-tracking entities will work. Your services will be
useless to any other clients.
Just My 2 cents,
Regards,
Koen
Self-Tracking Entities does indeed solve this problem if you are capable of sharing the Model with the client as opposed to using metadata generated by the reference.
Abstract the STEs and reference them from the client, you will have access to tracking disconnected from the context.
Unfortunately you won't find a simple solution to this in Entity Framework v1.0.
There has been much discussion and little resolution. It is one of the many known problems with EF v1.0 and one way or another you will end up having to write lot's of code to handle this.
In .NET 4.0 the ADO.NET team have introduced Self-Tracking Entities to tackle this very problem.