Unhandled Exceptions

05 Feb

Philly Alt.NET “Practical DDD in .NET” Presentation: That’s a Wrap!

Last evening (Thursday) I had the pleasure of being asked to speak at the monthly meeting of the Philadelphia Alt.NET User Group.  As mentioned previously in this post here, I delivered my “Pragmatic Implementation Patterns for Domain Driven Design in .NET” presentation to an enthusiastic audience of about 40-50.

A big thanks to everyone who took time out of their busy schedule and other obligations to attend the meeting!  The attendees were engaged, interested, and provided really great questions and feedback, both in Q+A during the presentation as well as in conversations afterward.  As a presenter, there’s really nothing more satisfying than to give a talk to a room full of people genuinely interested in the information you have to share and to an audience willing to engage with the topic.

Thanks to Penn State Great Valley School of Professional Studies

image

A big thanks goes out to the Penn State Great Valley School of Professional Studies for providing a truly excellent facility for the meeting.  As you can see from the photo at left, we were given a classroom-style room complete with A/V facilities and lots of comfortable seating for the attendees (some of which appear in the photo).  Located in Malvern, PA just slightly north and west of Center City Philadelphia, this location was a little easier for me to get to from the greater NYC area at the end of the business day than downtown Philly would have been.

A special thanks goes out to Sharon Kauffman, Program Manager for the Continuing Professional Education program.  She and her staff and faculty went well out of their way to ensure that the needs of the group and myself were entirely attended to both before and after the meeting.  Her team is really to be commended for their professionalism and great courtesy in welcoming both myself and the Philly Alt.NET group into their campus.

In fact, the experience has me wondering if the NYC Alt.NET Group shouldn’t also try to reach out to other Continuing Education programs in the NYC area to see if similar kinds of spaces might be available for our own meetings!

(Surprise) Bonus: VB.NET Continuing Education Students in the House

As an entirely unexpected bonus, a class of about 15 students from a VB.NET Continuing Education class was able to sit in on my presentation for the first hour or so.  Even though all of my code samples were in C# and my topic was clearly a pretty advanced one for a class of students without extensive career experience as OO software developers, I hope I did at least a passable job of trying to explain the high-order concepts at play in such a way that the content was still valuable to them.

When you’re delivering a presentation (as a speaker, teacher, or whatever) and there are two pretty disparate groups in attendance, it can often be hard to split-the-difference in a way that doesn’t leave one group bored to tears and another group feeling like they’ve just been dropped in the deep end of the ocean.  I hope I managed to do a decent job of delivery of the material there!

Hitting the Target?

Since only about 20% of the attendees were already familiar with many of the concepts underlying Domain-Driven Design (DDD), in addition to talking about implementation patterns I also spent significant time digging more deeply into the high-level concepts and principles of DDD than I’d originally intended.  Since I hadn’t prepared for that, those elements of my talk had to be more off-the-cuff than rehearsed.

Any time you as a teacher find yourself speaking more extemporaneously like that there’s a huge danger you run that you’re not structuring your delivery in a coherent manner so as to enable the attendees to follow your train of thought properly.  In such cases, you can often find yourself delivering a stream of data devoid of proper context and that certainly tends to inhibit effective learning on the part of your audience.

Earlier today, however, I received an e-mail from an attendee from which I wanted to share an excerpt:

I did not get a chance to tell you how much I got out of [the presentation]. Your presentation was great and it really helped me understand DDD. It also helped me demystify a lot of the concepts. I realized that even if you do not practice pure DDD the overall concept of designing according to the domain’s own internal language is a powerful idea and one that can be used in most OO projects.

This kind of response is indeed heartening for a teacher to receive – its validation that for at least one attendee, the truly important parts of the content got through as intended!  Several others that approached me in person after the meeting had similar positive feedback to share, so hopefully this means that attendees were able to glean value out of the content.

Presentation and Sample Code

For those interested in a copy of the presentation content, here are links to direct downloads of the materials:

As always with my content, please feel free to do whatever you want with it as you see fit but as a matter of simple professional courtesy I would request simply that if you plan to re-use the content to deliver a presentation of your own that you at least mention that my work formed at least some of your inspiration :)

Proteus Domain Foundation Project on Google Code

