Jan 16
Downtime
icon1 Darrell Mozingo | icon2 Misc. | icon4 January 16th, 2010| icon3No Comments »
downtime

My home-ran Linux server crashed shortly after the first of the year. I’ve gotten really good up time with it since I started using it 6 years ago, with only a power supply dieing on me once, and other than that having gone years at a time without having to do a single thing - even rebooting. Well, I’m thinking the motherboard gave out this time, and I really don’t feel like messing with the server any more between software updates and hardware issues (plus it was hosted in my company’s data center, and with a few of the ideas I’m hoping to bring to fruition this year, I don’t want to overstay my welcome there!).

So I moved to an actual hosted solution with Site5. I never realized it’d be so hard to find a freakin’ provider! I understand it’s probably the nature of the beast, but it seems like there’s no single provider out there that damn near everyone just loves, even as you move up the price scale. For every story about someone being with a host for years without a single problem, there’s one where they guy’s site was down every other day and he lost half of his data in a crash. Eek! I’ve have heard good things about Site5’s Ruby on Rails hosting and their uptime in general, however, plus they provide SVN & Git on all their servers so I don’t have to worry about hosting that separately with GitHub or Unfuddle, so I took the plunge for a year to try them out. Pretty good so far, though there were a few hiccups such as having to move my DNS hosting to them and at least one server outage. Guess I’ll see how it goes.

Anyway, that’s why the site was done for two weeks or so. Hopefully it shant happen again any time soon.

Jan 3
2010 Goals
icon1 Darrell Mozingo | icon2 Goals | icon4 January 3rd, 2010| icon3No Comments »

Time to lay out some professional and coding related goals for 2010:

Books

  1. Code Complete - Steve McConnell
  2. Patterns of Enterprise Application Architecture - Martin Fowler
  3. Applying Domain-Driven Design and Patterns - Jimmy Nilsson
  4. Working Effectively With Legacy Code - Michael Feathers

Tools/Techniques/Processes @ Work

  • Move from SVN to Git (and learn more about Git in the process).
  • Move from CC.NET to Team City for our build server.
  • Build a more robust build script and management process - including production deployment and database migration scenarios.

Involvement

  • Develop an idea I was given for an open source project and get it live to see what happens.
  • At least 24 blog posts (I’m not going to say 2 per month as I’m getting married this summer and I’m certain I won’t be able to maintain a schedule around it).
  • At least 3 feature/patch submissions to open source projects.

Coding

  • Get a version 1 out there on at least 1 of the 3 product ideas I have floating around.
  • Keep working on a good working knowledge of Ruby & Ruby on Rails (and use it to build the product mentioned above).

Pretty similar to last years goals overall, actually. I’ll be updating my progress every 3 months instead of 2 this year though.

Set any goals yourself this year?

Jan 2
2009 Goals - Year End Update
icon1 Darrell Mozingo | icon2 Goals | icon4 January 2nd, 2010| icon31 Comment »

2009’s over. How did I do on my goals for last year? Let’s see (comments in italics after each goal):

Books

  1. Code Complete - Steve McConnell (yep, I’ve never actually read it)    No progress.
  2. Patterns of Enterprise Application Architecture - Martin Fowler    No progress.
  3. Domain Driven Design - Erick Evans    Done.
  4. Working Effectively With Legacy Code - Michael Feathers    No progress.

Tools/Techniques/Processes @ Work

  • NHibernate and all its trimmings (FluentNHibernate, LINQ to NHibernate, etc), which I’ll need on a project here real soon.  Done.
  • Actually move from CC.NET to Team City (last attempt didn’t go so well).  No progress.
  • Build a more robust build script and management process - including production deployment scenarios.   No progress.
  • Messaging framework, either MassTransit, NServiceBus, or Ayende’s new Rhino Service Bus if he’s able to release it in time for our current project.  Didn’t need it, so no progress.

Involvement

  • We have weekly meetings to catch everyone up on what we’re doing, but I want to present on an actual topic during at least 2 of these - and present in a way where the other development teams will see the use in picking up the presented tool/technique.    Meetings still halted - no progress.
  • Have at least one meeting of the CantonALT.NET group and see if it can ever get up on its feet.   No progress, and more than likely dead in the water :(
  • The two blog posts per month target John put out there seems doable, so I’ll borrow it :)    Spot on, but no posts during October or November. I’ll consider this goal missed, then.
  • At least 3 feature/patch submissions to open source projects.  Done.

