Over the next several months I will be presenting a walkthrough of StructureMap. I will be starting with the basics of how to construct objects using StructureMap and then move on to more advanced topics.
I know there is lots of great information out there around how to use StructureMap. My intention for writing this series is mostly selfish. I want to learn StructureMap, and as I learn it I’ll be blogging the features I’m learning as I go.
I’m currently working on a project that uses the Unity dependency injection container. This container has worked very well for us, but as I’ve read various blogs and articles I’ve come to realize that a good DI container provides more than just DI. It’s my intention to learn the basic usage of StructureMap, but also dig into the more advanced usages as well as much of it’s support infrastructure that helps you keep your dependency injection code to a minimum (thinking of auto-wiring, convention-based registration, etc).
I’ll also be updating this post as I write each new article so that this post can remain as a table of contents for the whole series.
- Manual component registration and resolution
- Auto-wiring components
- Convention-based registration
- Component lifetime management
Today our project’s continuous integration build failed. I traced it down to a unit test that was exercising a scheduling class. The class takes a schedule and figures out the next time it should run based on the current date.
Now in our project we’ve provided a way to stub the current date or current time by having a SystemClock class that has a static Instance property. If we need to we can push a stubbed instance into that property in a unit test to control what the current date/time is.
The problem in the unit test was that it was relying on DateTime.Now and then figuring out what the expected next scheduled time should be right in the unit test. The calculations were wrong in the unit test and caused the unit test to fail.
Almost every time I see calculations in unit tests to figure out what the expected value should be (especially date-based calculations) I cringe because I see those as unit tests waiting to fail. If you’ve copied your calculations from the class under test, who says you got the calculations right in the production class? If you did the calculations differently, your unit test’s calculations could be wrong. Wherever possible I prefer to keep the moving parts to a minimum and have constant dates as my expected values in date-based unit tests.
>One of the other developers on the team I’m on pointed out a very handy feature in R# yesterday. It is the “Generate Members” feature and can be accessed using Ctrl+Ins. This handy tool is like a central point to accessing the generation features in R#. The nice thing is that the generated members are placed at the current location and you can generate as many members as you like in one shot. This makes doing things like wrapping a bunch of private fields really easy. So, the next time you are using Alt+Enter (Quick Fix) to generate some code using R#, consider using Alt+Ins and see what it can do.
I tend to use the Go To Type shortcut in R# alot (ctrl+N for you keyboard junkies). It was only recently that I found out that you can use simple wildcards when using the shortcut.
In the above screenshot you can see that I’m looking for all classes that start with “Pet” and end with “View”. I don’t use this feature every time I want to jump to a type, but often I can’t remember the exact name of a class but I’ll know pieces of the name and this helps in those cases (it’s especially helpful when I just know how the class name ends, eg. “*Presenter”).
>This is mostly for my own sake, but here’s a link to the list of targets that are run during a Team Build on TFS 2008. Customizable Team Foundation Build Targets
I’ve been using Team System for a number of years, and one thing that was frustrating was that the Pending Changes window showed all files in the current workspace. This becomes unmanageable when you have several projects sharing a workspace (whether that’s “best practice” is irrelevant).
Today I happened upon the option that I’ve been thinking should exist but could never find: Filter by Solution.
One thing that I feel is very important when building APIs is consistency in how method parameters are ordered. Abrams and Cwalina’s Framework Design Guidelines talks about this as well.
I came across one instance of inconsistency that is a good example, I think. We’re using MSTest for unit testing on our current project and so we make extensive use of it’s "Assert" class. For most of the assertions that do a comparison between and expected and actual object, you pass the expected object first. For example:
Assert.AreEqual(Of T)(expected as T, actual as T)
Assert.AreSame(expected as Object, actual as Object)
And now we come to the exception.
Assert.IsInstanceOfType(value as Object, expectedType as System.Type)
When using the assertion for IsInstanceOfType, suddenly it takes the actual object in the first position. This becomes annoying because now I have to remember if I put the actual or expected object first every time I use an assertion method.
Additionally, they’ve also named the expected object parameter “value” instead of “expected”.
So, when building APIs even if you are not planning on publishing them for devs outside of your project, remember to be consistent with parameter ordering and naming. It helps with discovery and adoption of the API.