﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2021 (c) 2026</copyright><ttl>60</ttl><item><title>Ayende Rahien commented on The right dependency level</title><description>Tobin, yes, the UoW can work with AR, you can check Exesto for the details, or ask in the rhino-tools-dev group.
  
CustomerByCityFinder.With(london).EagerLoad("Orders")
  
  
All you need is to create something that will return a detached criteria, AR can consume that.
  
Take into account that doing this in a general fashion may be a PITA, that is why I have NHQG.
</description><link>http://ayende.com/2551/the-right-dependency-level#comment20</link><guid>http://ayende.com/2551/the-right-dependency-level#comment20</guid><pubDate>Thu, 14 Jun 2007 19:39:14 GMT</pubDate></item><item><title>Tobin Harris commented on The right dependency level</title><description>I've used the xyzRepository.FindXyzByAbc(...) approach in quite a few projects now, and in retrospect there is something a bit smelly about it. Good points made by Ayende and  Tybor: I think the smell I was  experiencing came from the bloated class interface, the business logic in finder methods (SRP violation), and the modifying of the repository class each time you need another finder method (OCP violation).
  
  
@Ayende, @El Guapo
  
It seems this:
  
  
  FindAll&lt;Customer&gt;(Where.Customer.City == london);
  
  
is an example of simple specification objects, as discussed in Eric Evans's Domain Driven Design book? Might be worth El Guapo taking a look if he's interested.
  
  
@Ayende
  
I love this code!
  
  
  FindAll&lt;Customer&gt;( CustomerByCityFinder.With(london).EagerLoad("Orders") ); 
  
  
How do I get that in my ActiveRecord project please!? 
  
  
Also, whilst I'm here, can I get your unit of work class with ActiveRecordtoo? Sorry, don't mean to demand info, just brief pointers in the right direction would be much appreciated ;)
  
  
Tobin
</description><link>http://ayende.com/2551/the-right-dependency-level#comment19</link><guid>http://ayende.com/2551/the-right-dependency-level#comment19</guid><pubDate>Thu, 14 Jun 2007 19:09:09 GMT</pubDate></item><item><title>Frans Bouma commented on The right dependency level</title><description>I would say that using a unit of work class which is used to gather work (thats its purpose) also for persistence work, e.g. all the session work is a combination of concerns actually. So the session should IMHO utilize a unitofwork class, not be one. (Like what Mats explained is IMHO better)
</description><link>http://ayende.com/2551/the-right-dependency-level#comment18</link><guid>http://ayende.com/2551/the-right-dependency-level#comment18</guid><pubDate>Thu, 14 Jun 2007 07:50:35 GMT</pubDate></item><item><title>Mats Helander commented on The right dependency level</title><description>Unit of Work just means Unit of Work, it doesn't imply a session/context. In NPersist, there is a separate UnitOfWork class. The context object holds an instance of that, just like it holds an instance of an IdentityMap and other things. 
  
  
/Mats
</description><link>http://ayende.com/2551/the-right-dependency-level#comment17</link><guid>http://ayende.com/2551/the-right-dependency-level#comment17</guid><pubDate>Wed, 13 Jun 2007 20:53:13 GMT</pubDate></item><item><title>Ayende Rahien commented on The right dependency level</title><description>Would it be more accurate to call what you do batching? Checking Fowler's definition, it looks like that was the original purpose of the UoW pattern, to batch a set of changes to the DB, which was later expanded by users to include all context/session stuff.
  
  
I guess that require a separate discussion about the different patterns, similar to state vs. strategy or decorator vs. proxy.
</description><link>http://ayende.com/2551/the-right-dependency-level#comment16</link><guid>http://ayende.com/2551/the-right-dependency-level#comment16</guid><pubDate>Wed, 13 Jun 2007 20:31:42 GMT</pubDate></item><item><title>Frans Bouma commented on The right dependency level</title><description>Oren, my appologies, I shouldn't reply to blogposts after a full day at a conference and being too tired :). 
  
  
The 'unit of work' pattern is a misnomer: it resembles a unit which contains work. Now, in most o/r mappers, it's implemented as a session or context, the central object which knows all the mappings/meta-data and governs everything. That's a pattern LLBLGen Pro doesn't implement, totally correct. 
  
  
That's not to say we don't support a unit of work pattern, we do: like I described above (which is implemented since 2004 I believe, but I have to check). Our design (let's ignore our selfservicing paradigm for now which has persistence on the entiites, like customer.Save(), some people want that) of our adapter paradigm (which uses a service object to perform actions you want, like commit a unit of work object with work :)) is a decentral design: so there's no central object which controls everything, you don't need that. Of course, if you want to collect work to be performed in one transaction, for example insert a couple of entties, delete a couple, call a proc to delete some entities etc., you can all collect that work in the unit of work object we have so that that unit contains ... work :). 
  
  
You then can call Commit() on it by passing in an adapter object. E.g. one which you create using a little factory so you can decide on the fly to which db you want to commit all the work at that moment, not when the unit of work class is created, because that's perhaps somewhere in the BL tier which has no idea which db's are supported by the app. 
  
  
So my post was a misunderstanding of what you wanted to say. You are totally correct: we don't support the context/session pattern as we have a design which doesn't need that. We do support the pattern to gather work in a unit, e.g. the unit of work pattern :). 
</description><link>http://ayende.com/2551/the-right-dependency-level#comment15</link><guid>http://ayende.com/2551/the-right-dependency-level#comment15</guid><pubDate>Wed, 13 Jun 2007 20:21:19 GMT</pubDate></item><item><title>Ayende Rahien commented on The right dependency level</title><description>Frans, that wasn't the case when we last spoke about it, no?
  
  
I think that I am confused, because I am associating the unit of work pattern with the NH implementation. Can you explain what the differences are between the two?  Maybe I was thinking about persistence by reachability or cascades? 
  