Productivity

  • Trim RSS feed size by 1/3 (presently at 127, so trim it to at least 85) and cut time viewing it by half. I’ve gotten much better this past year at cutting through the useless stuff, but there’s still a lot there and it sucks up too much of my time.  Done.

So, overall I completed 4 of my 13 goals - 31%. Ouch. To be fair, 2 of the goals were out of my hands (didn’t need a messaging framework at work yet and didn’t want to think up some rinky-dink example project to try it on, and our weekly meetings were cancelled for me to present - though I could have found another venue to present). I was also pretty close on the blog posting goal, only missing a few because I ran short on ideas for a couple of months there.

Ah well, at least I gave them all a shot and completed at least one from each category. I also knocked off a lot of my personal goals for the year, so they sort of balanced out. I’ll post my code related goals for the upcoming year later this week.

How’d everyone else do? Have any new ones for this year?

Dec 23

I think I can safely say I finally “get” dependency injection (DI) and the need for a framework (such as StructureMap, Ninject, Windsor, or any other). More importantly, I think I finally get the best way to use it in an application. Its taken me a bit to get to this point, and almost everything I’ve read and heard on the subject was very hand-wavy, at least to me. So here’s my attempt at demystifying the subject along with a straight forward way to go about using it in your application, something I wish I could have heard a while ago.

What is it?

Many objects have an outside dependency of some sort. Instead of creating the dependency inside your class (by doing something like myDependency = new Dependency()), you want these dependencies to be “injected” in, usually by the constructor:

1
2
3
4
5
6
7
8
9
public class OrderProcessingService
{
	private readonly IRepository _repository;
 
	public OrderProcessingService(IRepository repository)
	{
		_repository = repository;
	}
}

That’s it. Seriously. It’s not hard to grasp, and you’re probably already doing it, but the trick for me was figuring out how to actually go about using this in any sort of sane and recommended way, as you’ll notice the requirement is now on the caller to provide an instance of IRepository. If you want more details on this pattern, there’s plenty out there.

Why should I bother using it?

  1. It takes handling the dependency’s life cycle out of your hands. Perhaps you want your database access class to stick around for a whole web request, another object to be a singleton, and another to be per thread when used in a Windows app, but per request in a Web app? Using a proper DI framework/container, you don’t have to worry about writing anything to support that, and changing the lifespan of a given object is a one line (and usually even enumeration value) change.
  2. It loosens up your code. You’re no longer “newing” up your data access or web service classes right in the middle of your operation. Swapping out implementations of, say, an interface, is a simple operation that’s located in one place. Just stick the dependency in your constructor, and you’re good to go. I’ve actually used this in quite a few places beyond the academic and largely unused-in-the-real-world “switching from Ms SQL to Oracle” examples, too.
  3. Greatly eases and simplifies unit testing. In many cases, using dependency injection is the only way to unit test portions of your code base (unless you use a certain tool to do it for you). By taking your dependencies in your constructor, you’re giving your unit tests a seam to inject fake implementation of these dependencies. This lets you skip actually hitting the database, web service, hard drive, or anything else that would kill the running time of a unit test or be almost impossible to setup and control in a repeatable manner.
If you’re looking for more detailed reasons, you’ll again want to refer to the gobs of information already out there.

How can I use it?

Ah, now for the juicy part I know you’re all dying to hear: how the hell to actually use the pattern in conjunction with one of the tools I mentioned at the beginning of the post. Before giving away the answer, let’s quickly go over the three primary ways to use a DI container in your app:

  1. Service locator: this pattern is generally considered a no-no, as it still burys your dependencies deep inside your code. Sure, you can swap them out when needed for unit testing, but they’re still very opaque and will almost certainly get very hard to work with, very fast:

    1
    2
    3
    4
    5
    6
    
    public void ProcessOrder()
    {
    	var repository = IoC.Resolve<IRepository>();
     
    	// Do stuff with repository.
    }
    In the above example, IoC.Resolve is a simple static method that delegates to whatever DI framework you’re using. Callers won’t know about this dependency, though, and without fully boot strapping your framework in your unit test (icky) or injecting a fake into your container, the call will either throw or return null, neither of which you want to be checking for everywhere.

  2. Poor-man’s dependency injection: This is a slight twist on normal constructor DI. You have one empty constructor for most of the program to use, which delegates to a “loaded” constructor that unit tests use. While making the dependencies clear, this removes lifetime management from the container’s hands, and also gets ugly when you start changing dependencies around. This is usually used in conjunction with the service locator pattern above:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    public class OrderProcessingService
    {
    	private readonly IRepository _repository;
     
    	public OrderProcessingService() : this(IoC.Resolve<IRepository>())
    	{
    	}
     
    	public OrderProcessingService(IRepository repository)
    	{
    		_repository = repository;
    	}
    }
  3. True dependency injection: Classes generally have only one constructor which takes in all the required dependencies (see the first code snippet at the top of the post).
