stefcl wrote:
Thanks for sharing your advice... Please let me ask you one last question :
Do you think it's a wrong approach to construct prefetch paths and filters in the GUI layer and to pass them to a BL method which returns entity graphs?
It gives a lot of flexibility to the forms for efficiently querying the datas they have to display but on the other hand, it reduces abstraction.
In fact you could have multiple overloads of BLL methods like GetCustomerById(...), GetCustomerByName(...), GetCustomerByIdWithOrders(...). Or perhaps just one or two like GetCustomers(IRelationPredicateBucket, ISortExpression), GetCustomers(IRelationPredicateBucket, IPrefetchPath2)
What would you recommand?
In DDD land people tend to speak about 'specifications'. So in layer X (e.g. the UI) code specifies what it wants, in terms known to the application. Those specifications are then send down to the layer X+1 which can understand the specifications and can fulfill the request of the layer X.
If you don't want to tie your layer X to what X+1 uses internally (e.g. LLBLGen Pro), you need to write your own specification stuff. If you don't mind, you can use the specification elements LLBLGen Pro offers you: prefetch paths, filters, relations, projections etc.
The thing is that the urge to avoid 'specifications tied to a given o/r mapper' is often based on a myth: even with POCO stuff, your entities are tied to the o/r mapper, and behavior of them will be dependent on the o/r mapper used.
That's not to say that it's not wise to look into a generic specification system: it can be easier sometimes to have such a system, and the most basic example of that is a BL API with methods like 'GetCustomersFilteredByCountry(string country)'.
What you should think of is: is the extra time spend on an API like that worth it? If your app is using LLBLGen Pro entities in the UI, you could opt for a mix of these elements or go all the way for writing filters at the spot where you need them.
The question 'where to write the code to specify the filter for a given set' isn't easily answered. If you need the set defined by the filter at 3 different spots in your application, one could argue to write a method for that and call that method at those 3 spots. However that can hurt you if you need to update the filter for 1 of those 3 spots after a while.
So it's a tradeoff. If you know up front where you need which data, you can write an API. if you don't know that up front, you can write a couple of generic methods which accept filters, sorters etc. and do the fetching there and return the data based on the filters specified.