Those in attendance saw much of the sample code I showed make use of a set of DDD-centric helper classes that made implementation of some of the patterns much more straightforward.  The binary of the assembly that contains these libraries is included in the code download of course, but for those interested in seeing the source code for this assembly I wanted to just mention that its all part of a project of mine that is available as open source and is hosted on Google Code as the Proteus Project.

As mentioned in the presentation, in addition to base classes that make it trivial to implement things like Entities and Value Objects in .NET by simply deriving from specific base-classes, this library also contains classes and interfaces to facilitate implementations of the Specification Pattern leveraging all kinds of boolean logic such as ANDs, ORs and the like.

Since this is open source, you can feel free download it, change it as you want to suit your needs, or just take a look at it to better understand how it all works.

Happy coding, everyone~!

30 Jan

NDbUnit v1.6 (and Proteus Unit Test libraries) with Oracle Support Released!

Thanks to a code contribution from an adopter of NDbUnit, I’m happy to announce that NDbUnit v1.6 is now released and available for download from the Google Code downloads page with support for Oracle 8i and later.

Oracle support has been on the project’s roadmap for some time now and its great to be able to introduce this support at long-last (and even more enjoyable to be able to jump-start this functionality with a contribution from an adopter of the project).

I’m happy to say that this now brings the complete list of supported DB targets under NDbUnit to six:

  • Microsoft SQL Server (including Express Editions and on up to Enterprise)
  • Microsoft OleDb-supported databases*
  • Microsoft SqlServerCe/Mobile Edition/whatever its called this month
  • MySql
  • Oracle (including XE and on up to Enterprise)
  • SqlLite (including both on-disk and in-memory variants)

*there is currently a known issue with OleDb support that is under review

FWIW, I’d still love to get support for PostGreSql in there too at some point (hint –hint, community!)

Proteus Unit Test Libraries update Released as well!

Now that NDbUnit properly supports Oracle, its possible to extend the Proteus Project’s Unit testing libraries to do the same and so I’m also happy to announce that the 1.2.6 release of the Proteus.UnitTest.dll library is also now available for download from its own Google Code downloads page.  The Proteus utility classes that wrap NDbUnit with a series of convenience methods now also support Oracle as a database target.

Happy coding~!

27 Jan

I’ll be speaking at Philly ALT.NET on Domain Driven Design

Next Thursday evening (2/4/2010) from 6:00pm-9:00pm I’ll be speaking at the Philadelphia Alt.NET user group on real-world Domain Driven Design implementation patterns in .NET.

The full title of the session is going to be “Lessons from the Trenches: Pragmatic Implementation Patterns for DDD in .NET” and the overview synopsis will be:

In this session, we’ll take a look at common implementation patterns for Domain Driven Design concepts in .NET.  Focusing less on Powerpoint and more on code samples and discussion, we’ll dig into exploring implementation patterns for Entities, Value Objects, Services, Factories, Repositories, and other DDD constructs as well as patterns for wiring them up to collaborate between each other in a larger application.  We’ll also discuss people’s real-world implementation experiences and investigate common pain-points in applying DDD to the software development process.

For details and to RSVP if you want to attend, visit this link.  I’m looking forward to a thorough interactive discussion session where we can dig into attendees’ real-world experiences with DDD and get at the heart of what it means to use a DDD approach to engineering your software solutions!

To my knowledge these meetings aren’t recorded but I hope to see everyone there (if you’re in the area and can make it!)

26 Jan

My Interview on the Connected Show podcast is Released!

Episode 23 of the Connected Show podcast has been released!  In this episode, host Peter Laudati interviews Andrew Brust about what he saw at this year’s CES in Las Vegas and then proceeds to interview none other than yours-truly about some of the work that myself and others have been doing with the Agile Firestarter events in and around the NYC metro area.

Agile: Putting the “Soft” in Software

In the interview Peter and I talk at length about the principles, values, and practices that underpin the Agile approach to software development, discuss why you as a developer should care about Agile, debate flawed metaphors comparing software engineering with the construction industry, investigate technical practices that make Agile successful, and even dig a bit into my thoughts about the challenges facing software engineering as a profession for the future.

Although it probably runs a bit longer than most Connected Show episodes, hopefully I found valuable things to say to fill the time :)

