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.

  • Old and busted or new hotness

    Roy Osherove posted a what's hot and what's not list, mainly aimed at this whole ALT.NET developer talk that's been going on. Unfortunately, I'm a little at odds with what Roy posted and don't agree with some (most?) of his comparisons. It's also hard to compare things here as he's grouped items together that either overlap, are completely different, or don't make sense to be together and are vague. I really don't care for the whole ALT.NET tagging as I think even the term ALT.NET is silly but here's my spin on Roy's items.

    UPDATE: Roy updated his blog entry with a note that he didn't necessarily agree with the list, these were his observations of the world. I was a little confused because I thought he was emoting what he felt. Silly me. Still, I think the comparisons are a little strange as it mixes technology with concepts hence why I put my list at the end together. I also stand corrected on A# and that Castle can do both DI and AOP quite well. Thanks for the info!

    Hot: Castle, ActiveRecord, NHibernate
    Not: Datasets, Entity Framework, MS Application Blocks

    I'm not quite sure what he's talking about here. I don't feel ActiveRecord is "hot" and I try to avoid the pattern altogether. NHibernate for sure and Castle is cool (over DataSets any day). Is he comparing Castle and it's DI against MS Application Blocks? More on that later.

    Hot: MVC, NUnit, MonoRail
    Not: Web Forms, SCSF, VSTS, MSTest

    Again it gets a little clouded here (at least with my glasses on). Definately NUnit over MSTest hands down. With the pain and suffering Oren's been going through with Web Forms, MonoRail looks like a good alternative (JP gave a presentation at the Calgary Code Camp and from what I saw it looked promising). MVC hot? A pattern? I guess. However it's a tough call here as SCSF implements MVC and it's not a horrible implementation of the pattern, so how can one be hot and the other not. Also I'll agree that VSTS isn't necessarily hot (more like complex, expensive, etc.) but what are you comparing it to?

    Hot: XP, TDD, Scrum
    Not: MSF Agile, MSF for CMMI

    No argument here and right on the money. I wish MSF Agile was never created.

    Hot: OR/M, NHibernate, LLBLGen, etc.
    Not: DLinq, Data Access Block, Plain ADO.NET

    NHibernate for sure, but LLBLGen generates code that uses ADO.NET under the covers here. I guess the point is that it's not hot to write ADO.NET code directly but have a code generator do it for you? Personally that's fine because anyone that writes their own full DAL is just wasting brain cells.

    Hot: Open Source  (Mono, SourceForge)
    Not: Application Blocks, CodePlex

    This confuses me. Open Source is one thing, but it's being compared to... Open Source. The MS Applicaition Blocks are all open source and every project on CodePlex is as well. If you're comparing SF to CP from an open source perspective, neither really are. You can't get CodePlex code at all (there's an Open Source version someone wrote but it's far from complete) and SourceForge hasn't released their code for years with the old code barely able to instal and configure (Alexandria). Better to go with GForge if you're looking to run your own SourceForge site and source code is provided.

    Hot: CVS, SVN
    Not: VSS, VSTS Source Control

    Agreed. VSS is the devil's spawn, although with all the crashing you can get I would suggest SVN is hot and CVS isn't. CVS is better than VSS stability wise, but it's still not all that hot.

    Hot: Subtext, DasBlog, WordPress, etc.
    Not: Microsoft MSN Spaces, Community Server

    Roy is comparing blog software for those that haven't clued in. I do agree that SubText/DasBlog/WordPress is much more powerful and are better blog engines. CS seems to be bloatware now (and I have a bad feeling from it after the last weblogs update). Microsoft does have SharePoint for blogs and it's getting better, but maybe still not ready for primetime to compete with something like DasBlog. The thing about blog software though is that there isn't going to be a giant shift. I mean, let's say the next guy (Google, MS, whoever) comes out with the be-all and end-all blog engine. Do you think thousands of DasBlog or WordPress users are going to migrate en masse? My blog is on CS, so is Roy's. So are we not hot because of this setup and Hanselman is?

    Okay, I'll stop there as there are some other weird deviations Roy makes. I totally am all in when it comes to simplicity in design, but he compares it to the entire P&P (which started this entire thread the last couple of weeks). I'll bite that CAB is complex and we've done that discussion to death. However where is the more simplistic version of CAB that gives us everything we need? Where's the HOT version of CAB? RYO Winforms, I don't think so. And I haven't worked at Google but being at Microsoft is pretty fun, but I guess that depends on what team you're on.

    There's also a point he makes about Google Gears being hot and Smart Client not. I haven't had an opportunity to really get into Gears and it sounds great, but things always come in great packages. Is this really the future of apps? I mean, with Silverlight we have super rich clients written in .NET managed code and all doing whatever they need to over the wire. Are going back to writing crappy web apps (maybe with MonoRail to reduce the crappiness) and just plug Gears in and voila, offline capabilities. Is a Silverlight/Gears combination the golden ticket here and Smart Clients go the way of big fat clients from VB6 days long passed.

    Like I said, I do agree with some of his comparisons, but let's compare apples to apples here. Here's my modified list where it's just one product/technology/concept against the other. I've also ommitted things that Roy and I agree on that are already in his list:

    Hot Not
    NHibernate Entity Framework
    Windsor Container ObjectBuilder
    Aspect# Policy Injection Application Block
    CruiseControl.NET Visual Studio Team Build
    SharpDevelop Visual Studio
    MonoRail Web Forms
    NUnit/MBUnit MSTest
    Scrum MSF Agile
    NAnt MSBuild
    log4net Logging Application Block
    Silverlight Flash
  • Extending the Notification Pattern Example

    Recently I've been looking at implementing the Notification pattern as described by Martin Fowler here. The UI calls methods on the domain to validate the data which is held in a Data Transfer Object (DTO). The DTO contains both the data needed by the class (for reconstituting domain objects) and a class for holding errors returned by the validation method. It's a nice way to remove managing errors in your domain layer but still have them available to your presentation layer.

    One thing I've always found with Fowlers posts is that the code is very thin (and it should be since it's just an example) and sometimes not complete. So for you guys I decided to put together a working example based on his sample for checking a policy claim number. A couple of things I've done to go beyond the example on Martin's page are:

    • Working solution file that compiles and runs (C# 2.0 although with slight modifications [removal of generics] it could work under 1.1)
    • Implementation of the Model View Presenter pattern. Martin uses the Autonomous View approach in his sample because he's really focused on Notification, but I thought it would be nice to show it implemented with MVP. Autonomous View is a pattern for putting all presentation state and behavior for a window in a single class, but that really doesn't support a base approach that I prefer namely MVP and separation of concerns so the MVP pattern is here for completeness.
    • Added Rhino mock tests to show how to test the presenter with a mocked out view. I thought this was important as the example is all about UI validation and this would be a good example to mock out a view using Rhino.

    The Tests

    It starts with the tests (it always starts with the tests). As I was re-implementing an example my tests were slighted a little bit towards how the sample worked. However I was focused on 3 main validations for the UI:

    • Policy Number is present
    • Claim Type is present
    • Incident Date is present and valid (cannot be set in the future)

    With those tests in mind, here's the check for the missing policy number (with mock setup and teardown):

       20 [SetUp]

       21 public void SetUp()

       22 {

       23     _mockery = new MockRepository();

       24     _view = _mockery.CreateMock<IRegisterClaimView>();

       25 }

       26 

       27 [TearDown]

       28 public void TearDown()

       29 {

       30     _mockery.VerifyAll();

       31 }

       32 

       33 [Test]

       34 public void MissingPolicyNumber()

       35 {

       36     Expect.Call(_view.PolicyNumber).Return(INVALID_POLICY_NUMBER);

       37     Expect.Call(_view.IncidentDate).Return(VALID_INCIDENT_DATE);

       38     Expect.Call(_view.ClaimType).Return(VALID_CLAIM_TYPE);

       39     _view.ResponseMessage = "Not registered, see errors";

       40     _view.SetError("txtPolicyNumber", "Policy number is missing");

       41     _mockery.ReplayAll();

       42 

       43     RegisterClaimPresenter presenter = new RegisterClaimPresenter(_view);

       44     presenter.RegisterClaim();

       45 }

    The constants are defined so it's easier to read and are defined like this:

       13 private const string INVALID_POLICY_NUMBER = "";

       14 private const string VALID_POLICY_NUMBER = "1";

       15 private const string INVALID_CLAIM_TYPE = "";

       16 private const string VALID_CLAIM_TYPE = "1";

       17 private static readonly DateTime INVALID_INCIDENT_DATE = DateTime.MinValue;

       18 private static readonly DateTime VALID_INCIDENT_DATE = DateTime.Now.AddDays(1);

    The view is mocked out (which is what we're testing) so we expect calling the 3 properties of the view (that match up to the UI). There's also a ResponseMessage property which displayed if there are errors or not. The SetError method needs a bit of explaining.

    In Martins example, he uses Autonomous View which is great and the way he resolves what control is causing what error it's easy to wire up. All the controls are there for the picking. When I implemented the MVP pattern I had a bit of a problem. I wasn't about to pollute my presenter with controls from the UI (otherwise it would be easy) so how could I get the view to wire up the right error message to the right control. The only way I could do it (in the implemenation of the view) was to pass in the control name as a string. Then in my view implementation I did this:

      115 public void SetError(string controlName, string errorMessage)

      116 {

      117     Control control = Controls[controlName];

      118     showError(control, errorMessage);

      119 }

    Then showError just handles setting the error via the built-in .NET error provider:

       37 void showError(Control arg, string message)

       38 {

       39     _errorProvider.SetError(arg, message);

       40 }

    Once I had the missing policy test working it was time to move onto the other requirements. MissingIncidentType and MissingIncidentDate are both the same (except there's no such thing as a null DateTime so I cheated a bit and returned DateTime.MinValue). The other check against the Incident Date is to ensure it's not set before the policy date. Since we don't have a policy screen I just stubbed it out in a stub Policy class and set it to the current date. So an invalid date would be something set in the past:

       76 [Test]

       77 public void CheckDateBeforePolicyStart()

       78 {

       79     Expect.Call(_view.PolicyNumber).Return(VALID_POLICY_NUMBER);

       80     Expect.Call(_view.ClaimType).Return(VALID_CLAIM_TYPE);

       81     Expect.Call(_view.IncidentDate).Return(VALID_INCIDENT_DATE.AddDays(-1));

       82     _view.ResponseMessage = "Not registered, see errors";

       83     _view.SetError("pkIncidentDate", "Incident Date is before we started doing this business");

       84     _mockery.ReplayAll();

       85 

       86     RegisterClaimPresenter presenter = new RegisterClaimPresenter(_view);

       87     presenter.RegisterClaim();

       88 }

    The presenter is pretty basic. In addition to just registering the view and talking to it, it has one main method called by the view (when the user clicks the submit button) called RegisterClaim. Here it is:

       25 public void RegisterClaim()

       26         {

       27             saveToClaim();

       28             _service.RegisterClaim(_claim);

       29             if(_claim.Notification.HasErrors)

       30             {

       31                 _view.ResponseMessage = "Not registered, see errors";

       32                 indicateErrors();

       33             }

       34             else

       35             {

       36                 _view.ResponseMessage = "Registration Succeeded";               

       37             }

       38         }

    Basically it calls saveToClaim (below) then calls a service layer method to register the claim. Information is stored in a Data Transfer Object which contains both the data from the view and any errors. The claim DTO has a Notification object which has errors (or not) and the presenter will tell the view if there are any problems, letting the view set the display accordingly.

    First here's the saveToClaim method in the presenter that will create a RegisterClaimDTO and populate it with information from the view:

       67 private void saveToClaim()

       68 {

       69     _claim = new RegisterClaimDTO();

       70     _claim.PolicyId = _view.PolicyNumber;

       71     _claim.IncidentDate = _view.IncidentDate;

       72     _claim.Type = _view.ClaimType;

       73 }

    The RegisterClaim method on the ClaimService object will just run it's own command (which does the actual registration of the claim and checks for any errors). The core part of the validation is in the Validate method on the RegisterClaim object:

       39 private void Validate()

       40 {

       41     failIfNullOrBlank(((RegisterClaimDTO)Data).PolicyId, RegisterClaimDTO.MISSING_POLICY_NUMBER);

       42     failIfNullOrBlank(((RegisterClaimDTO)Data).Type, RegisterClaimDTO.MISSING_INCIDENT_TYPE);

       43     fail(((RegisterClaimDTO)Data).IncidentDate == RegisterClaimDTO.BLANK_DATE, RegisterClaimDTO.MISSING_INCIDENT_DATE);

       44     if (isNullOrBlank(((RegisterClaimDTO)Data).PolicyId))

       45         return;

       46     Policy policy = FindPolicy(((RegisterClaimDTO)Data).PolicyId);

       47     if (policy == null)

       48     {

       49         Notification.Errors.Add(RegisterClaimDTO.UNKNOWN_POLICY_NUMBER);

       50     }

       51     else

       52     {

       53         fail((((RegisterClaimDTO)Data).IncidentDate.CompareTo(policy.InceptionDate) < 0),

       54             RegisterClaimDTO.DATE_BEFORE_POLICY_START);

       55     }

       56 }

    Here it checks the various business rules and then uses the Notification object to keep track of errors. The Notification object is an object embedded in the Data Transfer Object, which is passed into the service when it's created so our service layer has access to the DTO to register errors as it does it's validation.

    Finally coming back from the service layer, the presenter checks to see if the DTO's Notification object HasErrors. If it does, it sets the response message (mapped to a textbox in the UI) and calls a method called indicateErrors. This just runs through each error object in the DTO through a method to check the error:

       44 private void indicateErrors()

       45 {

       46     checkError(RegisterClaimDTO.MISSING_POLICY_NUMBER);

       47     checkError(RegisterClaimDTO.MISSING_INCIDENT_TYPE);

       48     checkError(RegisterClaimDTO.DATE_BEFORE_POLICY_START);

       49     checkError(RegisterClaimDTO.MISSING_INCIDENT_DATE);

       50 }

    checkError is a method that takes in the Error object which contains both the error message and the control it belongs to. If the Notification list contains the error it's checking, it then calls that ugly SetError method on the view. This will update the UI with the appropiate error message attached to the correct control:

       56 private void checkError(Error error)

       57 {

       58     if (_claim.Notification.IncludesError(error))

       59     {

       60         _view.SetError(error.ControlName, error.ToString());

       61     }

       62 }

    And that's about it. It's fairly simple but the sample has been broken down a bit further hopefully to help you understand the pattern better. 

    Here's the class diagram for all the classes in the system:

     

    And here's how the classes break down in the solution. Each folder would be a layer in your application (or split across multiple assemblies):

    Application Layer
    RegisterClaim.cs
    ServerCommand.cs

    Domain Layer
    Policy.cs

    Presentation Layer
    FrmRegisterClaim.cs
    IRegisterClaimView.cs
    Program.cs
    RegisterClaimPresenter.cs

    Service Layer
    ClaimService.cs
    DataTransferObject.cs
    Error.cs
    Notification.cs
    RegisterClaimDTO.cs

    So other than the ugly SetError method which takes in a string for a control name, I think this isn't bad. Maybe someone has a suggestion out there how to get rid of the control name string but like I said, I didn't want to introduce UI controls into my presenter so I'm not sure (other than maybe an enumeration) how to hook up the right error message with the right control. Feel free to offer a suggestion for improvement here. 

    You can download the entire solution with source code here. Enjoy!

  • I keep Hugh in my back pocket

    I really do. Sort of.

    I had to get a new set of business cards. All those fish bowls and throwing cards away really has dwindled my supply. Rather than going with traditional cards, I've been using ones with designs by Hugh MacLeod on them. I just ordered a new batch tonight, landing solidly on my favorite cartoon to date from Hugh (besides the Blue Monster). Here's my new cards:

    Front

    Back

     

    A little hard to read but just the basic info, my tagline from my blog, my blog address, phone number and email. The usual suspects. I'm really happy with the cards and they make for an interesting conversation piece at conferences, user groups, and general geek fests. I highly recommend them. You can check out all 72 gapingvoid designs here on Streetcards (with new ones always being added when Hugh comes up with a brilliant idea, which is quite often).

    Enjoy! 

  • Introducing the New Vista iPod

    Finally, after almost 9 months of pre-production she's finally arrived. Here she is:

    Vista Avalon Simser, ready for duty!

    Vista Avalon Simser was born May 18th at 18:10 MST, weighing in at 5 pounds and 11 ounces (well, 10.6 ounces but the hospital seems to round it up).

    Okay, first I know that most of you are reading this on the bus, at home, at work, and you're laughing. Some people are shocked and probably scratching your head why a nerd would potentially put their child through the slings and arrows of naming their spawn after an operating system. Hopefully by the time she's old enough for someone to make fun of her name, nobody will remember where it came from.

    Her name came as a discussion about what her name should be, as they always do. At first we didn't know what sex the baby was going to be so we started with a boys name. We rummaged around the Internet, baby name books, and our brains finally to arrive at Dev. Yeah, geek origins but it had meaning to us. Dev (as in short for Developer) sounded like a good boys name; had it's origins in Sanskrit, it was unique and interesting and we liked the sound of it. Then came the process of finding a good middle name and again after some time, we liked Orion (as in the constellation).

    We stared at the piece of paper with his name written out:

    Dev
    Orion
    Simser

    DOS

    There it was, plain as day. Our son's initials would be DOS. We laughed and laughed and then came the afterthought. Well, if our son's initials are DOS, a daughter would have be an upgrade. And thus the name Vista was born.

    Vista (the operating system) hadn't been released yet, but we looked at it on paper. Vista. I liked the sound of it. True, it was spawned from the name of Microsoft's next operating system but it was also a word seeded in the Italian language (from visto) meaning a sight. Well, a daughter who is a sight. That works for us. Besides, above all (other than the glares we'll get from geeks and this blog entry) Vista is a pretty name for a girl. As for the middle name, it was not driven by the fact that Avalon was the codename for Windows Presentation Foundation. Again we turned to unique names and needed something that fit. Something that sounded right to match Vista. Avalon being the paradise where Arthur was carried to after his death; Avalon the peninsula in Canada in Newfoundland; Avalon the Druidic site in Glastonbury, England. This just became the name we wanted for our daughter and it stuck.

    There are two reactions we get from her name. Probably everyone reading this blog, is the first reaction. "You named your daughter after an operating system?". The other is "Oh that's such a pretty name". We can separate the nerds from the norms with the reaction.

    Of course there are some advantages to being named after one of the most expensive operating systems in history (notice that I didn't say popular, good, or fast; let's not get into that holy war):

    • Her blog will contain the largest number of search hits with people looking for information about Vista
    • She has her very own carrying case (a laptop bag) and other personalized "logoware", most of which I can buy from the Microsoft store or any geek conference for the next 10 years
    • She'll be the only one at her school with a service pack (or two, or three, ...) named after her
    • If she's cute when she's older (and she will be) boys will make many crazy jokes about "starting her up" and "rebooting her" to which I will pummel them upside the head with an XPS laptop that I'll carry around to "interview" any potential suitors.

    Bottom line, we think it's a pretty name and it's hers for life. We like it, and she's our daughter not yours so deal.

    Not every entry into this world is perfect and there were complications. Needless to say, we were disappointed at the process (but not the result, not in the least). We had gone through obtaining a midwife. We're true believers of the natural way and were convinced having a midwife and a home birth was what we wanted. No drug induced delivery. No machines that go ping. No drip, drip, drip of some bag attached to the baby that's hooked up to a monitor. It was going to be natural, fun, and without stress.

    The best laid plans.

    As a result of a lot of factors (incompatible blood types between momma and poppa, go figure) it was difficult and we ended up doing everything we didn't want to happen. It was a hospital birth, we had machines that went ping, drugs were used to induce, an emergency C-Section was needed, etc. Like I said, the best laid plans.

    Vista spent a week in the hospital, mostly for jaundice. However she seemed to enjoy her personal suntan studio as you can see below.

    Everyone is home now. Mommy and Baby are doing great. Vista's two weeks old now and is thriving. This was a life changing experience for me. It will be long remembered, not only for the birth of my daughter; the changes we went through; and the journey ahead. I hope you've enjoyed the sharing of the experience and this is something that I'll someday show to her, so feel free to leave comments for her to read when she's old enough. So welcome Vista to the world as she'll be a big part of it.

    Here's Vista's entire Flickr set which of course grows every day with new images.

  • Do as I say, not as I do

    More fallout from the TestDriven.NET vs. Microsoft department. I read your comments to my blog (no, I didn't moderate any of them) and read through Dan Fernandez's well written and concise response here. Dan is the lead product manager for Visual Studio Express, so other than the legal guys, this is coming from the horses mouth. Phil Haack has a great piece here with his take on it (which has an interesting spin, as he declares MS violated the TestDriven.NET agreement by reverse engineering it to determine how TD.NET works with Express, touche).

    After reading through everything out there (including all the comments on Jamie's Slashdotted blog) I do understand both sides of the story. I do agree that MS is in their rights to put what they want in their EULA and they're right that users of TestDriven.NET in Express products are violating it. I don't agree that MS is playing by their own rules.

    Specifically I personally have a real problem with Microsoft saying TestDriven.NET violates a EULA, yet they themselves do exactly the same thing with Popfly Explorer, XNA Game Studio Express, and the Reporting add-in. It's no different than saying cops are allowed to break the law because they're cops. No. You write the rules and live by the rules (lead by example). Just because it's your product doesn't give you the right to violate your own agreement.

    There's also confusion in this issue because it's an EULA that TestDriven.NET violates. Let's look at that. End User License Agreement. IANAL, but in many cases of "agreements" they have never held up in court. They're simply that, an agreement. You either agree or disagree, but in the end there's no legal ramification either way against you. Remember the Dell incident where the EULA for Windows was shrink-wrapped but yet you had to agree to it. If you opened the package to read the EULA, you were agreeing to it even if you didn't agree after reading it.

    I do agree with the Blue Monster in that it's their right to put whatever they want in their EULA. It's theirs and they craft it. The thing here is that it's an End User agreement. So who's at fault here? Jamie for building a tool, or everyone who's using it. I believe it's the latter and most Americans will agree (yeah, I'm going to get slack for this generalization) in the same vein as it's not the gun manufacturers that are at fault, it's the people using them. So everyone who's installed TestDriven.NET on an Express SKU and allowed it to run is in violation. Where's the cease and desist orders for all of you? Jamie certainly isn't in the wrong to create the software he did (and MS recognizes this) but users (including himself perhaps, assuming he tested it) are violating their agreement with Microsoft by using it.

    The general consensus I'm seeing from the community (via comments and blogs) is that MS should patch the Express SKUs to not even allow loading add-ins. Of course, there's still the issue of their own add-ons but I'm sure they could get around that somehow. There's still the question of what specifically Jamie is violating (or rather what clause). Many people are asking that question but I guess it's a legal-speak problem as I can't find anything specific enough from Dan Fernandez's Blog:

    "Jamie has also made available a version of his product that extends the Visual Studio Express Editions which is a direct violation of both the EULA and “ethos” of the Express product line."

    If it's a "direct violation" what's the "specific clause" it's violating? Again I read it this afternoon and I can't see it. As for the violation of the "ethos" of the Express product line, ethos [meaning a distinguishing character according to Merriam-Webster] seems very subjective to me depending on who's looking at it. There's part of the EULA that states that you may not "work around any technical limitations in the software". Again, subjective here as I'm not sure that adding new functionality that didn't exist is a work around technical limitation. Express does not have a technical limitation running Unit Tests, it was just never designed with it in. Much like it can't edit images directly, do I voilate the EULA if I build something that let's me manipulate image files in Paint.NET instead of Visual Studio Express? Another comment is on reverse engineering the product (VS not TD) but I know how Jamie wrote his addin and it never reverse engineered anything. It uses a documented and public API that's been there for years.

    I do like and agree with Frans' comment on Phil's blog entry:

    "MS should have disabled add-in support in the toolkit. OF course they were tool lazy to do so or technically unable to do so, so they thought they could hide behind a silly phrase in an EULA which isn't even applicable here (as the EULA has no right on what Jamie distributes to OTHERS). If Jamie compiles his code on teh command line the whole EULA argument is moot, just to illustrate the point."

    So a few options could be pursued at this point:

    • Jamie removes the Express support for TD.NET. Maybe end of story? He did it before, and only since it was re-enabled has this bear reared it's ugly head.
    • MS issues a patch to the Express line to not load add-ins. Problem is their own add-ons won't load (unless they themselves circumvent that)
    • MS finds out everyone who's running TD.NET and issues a cease and desist letter them them because they're violating their EULA. Won't happen and again, they would have to tell their own users of Popfly Explorer and other tools to do this.
    • MS strong-arms Jamie to remove the product, support, or both. Jamie collapses under legal costs and gives up. Might happen as Microsoft has more than enough resources to just simply throw at this problem to make it go away.

    What a silly mess. Anyways, I'm done with this thread. Jamie has been Slashdotted, and life will find a way.

  • The pot calling the kettle black

    Who's the pot? Microsoft. Enough with the craziness over Jamie Cansdale's excellent (read:must install now) addon for Visual Studio TestDriven.NET. I'm a huge fan of the tool (bought a copy to support Jamie and his excellent efforts, I recommend any good developer to do the same) and have supported Jamie in his efforts, especially after they booted him from the MVP program over some questionable tactics and reasoning. I followed him via emails and his blog posts discussing the matter and the sillyness of it all. Now it's come to a head.

    The last few days it's been legal mayhem on his blog, posting the various letters and emails he's been getting and sending to MS lawyer-types. What really peeves me the most is the clause in the EULA that they are griping over:

    "...you may use the software only as expressly permitted in this agreement. In doing so you must comply with any technical limitations in the software that only allow you to use it certain ways... You may not work around any technical limitations in the software."

    What a load of crap. I'm sorry but let me rattle off two very big tools from Microsoft that voilate this EULA: Popfly Explorer and XNA Game Studio. Both are "add-ons" that *only* work with the Visual Studio Express SKU.

    Since when does building a tool that simply automates running a unit test runner constitute working around a technical limitation? Is the technical limitation that VSExpress doesn't have support for unit test frameworks. If that's true, then any macro that shells out and runs nunit-console.exe could be considered in volation. If they're willing to stretch TestDriven.NET to fall into this category, then I call foul on Popfly Explorer and XNA Game Studio. They are "manipulating" how Visual Studio Express works and there's obviously a technical limitation in that Visual Studio Express, OOTB, does not support the XNA content pipeline or understand Popfly so again, someone is in voilation here.

    Unfortunately for Jamie, he's between a rock and a hard place. EULA are just that. Agreements. IANAL but from what I know of past issues concerning EULAs, they're not legally binding. However with the Microsoft Man behind this nobody is going to be able to stand up (legally) against them.

    So is Microsoft going to sue themselves? Might as well, since the lawyers are already doing a damn fine job at making an ass out of themselves.

    My advice for Jamie, 1) pull the support for the Express SKU (again) if that will appease the Blue Monster and 2) contact the EFF. They have a good track record in these type of things and might be able to support you. I know I will so just yell if you need me.

  • ScrewTurn Wiki

    Kind of a crazy name for a piece of software (in this politically correct world, the use of "screw" doesn't go over very well with some management) but a really great example of Open Source in action.

    I was hunting around for a wiki for our development documentation and standards. My first thought was SharePoint but we're not rolled out yet to 2007 and I didn't want to bank on that yet. I wasn't quite sure what I was looking for, but needed a wiki that did basic features and had a few "must-have" features (like AD integration and content approval). A great site for checking out and comparing wikis is WikiMatrix. This site lets you compare *all* of the wiki software packages out there and even includes a wizard to step you through what you're looking for (OSS, platform, history, etc.) and gives you a nice side-by-side comparison page (much like comparing cars) to help you select a package.

    First I took a look at FlexWiki which was fairly popular and easy to setup. I had set it up on my laptop before as I was toying around with using a wiki as my home page. FlexWiki was simple and more importantly (for me anyways) it was C# and windows based so if I wanted to extend it, play around, write extensions, etc. then that would be bonus. Flex is nice and if you don't look at anything else, probably suites the purpose (although CSS-style customization seems to be pretty complex). While I was leaning towards C# type wikis, I knew that the best and most mature ones were PHP/MySQL based (like the one Wikipedia runs on, MediaWiki). However I just didn't want to introduce another stack of technology at my client just for the purpose of documentation.

    Finally I stumbled across ScrewTurn Wiki. Like Flex, it was easy to setup and like my favorite blogging software (dasBlog) it could be file based so you could just set it up and go. I installed ScrewTurn and messed around with it and it worked well. We handed the duties of really digging into it over to a co-op student we have for the summer and he's really gone to town with it. AD integration was added (it was always there, I just didn't enable it) and he's found some plugins and even written some code to extend it. What's very cool about ScrewTurn is that the common pages are written in C# and live as .cs files on your server. You just edit them and override methods, introduce new ones, whatever. New functionality without having to recompile assemblies or anything (everything is just JIT'd on the fly).

    Anyways, ScrewTurn looks like a very good IIS based wiki if that's your thing. I find it more mature than Flex, written in C# 2.0 and has a lot of great features. Like I said, if you have a LAMP environment in your world then you might want to look at something like MediaWiki but for a Microsoft world, ScrewTurn is da bomb. The plugin support is great and I'm hoping that the community will step up and build new plugins for the system so it can grow into something special.

    So you might want to give ScrewTurn a try if you're looking for a simple documentation system for your team.

  • ReSharper 3.0 Beta Available

    Great stuff from the guys that make the cool tools, JetBrains anounces the release of their latest beta version of ReSharper 3.0.

    This release includes refactoring for C# and Visual Basic.NET now. The C# side has been beefed up so it gives you some code suggestions that you may or may not choose to implement. Also with this release is XML and XAML support (handy when working with Silverlight now), a neat feature called "Go to Symbol" navigation which I'm prefering over "Go to Declaration", a smart TODO list, and a reworked Unit Test Runner (although I still prefer TestDriven.NET).

    You can grab the beta from here. I'll see if I can find some time and put together some screenshots or (gasp) a webcast on the features as talking about them is rather boring. Enjoy!

  • Efficiency vs. Effectiveness, the CAB debate continues

    There's been two great posts on the CAB debate recently that were interesting. Jeremy Miller had an excellent post over the brouhaha, citing that he really isn't going to be building a better CAB but supports the new project we recently launched, SCSFContrib. I think Jeremy's excellent "Roll your own CAB" series is good, but you need to take it in context and not look at it as "how to replace CAB" but rather "how to learn what it takes to build CAB". Chris Holmes posted a response called Tools Are Not Evil from Oren's blog entry about CAB and EJB (in response to Glenn Block's enty, yeah you really do need a roadmap to follow this series of blog posts).

    Oren's response to Chris Holmes post got me to write this entry. In it he made a statement that bugged me:

    "you require SCSF to be effective with CAB"

    Since this morning, it looks like he might have updated the entry saying he stands corrected on that statement but I wanted to highlight the difference between being efficient with a tool, and being effective with the technology the tool is supporting.

    Long before SCSF appeared, I was groking CAB as I wanted to see if it was useful for my application or not and what it was all about. That took some time (as any new API does) and there were some concepts that were alien but after some pain and suffering I got through it. Then SCSF came along and it enabled me to be more efficient with CAB in that I no longer had to write my own controller, or implement an MVP pattern myself. This could be done by running a single recipe. Event the entire solution could be started for me with a short wizard, saving me a few hours I would have taken otherwise. Did it create things I don't need? Probably. There are a lot of services there that I simply don't use however I'm not stoked about it and ignore them (sometimes just deleteting them from the project afterwards).

    The point is that SCSF made me more efficient in how I could leveage CAB, just like ReSharper makes me a more efficient developer when I do refactorings. Does it teach me why I need to extract an interface from a class? No, but it does it in less time than it would take manually. When I mentor people on refactoring, I teach them why we do the refactoring  (using the old school manual approach, going step by step much like how the refactorings are documented in Martin Fowlers book). We talk about why we do it and what we're doing each step of the way. After doing a few this way, they're comfortable with what they're doing then we yank out ReSharper and accomplish 10 minutes of coding in 10 seconds and a few keystrokes. Had the person not known why they're doing the refactoring (and what it is) just right-clicking and selecting Refactor from the menu would mean nothing.

    ReSharper (and other tools) make me a more efficient developer, but you still need to know the what and why behind the scenes in order to use the tools. I compare it to race car driving. You can give someone the best car on the planet, but if they just floor it they'll burn the engine out and any good driver worth his salt in any vehicle could drive circles around you. Same as development. I can code circles around guys that use wizards when they don't know what the wizard produces or why. Knowing what is happening behind the scenes and the reason behind it, makes using tools like ReSharper that much more value-added.

    SCSF does for CAB what ReSharper does for C# in my world and I'll take anyone that knows what they're doing over guys with a big toolbox and no clue why they're using them anyday.

     

  • Whoever Has the Most Toys, Wins

    Or do they? In the past couple of years, Google, Microsoft, and Yahoo have been buying up little niche products and technologies and absorbing them into their collectives like mad little scientists working in a lab. It reads like a whos-who of the IT world.

    Google

    Feedburner - Very recent purchase and something many of us bloggers use. Good move Google!
    Blogger - Awesome concept but I think it went by the wayside as Blogger became the MySpace for blogger-wanna-bes. Still some good bloggers use it, but I don't think it's panned out the way Google wanted it to.
    Picasa - Neat desktop app that I tried out a few times and well done. Hopefully they'll do something with this in the near future.
    Youtube - Biggest acquisition that I know of (who has this much money besides Microsoft?) but with thousands of videos being pulled every day by Viacom or someone else threatening to sue, I wonder what the future holds.
    DoubleClick - Have no idea what this is all about as DoubleClick is the evil of the Internet. Maybe they bought it to kill it off (doubt it).

    Yahoo

    Flickr - Probably the best photo site out there, many new features being added all the time and nobody nearly as interesting as these guys out there in this space.
    Konfabulator - Never really caught on and too many people compared it to the Mac desktop (which already had this capability OOTB). Windows Gadgets tries to be like this but again not a huge community swelling up around this.
    del.icio.us - Next to Flickr, one of the best buys for Yahoo and the best social bookmarking system out there.

    Microsoft

    Connectix - Huge boost in the virtual space, although I think it still trails behind VMWare
    Groove - What put Ray Ozzie on the map is now part of Office 2007 and still growing.
    Winternals - Best move MS made in a long time, awesome tools from these guys who know the inner workings of Windows better than Microsoft in some cases
    FolderShare - Great peer-to-peer file sharing system, but hasn't really taken off has it?

    There's a bunch more but I didn't want to get too obscure here. There's a very cool graph here that will show you the acquisitions and timelines.

    Who's Left?

    And here's the hot ticket items these days that are still blowing in the wind. It's anyone's guess who goes up on the block next and who walks away with the prize.

    Facebook - Whoever gets this gets gold at 100,000 new members a day (!). My money is on MS to pull out the checkbook any day now.
    Digg - Kevin Rose, who's already probably laughing his way to the bank will cash in big time on this if someone grabs it. Maybe Google to offset the Yahoo del.icio.us purchase?
    Slashdot - Yeah, like anyone would want this except to hear Cowboy Neal talk about himself (don't worry, Slashdotters don't read my blog - I hope)

    Any others?
    (SharePointKicks... yeah I wish)

    Maybe it's a good, maybe it's bad, my question is who will end up with the most toys? Or maybe once all the little ducks are bought up the three top dogs will duke it out with one winner walking away. UFC at the Enterprise level kids. Should be a fun match.