Specification Pattern from DDD - improves criteria building

Specification Pattern from DDD - improves criteria building

Old forum URL: forums.lhotka.net/forums/t/9992.aspx


enzed posted on Thursday, January 27, 2011

Hi,

I think the power of linq expression as encapsulated by the Specification pattern (just google to find .NET implementation) would greatly improve the building of criteria in CSLA.

It would allow more dynamic criteria formulation and less custom criteria classes.

Many orms like Entity Framework (POCO - code first) will take the expression and apply it directly.

Here's an exmaple of how I'd like to use it:

Client Side:

	public partial class WorkWeek
{
public static void Get(ISpecificationCriteria<WorkWeek> criteria, EventHandler<DataPortalResult<WorkWeek>> callback)
{
  var dp = new DataPortal<WorkWeek>();
  dp.FetchCompleted += callback;
  dp.BeginFetch(criteria);
}
}

Server side using object factory:

  public class WorkWeekDal : ObjectFactory
  {

      //Fetch on a specification based on the business object interface
      public TimeAGF.Business.WorkWeek Fetch(ISpecification<WorkWeek> criteria)
      {
          using (var db = new TimeAGFContext()) //Context is Entity Framework
          {
//apply the linq experssion directly - EF does the heavy lifting
              return db.WorkWeeks.Single(criteria.Predicate);
          } 
      }
}

Looking at the CSLA implementation, I think it would take some internal refactoring of CSLA to take these Specification types.  It would also require specific handling in the mobile formatters so this type can be serialised.

Other than that that is all that is required I think.

What do you think.  If you like it I can have a go at doing it in CSLA and posting the update - or maybe I've missed something or maybe you can implement quicker than me.

Anyway - for me it would reduce coding significantly.  I'd like to have it.

Kind Regards,

Nick

RockfordLhotka replied on Thursday, January 27, 2011

CSLA .NET is not an ORM, and has very different design goals from a typical ORM.

Most notably, business domain objects shouldn't normally be queried like data entity objects, because they should have already been designed specifically to meet the needs of each use case.

Data entity objects (like those generated by ORM tools) tend to be data-centric, and therefore somewhat reusable across use cases. After all, they are primarily just data entities in object form - more like tables than behavioral objects.

Domain objects (like you should create using CSLA) tend to be behavior-centric, and therefore focused on individual use cases. The fact that they have data at all is completely secondary to the behavior implemented by the object.

In short, the idea of being able to do a LINQ query across the object model on the client, and having that query serialized to the server so it can be translated into a data query is way outside the scope and philosophy of CSLA.

enzed replied on Thursday, January 27, 2011

Hi Rocky,

I understand your concerns and understand the idea of CSLA.  I agree with it.

Take a look at this http://blogs.msdn.com/b/adonet/archive/2010/12/06/ef-feature-ctp5-code-first-walkthrough.aspx

It would fit in nicely with CSLA. In my experience having a linq query based on the domain and then translated to the persistence has worked beautifully for me in the past.  EF CTP5 makes it hell of lot more easier.

For instance I've been able to shape the query to allow data security concerns to be encapsulated and handled in one discrete place.

I'd also add that CSLA provides the ability to construct critieria (which is a little limiting).  A linq query is therefore a more sophisticated criteria.  CSLA would just need to serialised this specific type.  The orm does the job translating - not a job for CSLA.  The only issue is that CSLA is very tighhly bound to what it can serialise (that is a flaw in my mind - but others would beg to differ I'd expect).

Regards,

 

Nick

 

RockfordLhotka replied on Thursday, January 27, 2011

I agree, the new EF features are very compelling.

But I stand by my 15 year assertion that only the Data Access layer should be aware of the structure of any data entities. The Interface, Interface Control and Business layers should be unaware of the shape of any lower-level data constructs.

And I hold to the philosophy that if you have to do queries over your domain objects to get them into the right shape for your use case, then you did a horrible job designing your domain model. Supporting that sort of query is just enabling bad design imo.

I implemented the entire object factory concept specifically to enable the use of what (I hope) EF is now being able to do, which is to query data entities and map the data into domain objects. All mapping and knowledge of data entities still encapsulated within the Data Access layer, but hopefully simplifying that layer for cases where EF can be exclusively used to do the work.

Whether the new EF features will actually go far enough I don't yet know. It all depends on whether they have appropriate hooks so we can use LoadProperty and ReadProperty to set/get every property value - thereby bypassing common issues like read-only properties, authz and business rules, etc.

Ideally CSLA would include an EfObjectFactory base class that abstracts the CRUD operations for an object when mapping against EF. Or something that provides higher abstraction anyway. But I haven't had time to dig into this at all yet - writing the ebook series is very time-consuming.

enzed replied on Thursday, January 27, 2011

I tend to think this is making too much of it.

I can't see what laws of software engineering are being brokne.  In fact it fits in with the DDD idea.

The expression is just another type of Criteria that's all.  It's not an EF thing.  I'd be using the expression if it where a directroy of files I was querying.  I repeat it's just criteria, just not bound by some imperative programming idea which is being unfairly imposed by CSLA.

Not to get too harsh about it, the philosophy you espouse imposes rigidity which is what we should be avoiding.  Limiting what you can serialise is an example of this. If this was not the case then this post would have never eventuated and I'd be happily doing my design - not screwing it as you are saying. 

So we can disagree - we are coming from a diffrent viewpoint.  But rest assured I know what I'm talking about - I know what I want to achieve - I want to do in less code.

I'd finally say that overall CSLA is quite good.  But some aspects of it are frustrating.

RockfordLhotka replied on Thursday, January 27, 2011

I have no problem with healthy disagreement, that happens all the time :)

I'm just saying that CSLA is an expression of my philosophy, and the features that get implemented support that philosophy. I'm not overly motivated to implement concepts that don't fit the way I view the framework. I do this for free after all - it'd be different if this were a commercial product - then I'd be motivated by the requirements of my highest paying customers ;)

The thing to consider though, is that there's absolutely nothing stopping you from creating an ExpressionCriteriaBase class that serializes LINQ expressions into a form that can be transported over the network. That's not easy (at all), but it has been done by some more ORM oriented products out there. I think LLBLgen does this, and I think they blogged about how they managed to build a serialization engine for expressions - you may find that useful if you go down this road.

Copyright (c) Marimer LLC