You can download the podcast directly from right here and the show notes can be found on Peter’s blog here.

As usual, all feedback/commentary on anything I do is welcome.  Happy listening~!

20 Jan

ALT.NET: Looks Like its Introspection Time Again!

Its time for the semi-annual “What is ALT.NET and what does it mean to me?” introspection merry-go-round.

I’ve said it before and I will say it again: introspection is a healthy form of self-review and an expression of self-awareness for both people and organizations/movements/shared-value-systems/whatever ALT.NET might be.  The last time this theme surfaced (to my knowledge) was back in March of 2009 and I blogged about my thoughts at that time in this post.

Since then, my thoughts on the subject haven’t changed much; I still feel that ALT.NET exists as an effective rallying-point for a shared set of values, ideas, and approaches to software engineering in the .NET ecosystem that’s every bit as important now as it was before.  Whether we like the name or don’t, accept the history (good and bad) of the ‘movement’ or attempt to reject it, consider it a success or a failure, for better or worse its still a name and concept that I experience all the time has traction as an identifier both for those that consider themselves part of it and those that do not.

Twitter –> Blogs –> Twitter

This particular round of introspection started on Twitter and then spilled over into the blog-o-sphere where various people offered their thoughts and opinions in long-form since 140 characters just didn’t seem to cut it for them.  Comments about the comments about the blog posts then continued on Twitter for some time afterward (yes, that sounds silly to me too FWIW :) )

As a point of reference, here are some links to some of those posts for the interested reader:

  • Ian Cooper wonders at length about the meaning of ALT.NET (and its purpose, goals, and possible future (ir)relevance) in a post entitled “Whither ALT.NET?”.
  • Sergio Pereira attempts to categorize the different broad types of people and their interaction styles with ALT.NET in a post entitled “On ALT.NET and Patience” that is somewhat reminiscent of what I was getting at in my post last March in that it tries to acknowledge that there are both many different kinds of people who interact with ALT.NET and thus many different experiences these people have in their interactions.
  • Derrick Bailey contributed a post, “Active vs. Activist”, to the discussion where he attempts to explore the eternal tension between the idealism of the revolutionary zeal and the pragmatism of effective leadership by comparing the canonical definitions of “Activists” rage against the machine with those that are merely “Active” in a movement.

Read the Comments!

I would encourage everyone interested to please read not only the blogs themselves but also the comments posted to them.  Whether you are ‘for’ or ‘against’ ALT.NET, care about its future or not, both the posts and the comments are useful as a measurement-in-time in the life (or death) of an idea and are probably worth your time to read for that reason alone.

18 Jan

Wanted: Virtual Alt.Net Community Contributors, Organizers, and Presenters

image This is a public call for greater community participation in the Virtual Alt.Net online community for 2010 and beyond.

What is Virtual Alt.Net?

Virtual Alt.Net is an online community that met weekly over the past year or so utilizing Live Meeting as a platform for exposing as many people as possible to software development concepts and ideas that many consider to be related to the Alt.Net community.  Virtual Alt.Net was spearheaded by Zack Young who accepted primary responsibility (along with several other people assisting him) for ensuring that speakers were invited, announcements of upcoming meetings distributed to as many people as possible, a web site for the effort was created, and a calendar of upcoming talks maintained.  Essentially, this entailed all the effort that would normally be related to maintaining a real-world user group, but didn’t include the need to secure a facility for the meetings, order food and beverage, and ensure attendees have access to the building.

As a member of the organizing team for the NYC Alt.Net user group that meets monthly, I can easily appreciate the amount of effort required to organize a weekly meeting.  Even without the requirement of securing space and refreshment, coordinating speakers on a weekly basis is a significant effort and Zack and his team are to be commended for assembling interesting topics on a weekly basis throughout the year.

What makes a healthy user group community?

The backbone of a healthy user group requires just one thing: community participation.  Forming a user group may be the act of a few individuals, but its continued health depends on the participation of the community at large.  The NYC Alt.Net user group was founded in late summer 2008 by small group of 4 to 5 individuals who formed the initial organizing team.  Today, about 18 months later, the organizing team is still 4 to 5 individuals.  But only three of the original organizers remain.  One of our original team had to bow out due to health reasons.  Another took a nine month assignment overseas in the Far East, and still another took a gig that required him to be out of town Monday through Friday every week for the past six months.  In the interim, others have stepped up to fill the gaps and help organize the group on a monthly basis.

