March 2007 Entries

Midway through the week with JP

 

So this is the first time I've really had a chance to post anything this week.  We're hosting Jean-Paul Boodhoo this week for his Nothin' But .Net bootcamp course, of which I've been lucky enough to be able to attend.  I think it's pretty clear now from other's experiences (and from my own so far) that the benefits from a course like are huge, so I won't detail them here (yet).  I mean, how often do we (developers) get to spend a week in a room full of other developers from varying backgrounds having discussions and driving out a reference application using TDD, proper refactorings and design patterns with an experienced mentor like JP right there in the action?!? 

For me, I know that's a pretty rare situation.  The pressures of timelines, estimates and a lot of the other "stuff" that comes along with "real" projects usually doesn't allow for this kind of concentrated learning environment.  Even though I've read and am reading quite a few patterns and design books, this week I've seen a lot of the techniques I've read about (and somewhat used) actually put into practice in very elegant ways (i.e. patterns like strategy, visitor, decorator, etc.). 

So one of the things JP mentioned this week (and also in this post) that I very much agree with is that if you want to improve your skills and be able to write better, maintainable software, you have to be a student of your profession.  Meaning you have to always keep sharpening your skills by doing things like learning a new language each year, read a book a month, etc.  And instead of trying to learn everything about everything, just concentrate on those areas for which your current (and somewhat immediate future) work pertains.  Otherwise, you could be wasting a lot of that time learning things, you will most likely rarely, if ever be able to put into practice.

To wrap it up for now, here are a few of the recommended books that were talked about as recommended reads:

Non-Technology Specific

Technology Specific

Even though I've read half of these books, I'm always going back and revisiting their content on an ongoing basis, and will probably continue to do so as I put more and more of their techniques into practice.  Sometimes you just get a fresh perspective on things when reading it again a year later.  But I've been wanting to read Code Complete 2 anyways, so working my way down the list, I think I may pick up a copy of that to read next.

Sorry, no code in this post.  I'm going to try to keep the number of non-code postings down from now on...

See you next week at the Richmond Boot Camp

 

Looking forward to spending a week with JP and all those who'll be attending the Nothin' But .NET Boot Camp next week at TCSC.  I've been working off-site at a client for almost a year now, so it'll be nice to get back to my "home office" at TCSC for some training.  Looks like we'll have a decent turnout.  I'm sure I'll be blogging next week, and from the sound of it, it's going to be awesome!

Switched back to Subtext

 

So I have a bit of blog engine ADD.  So now I'm going back closer to my roots of .TEXT using Subtext (a fork of .TEXT).  I used Subtext a little back in the day, then moved to DevAuthority for a while which uses Community Server, then moved back here to joeyDotNet.com and started using dasBlog.  I mostly liked it and how simple it was to set up without the need for a database.  But I had some quirks and some folks were having problems posting comments to my postings.  It may have been something easily fixed, but unfortunately my time is limited these days for troubleshooting something like that.

Besides, .TEXT is still my favorite single user blog engine.  So since Subtext is the closest thing to that, I think that's where I'm going to stay.  And this origami skin for Subtext is one of the best skins I've seen on any blogging platform.  One of these days I'll get back to creating some skins of my own again, but for right now this one is sweet!

Anyways, who cares about all this non-technical stuff.  Look forward to many more posts on the Castle project including MonoRail and ActiveRecord.  I'm going to be utilizing both of these on one of my current projects!

Reminder - How to enable syntax highlighting for HTML files with non-standard extensions

 

Or, another title could be "how to quickly enable syntax highlighting and intellisense for MonoRail view file types"...

Mainly just for my reference, 'cause I can never remember the Guids for all those editor types in the registry for Visual Studio.  :)

Just add a couple DWORD names/values to the following registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\Editors\{8281C572-2171-45AA-A642-7D8BC1662F1C}\Extensions

  • boo/27 - for Brail
  • vm/27 - for NVelocity

Fix for MonoRail RC2 VS add-in not generating Active Record facility config correctly

 

