A few quick additions to yesterday's Thoughts on Dependency Injection...

From the second:

This EF behaviour can result in subtle bugs as it is possible to be in a situation where queries may unexpectedly return stale or incorrect data. This wouldn't be possible with NHibernate's default behaviour. On the other side, it dramatically simplifies the issue of database transaction lifetime management.

That would have been good to know a few months ago. ;^)

That post's real take-home is this, however:

While it can be fine to re-use a DbContext across multiple business transactions, its lifetime should still be kept short.
Re-using the same DbContext instance for more than one business transaction can also lead to disastrous bugs where a service method accidently commits the changes from a previously failed business transaction.

I believe it also rightly argues against overusing lazy-loading. I tend to invoke queries fairly quickly, often forcing EF queries to call the database, with a ToList() call. As anyone who has read this blog for long would know, I'm painfully aware of pulling too much, and I don't put database logic in the business layer as a rule -- use the database engine; that's what it's there to do. Doing complicated logic in your "business" layer outside of your rdbms is kind of like writing your own JIT compiler for string manipulation in C. Insane. Use your tools; that's why you license them.

Know that an overuse of lazy-loading can get you into insanely inefficient queries. That is, just because you're "lazy loading" doesn't mean that you're using your rbdms correctly. You should have what amounts to a query builder inside of your business logic. Understand your use cases, write a view or sproc, and let your rdbms optimize. Don't get lazy with the justification that you're going to lazy load and that it's the same as writing SQL [in that it's work pushed to the dbms]. It's not the same.

Also keep in mind that Dependency Injection isn't nearly as fancy as it sounds. I think DI is usually couched in a very specific context that also involves an injection system, making the actual injection a somewhat obfuscated process, as I complained earlier. Getting familiar with all of that system's dependencies can be overwhelming at first glance, but, trust me, the concept itself is simple.

AndN .et MVC already has DI installed! Though I can never approve of sleeveless shirts for men in tutorial videos, this one is otherwise quite useful showing how quickly and easily DI can be in a .Net MVC project.

And even then, keep in mind how simple Inversion of Control really is. You probably do it a lot already to keep your code defensive and maintainable. You don't want your objects to depend on anything extraneous, so you'll often find yourself sending along something major to help your business objects get their work done. For instance, when you send along event handlers to widgets, that's a sort of IoC already! Told you you were familiar with it.

Labels: , , ,