I don’t think it’s an exaggeration at all to say that keeping this user group alive for the past 18 months would have been a lot harder for the original team had others in the membership not stepped up and offered to assist in the monthly organizing tasks.  Now, Virtual Alt.Net is in need of the same kind of increased membership participation in order to help ensure its future viability as well.

Wanted: Virtual Alt.Net Organizers

Virtual Alt.Net is looking for individuals that are willing to participate in scheduling the regular Live Meeting sessions, coordinating speakers, updating calendars, and distributing meeting announcements to the virtual community (via blog posts, twitter, email, and discussion forums).  Instead of having a single person spearhead this responsibility for virtual Alt.Net, it’s important for the continued health of the effort that a broader group of people gather together to collectively organize future meetings as a team.  If you would like to participate in this organization process, please add a comment to this blog post or contact me directly via e-mail (sbohlen@gmail.com).

Wanted: Virtual Alt.Net Contributors

If you’d like to help participate but would rather not commit to being a full fledged organizer, there are still a multitude of areas in which the group could benefit from other community contributions.  Since each virtual Alt.Net session is recorded via Live Meeting, each recording needs to be post-processed and posted to the virtual Alt.Net web site to make it available for download.  While this does not entail a significant amount of work, it is definitely an area in which members of the community could help to participate in the group.  If you would like to volunteer some of your time for this task, please add a comment to this blog post or contact me directly via e-mail (sbohlen@gmail.com).

Wanted: Virtual Alt.Net Presenters

Since virtual Alt.Net doesn’t require the use of any facilities to hold meetings, the most significant impediment to its future health is ensuring interesting speakers and topics are scheduled for every meeting.  In the past virtual Alt.Net has welcomed speakers ranging from the reasonably well known (Oren Eini, Jeremy Miller, Scott Bellware, etc.) to the much less well-known (like myself and others!) speaking on topics ranging from NHibernate to StoryTeller to Domain Driven Design to NHProf to SOLID design principles (for a full list of past topics, see their recordings on the Virtual Alt.Net website here).

Are you someone who has recently delivered a technical presentation to another user group (Alt.Net or otherwise)?  Then perhaps you would be willing to repeat the delivery for a virtual Alt.Net session.

Have you recently attended a presentation whose content you think might be of interest to other virtual Alt.Net attendees?  Then perhaps you might recommend to the presenter that they contact virtual Alt.Net an offer to deliver the same presentation in an online session.

Do you know somebody with expertise in a topic that might be of interest to virtual Alt.Net attendees?  Then you might be able to encourage them to contact us an offer to deliver presentation on the subject.

If you or someone you know is interested in getting some experience presenting technical topics to groups of listeners, then virtual Alt.Net can be a perfect place to begin to gain some of that experience.  Because the group is virtual, there is much less stress than presenting to a roomful of people, offering a great forum for new presenters to hone their skills.  The atmosphere is relaxed and informal, and everyone in attendance is there to learn something.

Whether you have a full-blown presentation to provide, a discussion topic for debate and investigation among the attendees, sample code that demonstrates something you feel attendees might find interesting, or just an interesting problem for which you found a clever solution, virtual Alt.Net represents a great opportunity for you to share your insights with the rest of the community.

Virtual Alt.Net Presentations: a Unique Format and Opportunity

One of the most common complaints that I routinely hear from both presenters and attendees at a live events is…

Its so hard to get anything meaningful across in a 1 hour session.  Presentations either have to be rushed in order to squeeze everything into the short time frame, or they have to be so high level as to be largely useless for the attendees.

Because virtual Alt.Net meets weekly, many meetings and topics are able to span multiple successive weekly sessions.  This format can offer a significantly deeper dive into a topic or area of interest, enabling both the presenter and attendees to gain significantly more value from such a format than they would be able to with a single presentation at a live event like the code camp or other.  If you are presenter that frequently laments the short time constraints in most live events and has a desire to be able to dig deeper into a particular topic in order to provide greater value for attendees, then virtual Alt.Net represents the unique opportunity for you to provide this content over a multi week series of presentations where you have the flexibility to dig deeper into your subject matter and provide greater value to attendees.