The last time I looked at LLBLGen was about a year ago, sorry.
  
  
Is my basic premise wrong then? Would you say that it is possible to move an app from NHibernate to LLBLGen or vice versa without a lot of hassle?
  
</description><link>http://ayende.com/2551/the-right-dependency-level#comment14</link><guid>http://ayende.com/2551/the-right-dependency-level#comment14</guid><pubDate>Wed, 13 Jun 2007 20:10:27 GMT</pubDate></item><item><title>Frans Bouma commented on The right dependency level</title><description>LLBLGen Pro has a fairly sophisticated UnitOfWork class, Oren. It can track all your work for you and is serializable so you can send it over a wire to get it persisted there. It can take part in a transaction (so you can have multiple unitofworks in one transaction) or in a single transaction. You can store delegate calls to procs, direct batch actions, entity saves, deletes into the unitofwork instance.
  
  
So it doesn't the session approach nhibernate does. That doesn't mean it doesn't support unitofwork, on the contrary. Actually, you can use our unitofwork on the client or in say the UI tier, BL tier, send it over the wire to another service, (remoting), then add more actions to the unitofwork object and then commit it in your dal layer where you have the availability of the adapter to the db of choice. In all the other layers I mentioned you don't have the ability to commit it if you don't want to. That's the best part. 
</description><link>http://ayende.com/2551/the-right-dependency-level#comment13</link><guid>http://ayende.com/2551/the-right-dependency-level#comment13</guid><pubDate>Wed, 13 Jun 2007 19:56:59 GMT</pubDate></item><item><title>Adam Tybor commented on The right dependency level</title><description>@El Guapo
  
  
&gt; I think you just made that up :)
  
Really?
  
  
FindAll&lt;Customer&gt;( CustomerByCityFinder.With(london).EagerLoad("Orders") );
  
  
In the above where is code for querying the DAL,  not encapsulated inside the Finder?  What is my service dealing with, a Repo and Finder, not the DAL.
  
  
Maybe points 1 and 3 are too similar.  Weather your DAL is ADO.Net or NHibernate it doesn't matter, the logic to build the query is encapsulated and isolated in one spot, the Finder.
  
  
Point 2 was probably personal preference, I try and eliminate code duplication as much as I can, how much copy and paste is involved in maintaining FindByXXX for every scenario possible?
  
  
I would much rather use the specification pattern when building complex queries.
  
</description><link>http://ayende.com/2551/the-right-dependency-level#comment12</link><guid>http://ayende.com/2551/the-right-dependency-level#comment12</guid><pubDate>Wed, 13 Jun 2007 16:30:08 GMT</pubDate></item><item><title>Mats Helander commented on The right dependency level</title><description>aCoder,
  
  
Or you could use Linq.
  
  
/Mats
</description><link>http://ayende.com/2551/the-right-dependency-level#comment11</link><guid>http://ayende.com/2551/the-right-dependency-level#comment11</guid><pubDate>Wed, 13 Jun 2007 13:49:21 GMT</pubDate></item><item><title>Ayende Rahien commented on The right dependency level</title><description>aCoder,
  
You use the finder approach outlined above.
  
That would encapsulate the specifics of NHibernate, while taking full advantage on it.
</description><link>http://ayende.com/2551/the-right-dependency-level#comment10</link><guid>http://ayende.com/2551/the-right-dependency-level#comment10</guid><pubDate>Wed, 13 Jun 2007 13:10:59 GMT</pubDate></item><item><title>aCoder commented on The right dependency level</title><description>My real problem is not the dependency on NHibernate from the service layer and beyond. The problem is generalizing the queries I want to make from the client to the service. If we accept the service as being the real application on which I can independently write any kind of client I want (web client, win client), how do I give the service the ability to accept any arbitrary query from the client, without the client being aware of NHibernate or whatever OR/M I use behind the service?
</description><link>http://ayende.com/2551/the-right-dependency-level#comment9</link><guid>http://ayende.com/2551/the-right-dependency-level#comment9</guid><pubDate>Wed, 13 Jun 2007 12:30:56 GMT</pubDate></item><item><title>MHolmgren commented on The right dependency level</title><description>:-)
  