#3, true dependency injection, is the one I had no idea how to go about setting up in my app. Everyone said not to use the service locator pattern or poor-man’s dependency injection, but how was I supposed to not use them and still get everything injected in? It seems like I was never supposed to call my DI container’s Resolve method. So what gives? Every time someone got close to answering it, it seemed like they’d blow off the question. Ugh.

After enough playing around, reading, and looking at other open source projects, though, it finally clicked: only call Resolve at the furthest edges of your application, and as few times as possible. So what does that mean and where should you be calling it in your app? Well… it depends.

Wait, isn’t that just another cop-out?

Well, yes and no. Yes in the fact that I’m not giving a solid answer, no in the sense that it really does depend on your application: what frameworks you’re using, how you have its architecture setup, etc.

Just so you can’t say I’m not providing anything solid, here’s how I’m using it in our current app:

  1. We’re using ASP.NET MVC & StructureMap, so we’re using a custom controller factory that creates controllers from the container. This means we can create an EmployeeService, extract an interface for it named IEmployeeService, put it as a requirement in the controller’s constructor, and it’s satisfied magically at run time. Even cooler, everything down the object graph from EmployeeService (say, an EmployeeRepository, or LoggingService, or EmailService, or anything else you need) gets their dependencies all satisfied automagically, too. We can stick a constructor argument in virtually anywhere and it’s taken care of for us, without giving it a second thought! Each web request, this all gets built out.
  2. We have a basic home brewed scheduled task framework that, given the name of a task you want to run (say /run Emailer runs the EmailerTask), instantiates the requested task class, and runs it. We use the container at the point of instantiation, effectively treating each “task” class as a controller from above, filling all the dependencies it needs down the object graph.
  3. We also fire off the scheduled task app by doing an IoC.Resolve<IApplication>().Run() in the console app’s Main method, giving the app everything it needs.
In all, we call IoC.Resolve only 4 times in our app, and it handles everything for us. We usually forget it’s even there, and take its services for granted when working with legacy applications that don’t have it.

Now, what if you’re using WebForms? Well, you’re not *completely* out of luck. It’s a pain, to be sure, but still doable.

Wrapping up

I hope this helped cleared up dependency injection for you a bit. Just remember to use the actual Resolve call of your container in as few places as possible in your application, and only on the “outside edges” of the app. Look at where you do all your main object creation (your web forms, Windows forms, controllers, WCF factories, Silverlight pages, etc). Stick the call in there, and forget about it.

Good luck.

Dec 4
Branch-Per-Feature in Subversion
icon1 Darrell Mozingo | icon2 Source Control | icon4 December 4th, 2009| icon38 Comments »

Preamble

Branch-Per-FeatureDisclaimer: My team and I have only been doing this for a short time, so please, for the love of all that is holy, don’t take my word as gospel on any of this. We’re learning more about this each day, but we’re still far from proficient or experienced. I’m just putting what we do and what we’ve learned out there to possibly help others, as I know we would have loved to hear this when we started. If you blow up your repository and lose all your code, it’s not my fault.

That said, lets discuss what Branch-Per-Feature is and how it typically works. I won’t get into much detail on why you should do it or what it is here, as Derick Bailey has an excellent, though unfortunately unfinished at the moment, series of posts on the subject and they’re a must read to get a solid background on this. In a nut shell, though, Branch-Per-Feature is basically what the name implies - you create a branch in your source control system for each “feature” you work on (where the “feature” can be defined as big or as small as you want - we’ll skip doing this for typos and the like). You can then work on that feature in isolation in your own branch, committing your changes as often as you like and not screwing up your other teammates or being affected by them, until you’re all finished, at which point you merge the completed feature back into the trunk. Using this methodology, the trunk should always be kept in a “shippable” state.

