Moving Criteria to the DAL interface

Moving Criteria to the DAL interface

Old forum URL:

tiago posted on Monday, October 24, 2011

Hi Rocky,

I have this SearchCriteria with 13 properties. Under the Encapsulated Implementation model it used to be a protected POCO class that was nested in a ReadOnlyBindingListBase class. Now I'm moving the project to Encapsulated Invoke and of course the 13 properties are still needed to make a decent search.

The DAL interface must know about a POCO object that stores the 13 properties as this object is passed as parameter of a Fetch method overload. None of the 13 properties is used by the interface itself. The options are:

1) Keep the SearchCriteria on the Business/Library assembly but make it inherit from an interface definition in the DAL interface. On the negative side, on the DAL implementation, an equivalent object must also be defined.

2) Move the SearchCriteria to the DAL interface assembly and use this object on the Business/Library and on the DAL implementation (somewhat like you do with DTOs).

I think everyone agrees option 2) is the simplest one. Now suppose this SearchCriteria class was changed and inherits from CriteriaBase or even BusinessBase. Defining the class on the DAL interface would make it dependent on Csla. Then again, DataNotFoundException class used on the EncapsulatedInvoke samples is already dependent on Csla.

What do you think?

StefanCop replied on Tuesday, October 25, 2011

I think option 2) is fine.

Here's another idea. The CodeSmith's Csla Templates uses a   Dictionary<string, object> _bag  to store alle criteria values.  And it passes this Bag to the DAL as a generic structure to construct the where clause.

When generating you can choose the keys in the dictionary equals to the column names, while the property names correspond to the business:

public string Iso3166Alphabetical
   get { return GetValue< string >("iso3166alpha3"
); }
   set { _bag["iso3166alpha3"] = value
; }

For some additional reasons, I made the Business a "friend" assembly of the DAL (I've no interfaces yet). So the DAL can access all internals of its Business counterpart, and the Criteria and DTO are in the Business.

tiago replied on Tuesday, November 01, 2011

On second thoughts, this can be handled in a couple of different ways. Some notes:

1) In what the DAL is concerned, criteria parameters are just parameters to pass on to the SQL query. As Stefan Cop pointed out, a Dictionary<string, object> is a form as good as any other. Maybe not the fastest alternative though.

2) Another way to do it is to let the Criteria class live in the business layer and to pass the criteria parameters to the DAL as method parameters. This is brings back the DTO or no DTO question. One of the issues is readability of the code. According to "Code Complete" author's advice, for readability sake the maximum number of parameters one should use is 7. If one has to pass more than 7 parameters, use 1) or 3)

3) Or we can do as stated before: move the criteria class to the interface layer.


StefanCop replied on Wednesday, November 02, 2011

I totally agree with you. Some more notes:

1) Such a generic structure has the advantage, that the presence or absence of entries indicate what you want in the where clause (as used by codesmith tempates), and as .NET type it is always accessible. On the other hand, you can add errornous entries, no safety. 
The templates cerate an accessor to the dictionary, which is in fact the Criteria for a BO. So, business code will only manipulate the dictionary through the Criteria wrapper.
In my opinion, if you don't benefit from dynamic creation of SQL Where clause, don't use a dictionary, but tailored type.

2) I suppose, you don't think criteria and DTO are the same. But the both help to overcome the problem not having to many parameters.

3) If you think of a true API or service contract, then all structures (and exceptions) which are referenced by interfaces are also part of the interface.
Therefore, DTOs (row data or criteria) belong truely to the interface layer. 

tiago replied on Wednesday, November 02, 2011

stefan cop

In my opinion, if you don't benefit from dynamic creation of SQL Where clause, don't use a dictionary, but tailored type.

True. I can use criteria or a "tailored" type with dynamic WHERE creation; if a property is NULL, don't add that property to the WHERE clause :)

Copyright (c) Marimer LLC