And if you don’t want to do a presentation as a multi-week deep dive into the content, then a presentation that lasts just a single session would certainly be welcome as well!

Change in Meeting Frequency?

In order to lighten the burden of having to assemble speakers on a weekly basis, beginning in 2010 virtual Alt.Net meetings will run monthly instead of weekly as a rule.  If and when topics arise that make sense to deliver in a series of successive meetings rather than a single session, these meetings will be delivered in a weekly fashion.  This is designed to try to strike an effective balance between the overhead of lining up speakers for weekly events and the desire for successive related sessions to not have too long a delay between meetings.  Single sessions will occur monthly and series of sessions will occur weekly (or at whatever other interval the presenter feels appropriate).

So in short, the success or failure of the future of Virtual Alt.Net is in the hands of the community.  This effort will only be as successful as the contributions of the larger community enable it to be.  If you or someone you know would like to be an organizer, contributor, or presenter for virtual Alt.Net in order to broaden its organizing team, please add a comment to this blog post or contact me directly via e-mail (sbohlen@gmail.com).

I hope to hear from you soon to ensure that the Virtual Alt.Net effort remains healthy!

18 Jan

NJ Agile Firestarter Decmeber 2009 Content Now Available!

image

For those of you who attended the Agile Firestarter in NJ in December of last year (and also anyone who didn’t!), this is just a quick note to let you know that the content for the event’s presentations has been posted for download as mentioned in Peter Laudati’s blog post here.  Not all of the slide decks are yet available for download, but my two presentations (Intro to Agile and Agile Estimation) are there along with Sara Chipps’ TDD talk.

Unlike the inaugural NY Agile Firestarter event we held back in June of 2009, these NJ sessions weren’t recorded, but you can get a good idea of the content from reviewing the slides at your leisure.  Stay tuned to this blog for upcoming announcements of future NYC-based Agile Firestarter events – there are definitely plans in the works for another NYC event (perhaps Spring 2010) if you weren’t able to attend either of the prior events in NYC or NJ.

Happy Coding~!

15 Jan

NYC CodeCamp March 6, 2010: Call For Speakers!

image

The NYC developer community is proud to announce the 4th (sort of annual) Code Camp to be held on Saturday, March 6, 2010, from 8:00 AM until 6:30 PM. It will take place at the Manhattan Microsoft office on 6th Avenue across the street from Radio City Music Hall.

We have our call for speakers open from now until February 5th.

To apply for a speaking slot, first please register as a speaker here: http://tinyurl.com/nycspeaker

Then with the email address you registered with on our speaker page, please add as many abstracts as you like here: http://tinyurl.com/nycsession

Submit on anything you like in the .NET space, there is no central “theme” to our Code Camp except .NET development!

Unfortunately we can’t afford to pay any T&E, but we will stuff you with lots of pizza and soda!

13 Jan

ASPNET MVC Firestarter Videos on Channel 9

As some of you are aware, back in early October 2009 I was asked by Microsoft to participate in delivering a day-long introduction to the ASP.NET MVC Framework.  For more details on the event, see this post.

As a follow-up, I just wanted to let everyone who wasn’t able to attend know that the videos from the day’s sessions have been posted to Channel 9 for online viewing at this link here.  FWIW, the same recordings have also been available here for some time now, but presumably the Channel 9 site will be a more stable / longer-lasting place for them.

I haven’t watched all the recordings myself (why on earth would I want to listen to myself talk?) but I’ve received some feedback that the audio on at least some of these recordings isn’t exactly the highest quality so you may have to strain a bit to make out the content.  Sorry, but I suppose poor quality recordings are better than no recordings at all!

Happy viewing~!

09 Jan

Externalizing Settings for Data-Dependent Unit Tests using Proteus DatabaseUnitTestBase

in a recent request for the Proteus Project, a user asked about defining test-related settings in external .config files to control connection strings settings, the location(s) of support files like the serialized dataset xml data files and the dataset xsd schema files, and possibly other things.  While it might be of value to ‘formalize’ this capability by designing an actual fixed .config file format and adding direct support for it into Proteus, it occurs to me that one of the reasons for this question may be that its not entirely clear to adopters of the framework how it was intended to allow just such extension to its behavior ‘natively’.