Sounds easy enough, right? As is often the case, however, the devil is in the details. I’m sure the first thing that jumps out at you in reading about this is “how the hell does this work with multiple developers?”. Well, the theory goes that as you’re working on your feature branch, you continuously merge changes from the trunk (i.e. features other developer’s have finished) into your branch. This means instead of merging after 2 weeks of work and finding a crap load of conflicts, you have a few here and a few there. In practice it generally works out that way, too, unless you or a team mate goes on a refactoring rampage and you need to merge those changes in (I’m usually guilty of this myself - sorry guys!). Following SRP and the small class sizes that result from it helps in the fact that multiple people usually aren’t working in the same class, too.

Simple scenario

I’ll walk through the steps of a simplified “feature” branch from start to finish. Simplified here means you’re either working by yourself, or you know nobody else has changed the trunk while you’re working on your feature. As the title of this post alludes to, I’ll be showing this using Subversion coupled with TortoiseSVN, so I’m not terribly sure how it’ll work with similar source control systems. Also, while all the tools and practices that I’m going to show here do help with merge problems and the like, they’re not a substitute for using actual communication on your team inorder to avoid problems. Sorry, but you just can’t get away from talking to people :)

Note: all of this is shown with a version of Subversion & TortoiseSVN > 1.6, as many of these features have only been included since then. Make sure the server, client, and your repository are upgraded to at least this version (especially check the repository, which needs upgraded separate from the server, which we learned the hard way). Ask your admin if you’re unsure about any of this.

Now, say we have a repository named BranchPerFeature with the standard /trunk, /branches, and /tags folders. It has a simple console app that displays a welcome message. Call me weird, but I’ve never liked the SVN switch command, so I just setup a local directory structure similar to the repository’s:

Local folder structure

We’ll start by creating a branch for our new feature. Right-click your checked out trunk folder, then select TortoiseSVN, then Branch/Tag. In the To URL field, we’ll enter a path in the branches folder in the repository, usually named after the feature we’re working on. In this case we’ll create a branch in branches/AddUserInput (we’re adding a Console.ReadLine() in this feature - exciting, huh?):

Creating feature branch

Now you can checkout that new branch in your local branches folder and start working on the feature, committing as often as you’d like knowing you’re not affecting anyone else. When you’re all done and everything is committed to it, we’ll merge it back into the local copy of your trunk. Go to where you have the trunk checked out, right-click and select TortoiseSVN, then Merge. Of the three options you’re presented with, select the second, Reintegrate a branch:

Integrating branch

We’re merging from our branch, so enter its repository URL in the From URL and hit next:

Integrate branch #2

Hit Merge on the final screen (or use the Test Merge button to do a dry-run that won’t affect anything). Remember, at this point all changes made from your branch, and applied to the trunk, are only local. Now open the updated trunk, run all your unit tests and whatnot, then commit these changes to the repository:

Commit merged branch

Congrats! Your first feature branch is finished and merged back into the trunk, hopefully with no problems. One major caveat of this procedure is you must not use your branch again after it’s merged back into the trunk. Why? Well, Subversion keeps some properties set on all your files/folders so it knows what revisions have been merged back into them, and continuing to work on your now stale branch and trying to merge it back into the trunk again at a latter point would be bad ju-ju. To make sure nobody accidentally uses your branch, be sure to “delete” it from your repository (don’t worry, the history is still available, just not readily available). To delete the branch, right-click on your checked out trunk folder, select TortoiseSVN, then Repo-browser. Navigate to your branches folder in the left pane, then right-click and delete your old branch:

Deleting old branch

A bit more complicated scenario

So you created your branch and you’re happily committing away when you see someone else committed to the trunk. Uh oh. Fortunately, it’s really not a big deal. We’ll just merge the new revisions from the trunk into our branch every now and then to keep it “current” with the trunk. Then when you’re done with your branch and go to merge it back into the trunk, it should theoretically merge without problems, as it’s the same as the trunk except for the changes you’ve made.

To show this, we’ll create a new branch to add a prime number calculator to our app. Same steps as above. After we’re working on the branch, though, we’ll commit a change to the trunk to simulate it being a co-worker’s change (it can be anything, even a conflicting change if you want). Now it’s time to update you branch!

First, check-in any changes you’ve made on the branch (this allows you to roll back the coming updates if they blow up, among other things). Then right-click on your checked out branch folder and select TortoiseSVN, then Merge. Choose the first option this time, Merge a range of revisions:

Updating branch