First, thanks Hammett for pointing me to the solution for this. 

(Hammett pointed me to the updated documentation for ActiveRecord and by copying that config, it fixes these problems.  In case you don't want to copy that config, see below about what the fixes are in case your curious and if you want to apply them to your current config.)

If you fire up VS and add a new MonoRail project using the wizard, enabling Active Record and Windsor integration, create a quick domain object mapped using Active Record, add it to the HomeController Index action and fire up the web app, you'll get this error (down further in the stack trace):

Item has already been added. Key in dictionary: 'hibernate.use_reflection_optimizer' Key being added: 'hibernate.use_reflection_optimizer'

To fix, remove the following line from the facilities.config file:

<add key="hibernate.use_reflection_optimizer" value="true" />

I believe this is because ActiveRecord is already taking care of adding this behind the scenes, so having in the config a second time is not necessary.

So then fire it back up and now you'll get this error message:

The user must provide an ADO.NET connection - NHibernate is not creating it.

To fix, just add the following line to the facilities.config file:

<add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />

That's it.  Now you can rock and roll!

Since when is it bad to be enthusiastic about OSS development tools?

 

Apparently, some folks won't try out anything without seeing "facts" or "substance".  In my previous post about my first impressions with the Castle project, it was basically just a brain dump of all the stuff I had learned and realized by playing with it over the period of a couple days. 

So to answer the commenter from DotNetKicks, no I haven't yet posted any examples of my own, because I felt I couldn't necessarily post anything "new" yet, other than the numerous samples that I was able to find online.  That's why I included a resources section at the bottom of my post.  Perhaps the commenter didn't read that far into my post.  If not he probably didn't catch my statement right before that either...

"I hope to post a lot more on these topics including some sample code."

On a related note, this kind of mentality is also something I see a lot of in the land of Microsoft developers.  One Microsoft Way or the highway.  You can't deny that there are some great development tools, OSS frameworks and languages out there that can really make us all do better at our jobs, even though they don't come directly from Microsoft headquarters.  If you never take the time to play with this stuff, your cheating yourself out of a lot of learning experiences that can actually help you with your day to day work (whether you actually use the tools on your "day job" or not). 

Besides, as usual, Microsoft continues to incorporate re-invent a lot of these tools and frameworks into their future products.  Just look at the recent stuff about an MVC framework coming from Microsoft, or the C# 3.0 language with syntatic sugar to help make it seem more dynamic in nature (even though it's not) like Ruby or Boo.  So either way, you're going have to learn it.  Why not be ahead of the game and start learning some of this stuff now.

Microsoft obviously has some serious talent working for them.  But I just wonder how much better their development tools would be if they embraced some of the existing frameworks and tools in the community.

So bottom line, using tools that help me do my job better make me happy (dare I say enthusiastic) whether they come directly from Microsoft or from the great community of developers working on OSS projects.

Is that a bad thing?

Castle MonoRail & ActiveRecord - First Impressions

 

Dear ASP.NET WebForms,

No longer will us web developers who happen to like C# and ASP.NET be a slave to your page lifecycles, control hierarchies and bloated viewstate.  Never to fear, MonoRail is here!  You may not want to read the following post as it may be damaging to your well known reputation among typical Microsoft web developers.

An Enlightening Experience

I've spent quite a few hours over the past few days playing with the amazing Castle Project (long overdue for me), mostly MonoRail and ActiveRecord.  All I can say is WOW!  As primarily a web developer who mostly uses ASP.NET, this is quite revolutionary for me.  Like most ASP.NET developers, I've had to become very familiar with the managing the page lifecycle, postbacks and all of the stuff that goes along with it.  Of course these things have their positives too (mostly for the "drag-n-drop your way to an unmaintainable enterprisey application" folks), but they definitely have their downsides, including hiding the stuff for which "web developers" really should have a good understanding

Disclaimer: Again, I've only started to tap into what MonoRail and the Castle project as a whole can do for us as developers, so be sure to read, read, read all the good stuff on the Castle project's web site to really learn what these frameworks can do for you.

The MVP/WebForms Way

I've been heavily using the Model-View-Presenter pattern (I usually prefer the Passive View flavor) now for quite a while.  It's greatly increased the testability of my ASP.NET/WebForm applications by abstracting most of the presentation logic into a separate testable layer of the application.  So MVP has been great for testability, not necessarily for reusability for other UI implementations like WinForms as some claim (sounds great in theory, but doesn't really play out in the real world in my experiences).  Unfortunately the page/view is the first thing that gets processed on each request.  This is usually not a huge deal since most of the time the WebForm code-behind is usually just a series of property implementations and some code to wire up control events to the presenter.  At least this is all it should be, but too often folks (sometimes including myself) are tempted to put logic into the code-behind that should be there, making it much harder to test.  Hmm, the term "wire up" smells like infrastructure code.  Let's see how a MVC framework could help us increase testability and reduce the amount of infrastructure code we have to write.

MVC To The Rescue

MonoRail is a true MVC framework for ASP.NET meaning the "controller" is the first thing that gets processed on each request, unlike WebForms as noted above.  This is somewhat subtle if you're using MVP/WebForms since most of the presentation logic is still in the somewhat analogous "presenter" class.  The beauty of MonoRail is that most of the infrastructure logic to wire the controller and view together are where they're supposed to be, in the framework.  By favoring convention over configuration, you can develop your UI/Presentation layer very quickly with MonoRail.  A couple great examples of this are the Getting Started article on the MonoRail site and this great screencast by hammett showing off some of the cool form validation stuff "baked in" to MonoRail.  I'm not going to delve into all of the good stuff that MonoRail offers right now, but suffice it to say, what I've seen so far covers quite a bit of what most projects would need.

ActiveRecord.CreateSimplicity()

I've known about the Active Record pattern for quite a while and frankly it's taken me quite a while to warm up to it.  Having methods like load and save on my domain objects has long turned me off from attempting its use in any of my projects.  I've usually preferred to use something like the Repository pattern instead, which of course is still a great way to develop your data access layer.  But after playing with Castle's ActiveRecord implementation, the simplicity in using it is quite refreshing.  The fact that my domain objects "know" about how it maps to the database and load/save itself is something I'm still a little weary of, but I can't deny the huge benefits you can gain from using this pattern when its appropriate.  As with most of the Castle projects I've played with so far, the syntax is very sweet and is definitely along the lines of a fluent interface.  And the built-in extensible validation framework is just what the doctor ordered for one of my current projects.  Imagine having your validation rules and error messages in a single place that can even be shown in the UI via MonoRail.  This is reality as shown by the screencast mentioned above!  You simply can't deny that kind of productivity benefit, and I'm all about increasing productivity without sacrificing maintainability.

Conclusion

So this should sum it up.  In my first 2 hours playing with MonoRail and ActiveRecord, I was able to TDD my way into developing a significant portion of the domain model from one of my current projects, including validation, database schema generation, integration tests against a real database and some scaffolding in MonoRail for dynamic generation of basic CRUD pages for the domain model.  Oh yeah, I didn't even get into scaffolding, but believe me, very cool indeed for rapid prototyping.  And of course Windsor for IoC is a whole 'nother animal that is very powerful and kind of at the heart of the Castle project as a whole.  So if you're like me, you're saying to yourself, "where do I sign up?".  I hope to post a lot more on these topics including some sample code.

Resources

So here's a very short list of some the resources I've found so far:

On my developer "need to read" bookshelf...

 

As I'm wrapping up the most excellent Applying Domain-Driven Design and Patterns by Nilsson, I have started cracking into the original Domain Driven Design book by Evans (yeah, I know, most people probably would have read this one first, oh well, guess I'm a rebel).  So once I inject that DDD theory into my brain (not much room left, but I suspect it will take the place of my rarely used PC hardware and overclocking brain cells), I need to whip through the 3rd book I got last Christmas, Venkat's Practices of an Agile Developer

So what's next on the horizon?  I'm thinking...

What else are my fellow developers reading these days?

Validating business rules which require a call to a repository - one approach

 

Ayende has a couple of recent posts which relate to entities, services and repositories.  In some of the comments, it was briefly discussed about if/how you should validate dynamic business rules that require a call to a repository.  Ayende mentioned this in one of his comments:

About business logic that needs talking to the database.
I would strive very hard to avoid doing it. Entities validate business logic by traversing the object graph they have, not by calling to the database.
Calling to the database makes it a lot harder to just start a new entity and run business logic.

I would agree it's not ideal and it does certainly make it harder to deal with the situation where you've changed the domain object but it's invalid, so you don't want to persist it.  It just so happens I'm having to tackle this problem right now in one of my projects.  Here's one way I've approached this so far, though I'm sure there are better ways.  So please let me know what you think...

One Approach

First off, one of my current approaches to business rules in general is similar to what Jean-Paul Boodhoo demonstrates in his posts on Validation In The Domain Layer.  I just really like how clean this kind of approach plays out.  Anyways, here goes...

So a simple rule might be something like a product cannot be saved if it's name is a duplicate of another product (this is an actual rule, though not for products, that a handful of my domain objects have in my current project).  So here's what a service might look like:

public class ProductService : IProductService
{
private readonly IProductRepository repository;

public ProductService(IProductRepository repository) // injected
{
this.repository = repository;
}

public IBusinessRuleSet SaveProduct(ProductDTO productDTO)
{
try
{
repository.BeginTransaction();

Product product = repository.FindById(productDTO.Id) ?? new Product();
product.Name = productDTO.Name;

IBusinessRuleSet brokenRules = GetBrokenRulesFor(product);

if (!brokenRules.IsEmpty)
{
repository.RollBackTransaction();
return brokenRules;
}

repository.Save(product);
repository.CommitTransaction();

return brokenRules;
}
catch (Exception)
{
repository.RollBackTransaction();
throw;
}
}

private IBusinessRuleSet GetBrokenRulesFor(Product productToSave)
{
productToSave.AddBusinessRule(InitializeDuplicateRuleUsing(productToSave.Name));

return productToSave.Validate();
}

private IBusinessRule<Product> InitializeDuplicateRuleUsing(string productName)
{
IBusinessRule<Product> duplicateRule =
Product.Rules.DuplicateProduct(delegate(Product productToValidate)
{
return
new DuplicateProductSpecification(
repository.FindByName(productName)).IsSatisfiedBy(
productToValidate);
});
return duplicateRule;
}
}

And here's an example of the Product domain object:

public class Product : DomainObject  // base domain object has Validate and other validation properties and methods
{
private string name;

public string Name
{
get { return name; }
set { name = value; }
}

public Product() : this(null)
{
}

public Product(string name)
{
this.name = name;
}

public static class Rules
{
public static IBusinessRule<Product> DuplicateProduct(
Predicate<Product> rulePredicate)
{
return
new BusinessRule<Product>("DuplicateProduct",
"A product with this name already exists.",
rulePredicate);
}
}
}

I like this because the rule itself including its description is still declared inside the domain object, but the logic for validating it is passed in via a Predicate.  This keeps the domain object from directly referencing the repository, though I have thought about trying that approach as well. 

Challenges with NHibernate

I did run into a couple challenges with NHibernate which I resolved by specifically managing the transaction and setting FlushMode to Commit instead of Auto.  This is needed because, as Jeffrey Palermo points out, queries using ICriteria and IQuery may flush changes to the database when set to Auto which is not good news when the result of that query may determine whether or not you want to persist the object in the first place.

Conclusion

I'm still looking for a more elegant solution, but this is getting me by for now.  One minor change might be to extract out the initialization of the duplicate rule into a class implementing the IBusinessRule<Product> interface to get rid of the private methods in the ProductService class.  I'm sure I'll make other changes as needed and as I learn better ways to structure entities, services and repositories. 

Looking forward to "getting my learn on" in Jean-Paul Boodhoo's upcoming class down here in Richmond, VA.  :)