This post is intended to try to put some background context around the design concepts that went into the architecting of the unit-test-related parts of the Proteus Project codebase and in the process understand how we can simply extend the behavior of the library to read settings from any arbitrary location.

Digression: Note that there are effectively two halves to the Proteus Project library: the half intended to provide convenience utility methods in support of database-dependent unit testing via the NDbUnit project and the half that provides infrastructure for domain-modeling.  This post is entirely about the half related to unit testing support.

Anatomy of the DatabaseUnitTestBase Class

The core of the database-unit-testing support provided by the Proteus project is the DatabaseUnitTestBase class.

Before everyone jumps all over me for appending the ugly wart ‘Base’ suffix to a class name, this is a convention that I always use when designing abstract classes that are only ever intended to be used as a supertype from which to derive (and of course the abstract keyword helps the compiler ensure that this will be the case!).

We all still use the letter ‘I’ as a prefix for interface declarations, so get over yourselves.  Clearly we still agree as a community that some warts are acceptable!

Fundamentally, there are several underlying design ideas that characterize this class:

  • its declared abstract so that use of it is achieved by deriving your own class from it, either directly or indirectly through as deep an inheritance hierarchy as you might want to suit your test-structure needs
  • it provides reasonable default assumptions for its settings so that if you just derive-and-go (and accept the conventions!) it will ‘just work’ with minimal config tweaking required
  • all of its operations that require access to settings (e.g., things like connection strings, paths to xml/xsd files, etc.) retrieve those settings via public property accessors
  • all of these public property accessors are declared virtual in the base class so that you can override them in any derived class as you see fit

Its this last aspect (overridable virtual properties) that provides us the needed extensibility point for us to extend the behavior of the base class to read its settings from some arbitrary config store of our choice in answer to the issue posted to the Proteus issues list.

Design Strategy for our Extension

In order to support externally-configurable settings for the DatabaseUnitTestBase class, the first thing we need to do is devise a simple set of design ideas for our approach:

  1. We will store everything in the app.config file; Microsoft went to all that trouble to give us this file format and integrate support for editing it in Visual Studio, MSBuild auto-magically copying it to the build output directory and renaming it <assemblyname>.<extension>.config when compiling, etc. so let’s leverage all that work
  2. Since we’re going be storing (among other things) connection strings, we will similarly leverage the app.config file’s native support for named connection strings and store the connection strings we might need there
  3. Named connection strings will be correlated to each of the tests by using the typename of the test fixture class as the ‘name’ of the named connection string
  4. For settings other than the connection strings, settings in the app.config file will be correlated to test fixtures by the simple convention of prefixing them with the typename of the test fixture class

A Sample Config File

Just so that we have an idea of where we are headed, here’s a look at a sample app.config file that supports two different test fixtures in our test project: Fixture1 and Fixture2:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <connectionStrings>
        <add name="Fixture1" connectionString="Data Source=.;Database=testdb;Trusted_Connection=True" />
        <add name="Fixture2" connectionString="Data Source=otherserver;Database=otherdb;Trusted_Connection=True" />
    </connectionStrings>
  <appSettings>
    <add key="Fixture1_TestSchemaFile" value="c:\MyTestData\SomeSchema.xsd" />
    <add key="Fixture1_TestDataFile" value="c:\MyTestData\SomeData.xml" />
    <add key="Fixture2_TestSchemaFile" value="c:\OtherTestData\schema.xsd" />
    <add key="Fixture2_TestDataFile" value="c:\OtherTestData\data.xml" />
  </appSettings>
</configuration>

In this example, for tests in Fixture1 we want to use the following settings:

  • a local server with a database named testdb
  • the xsd schema file (SomeSchema.xsd) and the xml data file (SomeData.xml) are located in c:\MyTestData\

And for tests in Fixture2 we want to use the following different settings:

  • a remote database server named “otherserver” with a database named otherdb
  • the xsd schema file (schema.xsd) and the xml data file (data.xml) are located in c:\OtherTestData\

Implementation: Derive and Override

As mentioned earlier, in order to change the behavior of the DatabaseUnitTestBase class, we need to derive from it and override some or all of its behaviors (as needed).  As you can see from the following screenshot, if you type the override keyword and hit the space bar, Visual Studio is kind enough to show you all of the possible super-class methods you can override in your derived class…