Make sure the trunk is specified in the URL to merge from field on the next screen. Leave the Revision range to merge field blank, as Subversion tracks which revisions it already merged in automatically and won’t try to re-merge them (which is new in version 1.6 - for older versions you’ll have to track this and specify revision ranges by hand, and trust me, it gets messy real quick):

Updating branch #2

If you hit the Show Log button on this screen, it should show revisions that have already been merged in gray:

Showing merged revisions

As a quick side note, when everything is done, you can do a diff on the files and see how Subversion tracks previously merged revisions on each file & folder:

Diff on updated file

After hitting next, you can hit either Merge or Test Merge (just like before), and make sure everything gets updated. Deal with any file or tree conflicts here, and run all your unit tests to make sure these new changes are still hunky-dory with your stuff. Then simply commit these new updates to your branch:

Committing updated branch

Keep up on these trunk updates while you’re working on your feature, and when you’re done and it’s time to merge back into the trunk, you shouldn’t have any (or at least not many!) issues or conflicts with it.

Monitoring the trunk

How can you know when changes are made to the trunk? Well, you can have everyone yell out when they commit to the trunk if you work close enough, you can email everyone, or you can get a tool to monitor the repository for you, such as SVN-Monitor which is quite awesome and totally free.

I set this up to monitor our trunk so I know when changes are made, with both a nice pop-up balloon and an email. Here’s a view of this sample’s trunk:

SVN-Monitor

Complex scenarios

You’re bound to run into issues now and again with this workflow, especially on larger teams, having a more complicated branching setup, or if you’re doing a lot of file shuffling in the trunk or your branch (as its been my experience that, in general, SVN doesn’t deal well with file moves/renames beyond the simple cases). I’m also working on a 3 person team, so I can’t speak as to how well this scales up to a 15 person team size.

I’m not pretending to cover every scenario or issue you’ll run into in this post, either, so accept that fact that you might, and probably will, have to either Google around for an answer to some weird error and drop down to the command line to fix something. You might as well know that going in.

Issues?

The biggest issue I have with this workflow so far is the time taken to create a new branch, mostly comprised of the time spent checking-out and updating R#:

  • Check-out time: as I mentioned, I don’t like the switch command (though it would probably solve this issue). We’re work on a large, and rapidly expanding, code base with over two dozen dependencies and lots of code files. It simply takes a while to check out a new branch (ok, in reality it’s only a few minutes, but still annoying).
  • Updating R#: I love the solution wide analysis R# offers, but it takes a while to scan everything when you open a newly created & checked out branch. This is on a quad-core machine with 15k RPM drives, too.

These issues, while not show stoppers by any means, are still annoying to me none-the-less, and I thought I’d mention it.

Wrapping up

So there you go. Common usage scenarios when using a branch-per-feature workflow with Subversion. Not too complicated. As I noted in the begining, we’ve been doing this for a short while now and it’s working quite nice, as before we’d just make one branch for each iteration, all work in that, and merge with the trunk when done. That meant if one of us was making breaking changes, we’d simply not commit until we were all done. That’s pretty risky. What happens if our machine crashes after 4 days of work, or we wanted a file back from a few days ago? Not cool.

It’s worth noting that, from what I understand, Git’s workflow follows this pattern by default. I’m planning to dive into that soon.

If I messed anything up in here, or you know a better way of doing it, please let me know!

Nov 1
2009 Goals - October Update
icon1 Darrell Mozingo | icon2 Goals | icon4 November 1st, 2009| icon3No Comments »

How am I doing on my goals for the year? Let’s see (comments in italics after each goal):

Books

  1. Code Complete - Steve McConnell (yep, I’ve never actually read it)    No progress.
  2. Patterns of Enterprise Application Architecture - Martin Fowler    Started.
  3. Domain Driven Design - Erick Evans    Done.
  4. Working Effectively With Legacy Code - Robert Martin    No progress.

Tools/Techniques/Processes @ Work

  • NHibernate and all its trimmings (FluentNHibernate, LINQ to NHibernate, etc), which I’ll need on a project here real soon.  Done, but still picking up stuff.
  • Actually move from CC.NET to Team City (last attempt didn’t go so well).  No progress.
  • Build a more robust build script and management process - including production deployment scenarios.   No progress.
  • Messaging framework, either MassTransit, NServiceBus, or Ayende’s new Rhino Service Bus if he’s able to release it in time for our current project.  We mentioned needing one a few times in discussing potential solutions to a few problems we’re having.