Flashback! Your recommendations have a lot of similarities with the pro/con debate of relational DB-engine dependence/independence from years ago - ie, to couple code to DB specific features, or not. I find that a good thing, we've come a long way debating the same arguments again but this time on a higher persistance abstraction level.
</description><link>http://ayende.com/2551/the-right-dependency-level#comment8</link><guid>http://ayende.com/2551/the-right-dependency-level#comment8</guid><pubDate>Wed, 13 Jun 2007 10:56:05 GMT</pubDate></item><item><title>Jeff Brown commented on The right dependency level</title><description>This is the difference between a service and a framework.  A service, like a Data Access Object, can usually be wrapped or replaced easily because it doesn't change how you structure your application.  A service just sits on the side-lines waiting to be called into action.  A framework, like NHibernate, is very different.  A framework wants to be a layer that sits underneath your application and empowers it to do wondrous things.
  
  
[I'm sure someone can come up with a crazy sports analogy here...]
  
  
Rule of thumb:  Don't ever try to put a framework in a box unless portability really is your primary concern.  If you find you need to do that, quite probably you need to revisit your assumptions or find/build a service on the side instead.
</description><link>http://ayende.com/2551/the-right-dependency-level#comment7</link><guid>http://ayende.com/2551/the-right-dependency-level#comment7</guid><pubDate>Wed, 13 Jun 2007 08:53:33 GMT</pubDate></item><item><title>Ayende Rahien commented on The right dependency level</title><description>@El Guapo,
  
  
Opened Closed Principal. I can extend the query mechanism without touching the DAL.
  
In any real world system, you need a LOT of queries, and queries options.
  
  
For instance:
  
  
FindAll&lt;Customer&gt;( CustomerByCityFinder.With(london).EagerLoad("Orders") );
  
  
</description><link>http://ayende.com/2551/the-right-dependency-level#comment6</link><guid>http://ayende.com/2551/the-right-dependency-level#comment6</guid><pubDate>Wed, 13 Jun 2007 01:46:52 GMT</pubDate></item><item><title>Ayende Rahien commented on The right dependency level</title><description>@ Andreas,
  
  
It is a valid approach to using NHibernate. I am following a parallel, but slightly different tack, but I like it.
</description><link>http://ayende.com/2551/the-right-dependency-level#comment5</link><guid>http://ayende.com/2551/the-right-dependency-level#comment5</guid><pubDate>Wed, 13 Jun 2007 01:45:03 GMT</pubDate></item><item><title>El Guapo commented on The right dependency level</title><description>1) It prevents from dealing directly with the DAL in your services and domain.
  
  
Either approach is calling into the DAL, correct?
  
  
2) It alleviates littering your DAL with methods like FindByXXX
  
  
I have never had a problem reading ReadByXXX, have you? They show up nicely in the VS class browser.
  
  
3) It encapsulates the logic of the DAL in the FInder so your service and domain code stay cleaner. 
  
  
I think you just made that up :)
  
</description><link>http://ayende.com/2551/the-right-dependency-level#comment4</link><guid>http://ayende.com/2551/the-right-dependency-level#comment4</guid><pubDate>Tue, 12 Jun 2007 21:46:55 GMT</pubDate></item><item><title>Andreas commented on The right dependency level</title><description>Might be a little off topic.
  
Just curious about what you think of the approach that is mention in this article old http://www.codeproject.com/aspnet/NHibernateBestPractices.asp.
  
You didn't make much of a comment on it when you refered to it some time ago not what I can remember anyway.
</description><link>http://ayende.com/2551/the-right-dependency-level#comment3</link><guid>http://ayende.com/2551/the-right-dependency-level#comment3</guid><pubDate>Tue, 12 Jun 2007 21:33:31 GMT</pubDate></item><item><title>Adam Tybor commented on The right dependency level</title><description>Where was this advice 6 months ago???
  
  
I am guilty and I was a failure at trying to remove dependencies from NHibernate.  It the end its far easier to keep the dependency and isolate usage in certain areas of the application.
  
  
@El Gaupo
  
1) It prevents from dealing directly with the DAL in your services and domain.
  
  
2) It alleviates littering your DAL with methods like FindByXXX
  
  
3) It encapsulates the logic of the DAL in the FInder so your service and domain code stay cleaner.
</description><link>http://ayende.com/2551/the-right-dependency-level#comment2</link><guid>http://ayende.com/2551/the-right-dependency-level#comment2</guid><pubDate>Tue, 12 Jun 2007 21:12:46 GMT</pubDate></item><item><title>El Guapo commented on The right dependency level</title><description>Why is this 
  
  
FindAll&lt;Customer&gt;(  CustomerByCityFinder.With(london) );
  
  
Really any better than
  
  
DataAccess.GetAllCustomers()   or
  
DataAccess.GetCustomersByCity("London")
  
  
Public static data access methods are easier to read, write, maintain, and re-implement in another library when switching OR/M implementations.
  
  
I think your implementation is geeky cool, but really not any better in reality.
  
</description><link>http://ayende.com/2551/the-right-dependency-level#comment1</link><guid>http://ayende.com/2551/the-right-dependency-level#comment1</guid><pubDate>Tue, 12 Jun 2007 20:35:05 GMT</pubDate></item></channel></rss>