image

As you can see from the above screenshot, nearly every setting is accessible via an overridable property ‘getter’ and nearly every behavior is accessible via an overridable method.

Don’t like the way the base class reads its connection string?  Override the DatabaseConnectionString property getter.  Don’t like what the library is doing in its DatabaseFixtureTearDown method?  Override the DatabaseFixtureTearDown() method and provide your own behavior.  And because overridden class elements in a derived class still have access to the underlying base class’ original methods, its entirely possible to extend and enhance the original behavior rather than completely replace it as in the following snippet:

protected override void DatabaseFixtureTearDown()
{
    //do something special BEFORE the database state is reset
    base.DatabaseFixtureTearDown();
    //do something special AFTER the database state is reset
}

Overriding What We Need, Ignoring What We Don’t

In our specific example, in our derived class we only need to override the property getters for DatabaseConnectionString, TestDataFilename, and TestSchemeFilename so that they read the values we want out of the app.config file rather than simply performing their default out-of-the-box behavior.

Just for the record, the default assumptions of the DatabaseUnitTestBase class that we will be overriding are:

  • that the connection string is stored in the app.config and is named testDatabase
  • that the test data is stored in a file named TestData.xml and is stored in a folder named TestData placed directly under the project root folder in Visual Studio
  • that the dataset schema is stored in a file named Database.xsd and is stored in a folder named TestData placed directly under the project root folder in Visual Studio

In our case, none of these assumptions the DatabaseUnitTestBase class makes is true so we must override its behavior to reflect retrieving the settings from the app.config file based on the different conventions we want from our ‘Design Strategy’ discussed earlier in this post.

Implementing Our Fixture1 Class

So what’s an implementation of this going to look like?  Let’s take a quick look at how simple this actually is…

Get Discriminator

To get started, we can immediately see that we’re going to need a simple convenience method in our class that can get us the name of the test fixture since its effectively the discriminator in our app.config settings.

private string GetSettingsDiscriminator()
{
    return this.GetType().Name;
}

Almost an absurdly simple method, this inspects the current type (which will be the test fixture class) and returns it’s unqualified name (e.g., in the case of Fixture1, this will return the string “Fixture1”).

We bother to write this simple method none-the-less because it helps abstract out how the discriminator is determined so that if at some later point we want to bother to determine it some other way, calling code doesn’t have to concern itself with how the discriminator is actually determined.  A very simple example of this is that it might (later) be worthwhile changing the discriminator to be the entire fully-qualified typename (by returning this.GetType().Fullname instead) so that more than one Fixture1 class could co-exist in the same test assembly (but obviously in different namespaces else they would collide and the compiler would complain!).  For our example, returning the unqualified typename is fine.

Overriding The Connection String

Overriding the retrieval of the connection string is very simple, we just need to use the .NET ConfigurationManager class to retrieve the named connection string based on our discriminator value (our fixture name).  Now that we have our GetSettingsDiscriminator() method defined, this becomes quite simple:

protected override string DatabaseConnectionString
{
    get
    {
        return ConfigurationManager.ConnectionStrings[GetSettingsDiscriminator()].ConnectionString;
    }
}

Overriding the Schema File

Following a similar pattern, all we need to do to enable our desired retrieval of the Schema File on a fixture-specific basis is override the TestSchemaFilename property getter as in…

protected override string TestSchemaFilename
{
    get
    {
        return ConfigurationManager.AppSettings[GetSettingsDiscriminator() + "_TestSchemaFile"];
    }
}

Following our ‘design guidelines’ of storing the fixture-specific non-connection-string settings with keys prefixed with the fixture name, we again invoke our helper method and just concatenate it onto the front of the expected appSettings key.

Overriding the Data File

Unsurprisingly, we follow the same approach to overriding the retrieval of the Data File on a fixture-specific basis, overriding the TestDataFilename property to perform the same kind of operation (read from the app.config file)…

protected override string TestDataFilename
{
    get
    {
        return ConfigurationManager.AppSettings[GetSettingsDiscriminator() + "_TestDataFile"];
    }
}

Where to Put All This?