Involvement

  • We have weekly meetings to catch everyone up on what we’re doing, but I want to present on an actual topic during at least 2 of these - and present in a way where the other development teams will see the use in picking up the presented tool/technique.    Meetings still halted - no progress.
  • Have at least one meeting of the CantonALT.NET group and see if it can ever get up on its feet.   No progress, and more than likely dead in the water :(
  • The two blog posts per month target John put out there seems doable, so I’ll borrow it :)    Slipping a bit, mostly due to lack of things to talk about for a while. I have a few interesting (at least to me) posts in the works though.
  • At least 3 feature/patch submissions to open source projects.  No further progress past the last update.

Productivity

  • Trim RSS feed size by 1/3 (presently at 127, so trim it to at least 85) and cut time viewing it by half. I’ve gotten much better this past year at cutting through the useless stuff, but there’s still a lot there and it sucks up too much of my time.  Down to 85! Lets see if I can keep it around that area. I’m trying to delete a feed if there’s one I want to add.

Not looking like I’ll be finishing everything before the year’s up.

I’ll update again in the beginning of January.

Oct 23
Ideas
icon1 Darrell Mozingo | icon2 Misc. | icon4 October 23rd, 2009| icon3No Comments »

My recent lack of posts aren’t so much because I don’t have the time or desire to do them, I just don’t have any ideas left to post about. Nothing terribly exciting going on at work and no time for development stuff at home. I tried getting my company to open source an old ASP.NET page I wrote (actually, my first “professional” one) that was quite successful but has since been replaced for a new direction, but they unfortunately turned it down. I was hoping to walk through it step by step in a huge refactoring series of posts, adding tests, getting rid of the huge amounts of inline SQL, etc. Maybe I’ll work on getting them to do that again.

In the mean time it’s back to the drawing board for post ideas. I prefer series and actual code/concrete posts, so maybe a small app? That seems over done though, not to mention the odds of me actually seeing it the whole way through are pretty slim. Hmmmmmm.

Sep 15
Injecting all instances of a given type
icon1 Darrell Mozingo | icon2 Misc. | icon4 September 15th, 2009| icon33 Comments »

I’m sure I’m a little late to the game here, but I recently stumbled across how to do collection injection with Structure Map. I’ve known it was possible, and have seen it hinted at in other blogs posts for a while, but I just didn’t know how exactly it was done.

Why would you want to do this? Lets take an actual situation from our system. We rolled a small scheduled task framework (sorry Quartz.NET and Topshelf, you just didn’t fit the bill for our needs). I wanted us to just drop a POCO object in the project and implement an ITask interface, which had exactly one method: Run(). I also wanted these objects to be pulled from the container so they could have services/repositories injected in as needed.

To make it easy for our network admins to schedule these tasks, I wrote the application to take a single /run <taskName> parameter. So if you wanted to run the EmailUsersTask, you’d simply run the app with /run EmailUsers. I also added a TaskDescription attribute so task authors could add a single sentence letting everyone know what it did, which would be displayed when the user ran the app with no parameters in a list with all the available tasks and a description of each.

Simple enough, right?

My first stab at it, and it actually ran for a while like this, took in Structure Map’s IContainer to retrieve the task with all its dependencies satisfied, and to display all the available tasks it would just loop through all types in the assembly (filtered for only those implementing ITask), and get the needed display information.

Worked fine and dandy, but testing it was slow. I had to scan all the types in the assembly, even if I knew I was looking for a single test dummy class. I didn’t like it, so I began tinkering with Structure Map. I wanted the fully initialized objects (from the container) injected in as an IEnumerable<ITask>, so I could just pluck the needed one to run, and loop through that list to build up the small display when needed. It would be easier to read and also make testing quicker and simpler. Here’s what I ended up with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void BootstrapStructureMap()
{
	ObjectFactory.Initialize(y =>
	                         {
	                         	y.Scan(x =>
	                         	       {
	                         	       	x.TheCallingAssembly();
						x.WithDefaultConventions();
						x.AddAllTypesOf<ITask>();
	                         	       });
 
					y.ForRequestedType<IEnumerable<ITask>>()
	                         		.TheDefault.Is.ConstructedBy(x => ObjectFactory.GetAllInstances<ITask>());
	                         });
}

This is called while our app is boot strapping (though we use separate Registries for each area of the app, I just simplified it for posting). Pretty self explanatory - the AddAllTypesOf tells Structure Map to gather up all implementors of ITask in the assembly, and we then tell Structure Map to get all instances of that interface to pass it in whenever IEnumerable<ITask> is requested. Without that, you’d have to take in an array of ITask's. Same difference, I just prefer enumerables.

