Attention: We are retiring the ASP.NET Community Blogs. Learn more >

Fear and Loathing

Gonzo blogging from the Annie Leibovitz of the software development world.

  • Using MSBuild with Smart Client Software Factories

    The Smart Client Software Factory (SCSF) is an awesome tool. It comes in the form as a guidance package from the patterns and practices guys and kicks off your initial Smart Client app with various services, several projects, and a shell application all built on top of the Composite Application UI Block (CAB).

    I have found one problem with the current version of SCSF and that's when you generate the initial solution and try to build it using MSBuild. Create a solution using the factory and try building the .sln file with MSBuild. You'll get a host of errors about projects referencing projects that don't exist. Here's some sample output:

    SmartClientSolution1.sln : Solution file warning MSB4051: Project {90BC9A2E-DF32-4D50-AB7A-2967B8F5D8D9} is referencing a project with GUID {BE39A9ED-D4C6-42E7-91D6-63D9B1D185C6}, but a project with this GUID was not found in the .SLN file.

    I believe this might be because the .csproj/.sln file is generated before the GUIDs are. It doesn't have a problem in the IDE because it references projects by relative file path, but when you try to build a solution using MSBuild (like via an automated build server) the build fails.

    Just to clarify this. The GUIDs in the solution file and csproj files are correct however where each project references another in the csproj file it contains both a reference location and a GUID. It's that GUID that's incorrect.

    Here's the section in each .csproj I'm referring to:

    <ItemGroup>
    <ProjectReference Include="..\Infrastructure.Interface\Infrastructure.Interface.csproj">
    <Project>{C0143C3B-2D43-4CC3-B593-236D4097F23F}</Project>
    <Name>Infrastructure.Interface</Name>
    </ProjectReference>
    <ProjectReference Include="..\Infrastructure.Library\Infrastructure.Library.csproj">
    <Project>{90BC9A2E-DF32-4D50-AB7A-2967B8F5D8D9}</Project>
    <Name>Infrastructure.Library</Name>
    </ProjectReference>
    </ItemGroup>

    You can fix this without a problem. To do so just open up the .csproj file and in the ItemGroup section, paste in the correct GUIDs for each project it's referring to from the original .sln file. The references that need to be fixed are:

    • Infrastructure.Library referencing Infrastructure.Interface
    • Infrastructure.Module referencing Infrastructure.Interface
    • Shell referencing Infrastructure.Interface
    • Shell referencing Infrastructure.Library

    Once you've updated the GUIDs in the .csproj files, you'll be good to go for automated builds of your CAB projects. I've logged this as an issue here on the new CodePlex site so hopefully they'll get to fixing this as it was a real pain to find.

  • My Top 10 Films of 2006

    Seems like you do this every year, but a friend asked me what mine were. Here they are:

    1. The Departed
    2. El Laberinto del Fauno (Pan’s Labyrinth)
    3. Cars
    4. Pirates of the Caribbean
    5. Letters from Iwo Jima
    6. United 93
    7. The Illusionist
    8. The Prestige
    9. The Da Vinci Code
    10. Superman Returns

    You could question Superman Returns but I really liked the homages Brian Singer did as a nod to Richard Donner and his amazing version. Cars really did make my feel good, Pirates was a good escape and despite complaints about how off the Da Vinci Code was, it was still fun. However Scorsese really nailed it with The Departed. Oscar nods to him and some of the cast. These are only films I've seen. If I had got out to see A Scanner Darkly, that might bump something like The Illusionist or The Prestige.

    So what's your 10?
     

  • Development mottos to keep the team spirit alive

    Today we were talking over some things as we start up the next sprint (sprint #4, 1 maybe 2 to go!). The conversation turned towards the fact that one guy on the team was away on holiday but he was the "report guy" and currently one report was causing problems. Unfortunately we've run astruck of the code ownership problem that I really wanted to avoid, namely being dependent on one resource for one slice of the application. Not a good place to be in and something you want to avoid. As we were chatting this set of syllables came streaming out of my mouth:

    "If all you do is what you know, you'll never grow."

    Plain, simple, and short. Now maybe I heard this somewhere before but after saying it, it made me think (and laugh) and we all had a good chuckle over it. However it really does ring true. Sure everyone has individual skills and some people are better at database programming vs. UI design vs. domain modeling, but in the end a well-oiled team needs to be able to respond to any problem. In any module. In any area of the code. While you might be great at writing the same thing over and over again, it isn't challenging let alone pushing any kind of thought-provoking edge so how do you expect to move with the times?

    We wrote the quote on the whiteboard and it resonated. It's one of the mantras we're adopting to always remember not to paint ourselves into a corner and be dependent on any one resource and to tread into those uncharted areas of the your capacity. So get out a little bit, explore your code and if you've never written a view using MVP, now's as good as time as any to learn.

    Later in the conversation we came up with another one (we thought we were on a roll). It started with the U.S. Army's "Be all that you can be" motto and became this:

    "Test all that you can test."

    Yeah, a little corny but then my co-worker Dale came up with this widget:

    "If you don't write tests... you're dead."

    It was getting later in the day and things started to go downhill but walk with me on this one. We laughed at it but then combined the two statements:

    "Test all that you can test and if you don't write tests you're dead."

    While it may sound a little chilling and morbid for a software development project, after we wrote it on the whiteboard it just clicked. The team was dead in the water if we don't write tests. We're currently facing new functionality and dealing with some bugs coming up and doing lots of fairly aggressive refactoring. You can't successfully refactor parts of your codebase if you don't know what it does or what the downstream impact is, so when you come upon muddy waters where there's no tests our mantra is to write one then move on. While we do have about 70 good tests (after 3 months of development) we could have more and we've been procrastinating to write more tests (especially for the presenters) for a long time. Pressures from the users, not enough time, blah, blah, blah, blah, blah. So with this little motto and some team re-enforcement of asking everyone at the Scrum when they mark something as "Done" we'll ask if they have tests for it. If not, we're not going to consider it done. Hopefully that'll get us back on track and be productive at the same time.

    Finally, later today we had a technical overview and discussion of a new Smart Client project I'm leading up. It was the usual wallow through all the tools, techniques, technologies, process, and standards that we're going to do (with a load of the usual acronyms [CAB, SCSF, TDD, DDD, BDD, FIT, etc.] all thrown up on the whiteboard for discussion). About halfway through as we were talking about testing and specialization of code, I threw the two statements up on the whiteboard again. 

    "If all you do is what you know, you'll never grow."

    "Test all that you can test and if you don't write tests you're dead."

    A completely different team with varying levels of experience on the various tools and processes, yet everyone agreed with what we had written. Yup, that's what we have to do for this project to be successful (well that plus deliver a quality solution to the customer).

    Anyways, just something to think about. Even if something sounds corny it's a morale builder and an item to talk about. Remember to keep these little team building exercises fun and light and hey, who knows, you might come up with a little motto for your team to keep things interesting!

  • Handling Multiple Environment Configurations with .NET 2.0

    Dealing with connection strings and configuration information is something developers do every day. The problem is compounded when you have to worry about local database connections, QA/Test deployments, and finally your release into production. Luckily with .NET 2.0 configuration is easier and the ability to externalize configurations combined with a little craftiness on your part will make builds easier to deal with.

    Let's say you have 4 environments to deal with. Your local machine, an automated build server, a test deployment for QA to do user acceptance testing, and the production release. Each one of them has different needs and will access information like database connections in a variety of places. By default when you create a new project (any project) in Visual Studio you get two configurations, Debug and Release. Debug has symbolic debugging turned on, Release doesn't (plus there are some other optimizations but we don't care about those right now).

    In 2.0 application configuration is easier with a little something like this:

      142     <connectionStrings configSource="ConnectionStrings.config"/>

    Rather than having our connection string all spelled out in App.Config or Web.Config, we can redirect it to a completely separate file. As the connection strings may change from environment to environment you don't want to have to edit this file manually, especially if it's being checked into source control so you're always changing it. This means the next time your buddy pulls down the file he'll have whatever change you made (maybe after a deployment to Test) and have to change it back. Worse yet is you might forget to edit this during a deployment (there's no way to force you to) so the next this is you deploy your Smart Client app with a connection to "localhost". Not cool.

    So here's a strategy that might work for you. Create a config file for each environment you have then during a pre or post build step (doesn't matter which) in your main forms build you can copy the appropriate file as needed. This way your App.Config or Web.Config file doesn't change but the right settings are picked up from the file(s) you need.

    First create the configurations you need. This is done by right clicking on the Solution and selecting Configuration Manager. Then in the "Active solution configuration" drop down, select "<New...>" to create them. You can accept using the default Debug and Release configurations if you want, but I find that "Debug" isn't very informative as I might want a debug version both on my local machine and my automated test or shared dev server. Here's a configuration I use that might suggest something that works for you:

    • localhost - Based on Debug but indicates to me I'm building and running locally
    • AutomatedBuild - Based on Debug or Release (your choice) but used for the automated build server. For example you may not want the automated build to deploy any web or report projects so it's good to have a new configuration here.
    • Test - Based on Debug and used for your testers. You might want to base this on the Release configuration (depending on how savvy your testers are) and you might want to name this something more appropriate to your environment (like QA or something)
    • Production - Based on Release and meant to be the build you deploy to your customer

    Note these are all new configurations rather than renamed ones. Why? If you simply rename a configuration that's done at the Solution level. The project configuration names in each project will still be Debug and Release so it's confusing when you're setting up what configuration of a project is matched against the build. Trust me, just create new configurations and you'll be fine.

    Now that you have your configurations setup, create a new file for each configuration. This will hold the connection strings for each configuration. Name them using the following convention:

    ConfigurationName.ConnectionStrings.config

    For example if you had localhost, Test, and Production as your configurations you would have the following new files in your main project:

    • localhost.ConnectionStrings.config
    • Test.ConnectionStrings.config
    • Production.ConnectionStrings.config

    The contents of each of these files is dependent on the environment but will look like this:

        1 <connectionStrings>

        2     <add name="LocalSqlServer"

        3         connectionString="Data Source=localhost;Initial Catalog=DatabaseName;User Id=sa;Password=password;"

        4         providerName="System.Data.SqlClient" />

        5 </connectionStrings>

    Finally to make it all work, go into your main project and setup a pre or post build event that looks like this:

    copy "$(ProjectDir)$(ConfigurationName).ConnectionStrings.config" "$(ProjectDir)$(OutDir)ConnectionStrings.config" /Y

    What does this do? It grabs the configuration file for the appropriate build and copies it to your output directory with a common name. That name is what's referenced in your App.Config or Web.Config as shown above.

    Now when you build your system, depending on each configuration, it will copy the appropriate file with the correct settings but nobody needs to edit the main configuration file as it always references a common name (ConnectionStrings.config). Cool huh?

    Note you can use this for a variety of sections in config (there are restrictions). Check the API documentation on what you can and can't externalize but connection strings and app settings are one of them which is good enough for 90% of the universe. 

    Of course, after all this is said and done there is another way to handle your environment issues. Just use NAnt or MSBuild, but then that's a whole 'nuther blog post isn't it?

    Enjoy!

  • Back to the Future

    Many bloggers these days are writing up their New Years plan. What are they going to accomplish this year. Sounds like a good idea, but I wanted to put a bit of a spin on it. Rather than write out a detailed, technical list of tasks I want to do I thought it would be more effective to write a future letter to myself.

    Here's how it works. You write up an informal letter to yourself, to be read by yourself this time next year. In it, you state in past tense what you accomplished the previous year (2007). This time next year, you open the letter, read the email, visit the blog entry, whatever and see how you did. So rather than have a sticky list of tasks, you've got a friendly view of what you accomplished (or set out to accomplish) which hopefully brings more meaning to the meat of things.

    As this is my first venture of this type, next years letter will be more detailed and have more meaning than the first time around but overall I think it's a better approach to the whole blogging New Years Resolution that's going around now.

    Okay, so here's mine.

    Dear Bil,

    Congratulations on finally getting the MOSS 2007 version of the SharePoint Forums out there (and killing off those nasty bugs people have been reporting). It's your most popular SharePoint tool to date. Following up with the forums you did a good job with the Knowledgebase as many people found value in that (and you were able to use a lot of code and concepts between the two). And the trifactor was releasing SharePoint Builder which had been lingering for awhile but proved to be a valuable tool for the community.

    You finally put to rest a new SharePoint community that needed to get out there and it was a great launch, with updates every few months to keep the community needs met and fresh. All this work was not without benefits as in April you got re-awarded the MVP award in SharePoint for the 4th year running.

    It was a busy year travelling as you made your way to the MVP Summit in March, got at least one conference in during the year and then there was PDC. While you didn't present or speak there, it was an important event no matter and you hooked up with a lot of people and showed off what was to come in 2008 with SharePoint. You did manage to make up the year with at least one web cast or user group presentation each month on something new either in SharePoint, Team System, Agile, or Scrum.

    Finally, while you were a blogging monster creating many entries all with some content to offer the community, you did find time for the family as that always does come first. Congrats and here's to a great 2008!

    Until next year, we'll see how close to the mark I came.

  • SharePoint Builder now setup on CodePlex

    Yeah, I'm a CodePlex junkie. First the forums, then the knowledgebase, now SharePoint Builder. SharePoint Builder, my red-headed step-child of a project that spawned from a cigarette conversation with AC (and others, they were doing the smoking) somewhere in Redmond.

    SharePoint Builder

    I've setup SharePoint Builder on CodePlex and it will be released under the same license the other projects are, namely the Creative Commons Attribution-ShareAlike 2.5 license. Basically, do what you will with the tools. Credit me for any derivitive works and feel free to use it commercially. I'm pretty easy.

    As mentioned before, SharePoint builder (very different than the image above right now) is built on top of .NET 2.0, C# (code will be available at release) and uses the Composite Application UI Block (CAB) as well as Enterprise Libraries and a few other Microsoft goodies. You'll need the Guidance Automation Extensions and Smart Client Software Factory installed for the source code release.

    No commercial libraries will be used, but I would really like to try building it using a Ribbon control as the paradigm fits well, however I don't want to tie anyone to a library that they have to pay for. Not sure what I'll do there as there are currently no free, open source Ribbon implementations and I'm not about to build one myself. 

    No date on release yet as I'm wrapping up the forums and knowledgebase now along with another project I promised someone but will be doing small commits of the source over the next few weeks to get things into the system.

    Also I'll be setting up the release on a public web server for ClickOnce installs in case you don't want to download and build it yourself but rather just use it.

    Hey, I told you it was going to be a busy year. Second day and I've already done 8 posts, tagged 5 people, and updated 3 ongoing projects. Just wait until tommorow :)

  • SharePoint Forums and Knowledgebase Release Date Updates

    Just wanted to let everyone know I've updated the plan for the release of the SharePoint Forums and SharePoint Knowledgebase Web Parts. These are the dates as I can commit to them now (crazy holiday schedule and stuff that just prevented me from getting the job done):

    SharePoint Forums v2.0.0.0

    • Prod: Feb-12-2007

    SharePoint Knowledgebase v1.0.0.0

    • Beta: Jan-29-2007
    • Prod: Feb-26-2007

    Not a lot of information on the Knowledgebase Web Part yet (other than this post). Feel free to log your own features/enhancements in the Issue Tracker yourself and vote to shape the feature list!

  • Vote for your most wanted issue on the SharePoint Forums Web Part

    The guys at CodePlex updated the site some time ago implementing a "digg" like feature where you can vote for an issue and bump it up in priority. It's really slick and helps keep things in sight and what's important to you. So if you get a chance to visit the SharePoint Forums Web Part site on CodePlex here over the next while, take a look through the Issue Tracker and vote on your favorites. This is for tracking bugs but also includes new features and enhancements.

    Now I just need to bust my butt to get this (and other things) done asap (like the long overdue 2007 update and some bug fixing that has to be done).

  • Five degrees of separation

    There's a tagging game going on in the blog-o-world. I traced the origins (I think) back to Jeff Pulver here. Basically someone tags and you have to come up with 5 things about yourself that relatively few people know. You then go and annoy the crap out of 5 of your friends who blog to do the same. Glenn Block tagged me. Yeah, it's 2007 and we're practicing digital chain-letters but oh what the heck, it's almost January 2nd and I still haven't finished my blogging day just yet.

    Here's 5 completely silly things you may (or may not) know about me (or care):

    1. I used to be big in graphic design doing movie poster (for movies that would barely show up on IFC), animation (for films I'd rather not admit I was part of), and drawing comic books (indy back when indy was cool, never did the big Marvel or DC titles).
    2. I was part of a special effects studio based out of Oakville, Ontario where I did matte paintings and special effects. We won an award one year from Much Music for the effects on a music video I did work for.
    3. I drive the biggest, gas-guzzling vehicle known to man (a Dodge RAM 1500 Megacab) and I'm proud of doing my part for the environment (I also have a Suziki SUV so I generally take up the slack up for the gas quotient per person in Alberta). Go ahead naturalists, have at me!
    4. I've never broken a bone in my body but did have my appendix removed a few years ago (just before it was about to explode in a rather Stubbs the Zombie like move).
    5. My name "BIL" is spelled this way because back in the 80's when video games and quarters were all the rage, the games only supported entering three letters when you got a high score. I got a lot of high scores and would only be able to spell "BIL" instead of "BILL" (curse those Atari programmers!). So it just stuck.

    There. Tag. You're it. I ceremoniously tag the following people that have crossed my path in the past and will now pay for it, or face the wrath of the broken tagging game:

    • Jean-Paul Boodhoo - Developer Craftsman Extraordinary, in any language or tool
    • James Kovacs - Intense 64-bit .NET guy and recent Architecture MVP awardee
    • Kate Gregory - Awesome C++ skills and a fellow Canuck
    • Joel Semeniuk - My Winnipeg Team System guru
    • Keith Richie - Former Microsoft SharePoint guy, new Mindsharp SharePoint guy

    Go forth you uber-geeks and thou shalt write 5 things about yourself, not 3, and definitely no more than 5, and then tag 5 other people with the same fate.

    Who knows, maybe someone can make some money from this silly game then we can talk again. Here's a thought, someone could build a diagram of everyone who tagged everyone else. Then we'll see how close me and Mr. Gates really are.

  • SCSF Community has moved

    One of my favorite geek communities (if you want to call it that) is the group out of the Patterns and Practices guys who make the Smart Client Software Factory. This is a great package built on top of the Composite Application UI Block and created using the Guidance Automation Toolkit to create an excellent way to get your Smart Client projects off the ground (I've started 3 Enterprise applications using it so far).

    They've moved their site over to CodePlex (hurray!). I really detest (read:hate, scourn, abhorr, loathe, spite) GotDotNet and it's workpaces. I mean, everytime someone sends me a link it's a crapshoot whether or not I'll even get to the site by going to the link. When I go to links on GDN it's tied to Windows Live IDs or something but when I go to these links I end up at the basic page. I have to reload the page to actually get to the real destination after Windows Live logs me in (or something silly like that). The search navigation is confusing and have the time I get lost and end up somewhere I shouldn't be. Yeah, in a word I hate GDN and am very happy these guys are moving to CodePlex.

    The new site actually covers the SCSF, CAB, and a few other blocks like the Updater block (which needs to be updated to work with SCSF for example). It's nice to have everything together in one spot and I'm sure they'll add more as they grow. They have locked the forums on the old GDN site (which explains why I'm not getting any new feeds) and have committed to moving all the content over (code, forums, etc.) which is a nice touch for finding information (the search on CodePlex actually works).

    You can find them on their new CodePlex home here.