That’s really about all there is to it.  Since the methods within the DatabaseUnitTestBase class are expressed in terms of these public properties, when the class goes about its work, it will use the overridden property accessors to read the values out of the app.config rather than using its ‘default’ values for these settings.

This leaves us with a bit of a conundrum however: since these base-class methods need to be overridden in each test fixture class that derives from DatabaseUnitTestBase, we would seem to need to reproduce all this code (even though its hardly much) in each of our test fixtures.

Inheritance to the Rescue!

Rather than going that route, I would suggest instead that all these overrides simply be refactored into a common class from which you can then inherit each of your test fixtures as needed.  In my example, I’m calling this new class ConfigDrivenDatabaseUnitTestBase as in…

public abstract class ConfigDrivenDatabaseUnitTestBase : DatabaseUnitTestBase
{
    protected override string DatabaseConnectionString
    {
        get
        {
            return ConfigurationManager.ConnectionStrings[GetSettingsDiscriminator()].ConnectionString;
        }
    }

    protected override string TestDataFilename
    {
        get
        {
            return ConfigurationManager.AppSettings[GetSettingsDiscriminator() + "_TestDataFile"];
        }
    }

    protected override string TestSchemaFilename
    {
        get
        {
            return ConfigurationManager.AppSettings[GetSettingsDiscriminator() + "_TestSchemaFile"];
        }
    }

    private string GetSettingsDiscriminator()
    {
        return this.GetType().Name;
    }
}

I’m leaving it also abstract so that its clear (and the compiler will enforce!) that its intended to only be used as a super type from which to derive other classes.

Using the ConfigDrivenDatabaseUnitTestBase Class

Using the new class in your own tests is now identical to using the original non-overidden DatabaseUnitTestBase class: simply derive from ConfigDrivenDatabaseUnitTestBase and get started as you normally would using the original class…

[TestFixture]
public class Fixture1 : ConfigDrivenDatabaseUnitTestBase
{
    [Test]
    public void Test()
    {
        //your test here!
    }
}

[TestFixture]
public class Fixture2 : ConfigDrivenDatabaseUnitTestBase
{
    [Test]
    public void Test()
    {
        //your test here!
    }
}

Clean-Up and Error-Prevention

This example is necessarily down-and-dirty and contains no error-checking or even fall-back behavior if settings aren’t found in the app.config file.  Some ideas here for the reader include…

  • throwing an exception if a setting isn’t found
  • falling back to the ‘default’ behavior is a setting isn’t found

The exception approach might make sense if you want to only use this new base class in cases where you know you will use app.config-based settings and want explicit notification when a setting is missing as in…

protected override string TestDataFilename
{
    get
    {
        string filename = ConfigurationManager.AppSettings[GetSettingsDiscriminator() + "_TestDataFile"];
        if (String.IsNullOrEmpty(filename))
            throw new ConfigurationException("Could not find setting for TestDataFilename!");

        return filename;
    }
}

Since the overridden methods of base classes are still accessible to derived classes, its also possible to ‘fall-back to default behavior’ if custom settings aren’t found.  This might make sense when you want to use the new base class everywhere and then selectively override just the settings for certain fixtures that need different settings by adding them to the .config file if/when needed as in…

protected override string TestDataFilename
{
    get
    {
        string filename = ConfigurationManager.AppSettings[GetSettingsDiscriminator() + "_TestDataFile"];
        if (String.IsNullOrEmpty(filename))
            filename = base.TestDataFilename;

        return filename;
    }
}

This second approach would permit you to use this new ConfigDrivenDatabaseUnitTestBase class as a base for all your fixtures without regard for whether you place settings for each in your app.config file.

Override, Override, Override!

This specific example gives just a flavor for the kinds of extensibility that are possible using the Proteus library for data-dependent unit testing.  I hope this helps clarify how its really quite simple to change the behavior of (nearly!) the entire base by deriving your own class from it and overriding properties and methods as you see the need for your specific situation(s).  Since all of the methods and properties are virtual, it should be possible to twist the class into doing just about whatever you find you need.

Obviously if there are things that this approach to derive-override-extend doesn’t support, let me know and I can look into extending the library in other ways too!

Mean time, Happy coding!

© 2010 Unhandled Exceptions | Entries (RSS) and Comments (RSS)

GPS Reviews and news from GPS Gazettewordpress logo