So there you go - get a collection of fully constructed types injected into your objects. We did this assembly type looping in one or two other system startup areas of the app, and I was able to kill them all off with this technique while shaving a good 4 seconds off our unit test suite. Pretty neato.

As a moral, of sorts, for this story, I also learned after doing all this to always RTFM when you have a question. It’ll save you a lot of time tinkering on your own :)

Sep 1
2009 Goals - September Update
icon1 Darrell Mozingo | icon2 Goals | icon4 September 1st, 2009| icon31 Comment »

Three quarters of the way through 2009. How am I doing on my goals for the year? Let’s see (comments in italics after each goal):

Books

  1. Code Complete - Steve McConnell (yep, I’ve never actually read it)    No progress.
  2. Patterns of Enterprise Application Architecture - Martin Fowler    Ready to start here soon.
  3. Domain Driven Design - Erick Evans    Done.
  4. Working Effectively With Legacy Code - Robert Martin    I think we’re getting close to needing a messaging framework, but I’m not quite ready to introduce the knowledge overhead for the team yet.

Tools/Techniques/Processes @ Work

  • NHibernate and all its trimmings (FluentNHibernate, LINQ to NHibernate, etc), which I’ll need on a project here real soon.  Done, but still picking up stuff.
  • Actually move from CC.NET to Team City (last attempt didn’t go so well).  No progress.
  • Build a more robust build script and management process - including production deployment scenarios.   No progress.
  • Messaging framework, either MassTransit, NServiceBus, or Ayende’s new Rhino Service Bus if he’s able to release it in time for our current project.  No progress as we haven’t needed any yet.

Involvement

  • We have weekly meetings to catch everyone up on what we’re doing, but I want to present on an actual topic during at least 2 of these - and present in a way where the other development teams will see the use in picking up the presented tool/technique.    Our meetings are still halted, but I’m hoping to do an intro IoC/DI presentation if they ever start again.
  • Have at least one meeting of the CantonALT.NET group and see if it can ever get up on its feet.   No progress, but we’ve had quite a few more Code & Coffee get togethers, and we’re talking about getting a meeting together that’s not quite as tied to ALT.NET (some of the guys used to run them back in the early oughts).
  • The two blog posts per month target John put out there seems doable, so I’ll borrow it :)    Still on target, thought I’m starting to run out of post ideas. Might need to think up another series on something.
  • At least 3 feature/patch submissions to open source projects.  No further progress past the last update.

Productivity

  • Trim RSS feed size by 1/3 (presently at 127, so trim it to at least 85) and cut time viewing it by half. I’ve gotten much better this past year at cutting through the useless stuff, but there’s still a lot there and it sucks up too much of my time.  Down to 89. Went on a feed cutting spree a few weeks back, mostly dead ones and others that have wondered into other topics that don’t interest me as much.

I’ll just point to the reading again. No more excuses - I just can’t read technical books for long periods of time, especially dense ones, which are oddly the ones I want to read.

I’ll update again in the beginning of November.

Aug 31
Auditing with NHibernate Listeners
icon1 Darrell Mozingo | icon2 NHibernate | icon4 August 31st, 2009| icon314 Comments »

We recently had a requirement to do auditing in our application, complete with storing the old and new values. Previous applications had used a method that took all that information in an wrote it to the database, giving us a lot of control of what we logged and when, but it required us to call it in every needed situation or we’d lose the capability, not to mention it made reading the code horrid.

Thankfully, we’re using NHibernate for this application. I’d read here and there over the past year about how simple auditing was with NHibernate and I’d bookmarked them, knowing this requirement was working its way down the pipeline. Unfortunately, pretty much every example I could find out there was simple using simple created time stamp, modified time stamp, and user making the update fields. For our application we needed to track the old and new values in addition to these fields, along with a few other requirements that are pretty specific to our application (so I’ll leave them out here).

We’ll store these audit entries in a separate table with a primary key reference back to the entity they modified. Let’s start by defining a domain object to represent a single audit entry:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class AuditLogEntry
{
	public virtual int Id { get; set; }
	public virtual string Username { get; set; }
	public virtual string AuditEntryType { get; set; }
	public virtual string EntityFullName { get; set; }
	public virtual string EntityShortName { get; set; }
	public virtual int EntityId { get; set; }
	public virtual string FieldName { get; set; }
	public virtual string OldValue { get; set; }
	public virtual string NewValue { get; set; }
	public virtual DateTime Timestamp { get; set; }
}

Pretty self explanatory - it’ll store details related to the update, including what field was updated, the object full/short name, id of the entity, the old/new values, username that made the update, and a time stamp.

We’ll also need a simple entity to use as our test subject:

1
2
3
4
5
6
public class Employee
{
	public virtual int Id { get; set; }
	public virtual string Name { get; set; }
	public virtual int Age { get; set; }
}

Again, nothing fancy (though note this will scale up - we’re using fairly complex objects in our domain, and while the auditing code I’ll post here isn’t the exact same, it’s not too far off, and we haven’t had a problem yet). I’ll stick with Fluent NHibernate’s auto mapping to produce the basic mappings we’ll need. There’s nothing special required there.

Now for the actual auditing code. We’ll use the newer Listener (Pre/Post Update/Insert/Delete/etc) interfaces, which replaced the generic IInterceptor. Basically, each seperate entity that’s saved will get passed into our class, allowing us to do whatever we need with it. We’ll be collecting auditing data:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class AuditUpdateListener : IPostUpdateEventListener
{
	private const string _noValueString = "*No Value*";
 
	private static string getStringValueFromStateArray(object[] stateArray, int position)
	{
		var value = stateArray[position];
 
		return value == null || value.ToString() == string.Empty
		       	? _noValueString
		       	: value.ToString();
	}
 
	public void OnPostUpdate(PostUpdateEvent @event)
	{
		if (@event.Entity is AuditLogEntry)
		{
			return;
		}
 
		var entityFullName = @event.Entity.GetType().FullName;
 
		if (@event.OldState == null)
		{
			throw new ArgumentNullException("No old state available for entity type '" + entityFullName +
			                                "'. Make sure you're loading it into Session before modifying and saving it.");
		}
 
		var dirtyFieldIndexes = @event.Persister.FindDirty(@event.State, @event.OldState, @event.Entity, @event.Session);
 
		var session = @event.Session.GetSession(EntityMode.Poco);
 
		foreach (var dirtyFieldIndex in dirtyFieldIndexes)
		{
			var oldValue = getStringValueFromStateArray(@event.OldState, dirtyFieldIndex);
			var newValue = getStringValueFromStateArray(@event.State, dirtyFieldIndex);
 
			if (oldValue == newValue)
			{
				continue;
			}
 
			session.Save(new AuditLogEntry
			             	{
			             		EntityShortName = @event.Entity.GetType().Name,
			             		FieldName = @event.Persister.PropertyNames[dirtyFieldIndex],
			             		EntityFullName = entityFullName,
			             		OldValue = oldValue,
			             		NewValue = newValue,
			             		Username = Environment.UserName,
			             		EntityId = (int)@event.Id,
			             		AuditEntryType = "Update",
			             		Timestamp = DateTime.Now
			             	});
		}
 
		session.Flush();
	}
}

First we inherit from IPostUpdateEventListener, which has a single OnPostUpdate method defined. We check to make sure we’re not auditing another audit entity (infinite loop, anyone?), then make sure we have the old values available, throwing if we don’t. For this system to work/be effective, you must load the entity into session, modify it, then save. In a few places, we had everything we already needed from the form (we’re working in a web environment), so we’d just set all the properties, including the entity’s id. The problem there is NHibernate’s session has no idea what the old values are, so we’ve now made it a policy to always load the entity before saving it.

On line 29, we’re delegating to NHibernate to tell us which properties in the entity are dirty, or have changed. We then loop through those properties, collect the needed values for our AuditLogEntry entity, and save it off.

As I’ve mentioned, this works just fine for most applications. The first issue we ran into was Components (in the NHibernate sense). They’re represented as a single property changed on the entity, so all you get is the ToString on the object. Fortunately there’s an easy way to see if the property is a Component (hint: @event.Persister.PropertyTypes[dirtyFieldIndex] is ComponentType before line 43), so we use reflection to loop through the properties by hand and compare them for dirtiness.

There you go, damn near complete old & new value auditing, just like mom would have always wanted. Not perfect, I’m sure, but we’ve been using a modified version of this for a while and haven’t had any problems.

In the working example, available here, I run through an edit and display the audit results in a console app using Sqlite. Give it a try, and let me know if you find this helpful at all.

« Previous Entries Next Entries »