CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Karl Seguin

.NET From Ottawa, Ontario - http://twitter.com/karlseguin/

July 2006 - Posts

  • Old news? MSDN does wiki?!

    Someone vindicate me and say "wow, I didn't know about this either"...but...

    Somehow I missed the news that MSDN had gone wiki - or atleast a version of it was wikicized. You can see the site at http://msdnwiki.microsoft.com. I happen to be looking up FxCop documentation today and ended up there. I've submit bugs/comments to the FxCop team before - and they've always been very quick to reply - but obviously a wiki's the way to go.

    I also found a blog entry from Mike Pope whotook issue with my view of the coverage HttpHandlers get from tech writers. Fair enough. What's cool is that he added my point of view to MSDN Wiki's section on HttpHandlers. Thanks!

    I seriously intend to contribute to this project!

  • Being Explicit

    Do custom "flexible" solutions ever drive me crazy. Most of them amount to meta-based repositories (key => value), heavy use of "object" and datasets and impossible to maintain code.

    The masterminds behind these systems are often senior "architects".  In my experience though, the simplest solution is generally the most flexible. I'm a big fan of YAGNI (You Aren't Gonna Need It) and straightforward designs.

    Years ago, Martin Fowler wrote a paper called  "To Be Explicit" which I've always kept close at hand - especially when fighting with one of those so-called architects. I happen to open it up again today, and figured I'd share  this little 15 pages of goodness with anyone not familiar with it.

    (Ironically, I believe that a lot of Martin Fowler's work promotes highly implicit code - especially some of his analysis patterns (I said analysis, not design). Of course, if you read what he says about some of those patterns, you'll see that he cautions you to be very careful about their use - and make sure that you actually need to use them. Hard to fault him for all the in-the-sky architects out there).
  • weblogs.asp.net

    At the risk of embarrassing myself, what's up with weblogs.asp.net? Ever since the delayed upgrade to CommunityServer, a number of bloggers have been turning off anonymous comments (a mistake as far as I'm concerned, meh, their blog their business). What I can't figure out is how to log-in or register to leave a comment!

    Take this new post from Jeff (which I'm just taking 'cuz it was the first on the list that requires a login). If you aren't logged in, all you'll see @ the bottom is:

    "Comments

    No Comments
    Anonymous comments are disabled"

    But there's no link to login or register - anywhere on the page. The weblogs.asp.net homepage itself doesn't have a link to register or login - which strikes me as odd given how ginormous the header is.

    I'm missing something, right?

    On a slightly related topic. David Burke thinks Community Server is open source. But Phillip Haack is right in saying that it isn't. It seems to come down to a matter of definition, with David using his own, and Phillip using the OSIs. In fairness to Telligent, I couldn't find anywhere on their site that claims that CommunityServer is "Open Source".

    P.S. - I'm blogging this from writely.com , we'll see how it works. HAHAH.. Sorry Jeffrey, it showed up under your blog..trying again.


  • Programming is too easy

    Another day, another coding horror. *sigh* not how I wanted to start off this week. At least the problem isn't technical, but rather an embarrassing misunderstanding of a business rule – and of course the system's in production. It could be the client's fault for not being clear in the first place, but that really doesn't matter. It's frustrating, a programmers happiness is directly tied to the quality of the code he or she produces – end of story!

    Jeffrey Palermo talked about this very same thing not too long ago, and all of his points were bang on. He's particularly right about how easy tools make it to get something, anything, out the door. There are a lot of parties responsible for the current state we find ourselves in. Schools quickly come to mind: be it I.T. condensed courses or Universities. Joel went on and on and on (and on and on) about how important knowing C is for new grads, and I agree. Of course, individuals are to blame too. How many developers got into it for the money instead of actually loving it? Your misery is well deserved. How many refuse to learn from their mistakes?

    As easy as it is to blame schools or even individuals, I put almost all the blame on lazy and underskilled managers and HR departments. Managers (or leads, or whoever does the hiring) need to know what they are looking for as well as how to find it. If you want a junior programmer, make sure you have the right team/person in place to properly mentor him or her. Jeffrey talks about the Apprentice/Journeyman/Master relationship (they are called Artisan's in WoW) and in my experience it's a vastly underused concept in software development.

    I'm sure money plays a big part in all of this, but I'm reminded of a great book called Peopleware by Tom Demarco and Timothy Lister. There's pretty strong evidence that the best programmers outperform the worst programmers by a factor of 10. I used to think that there was no way one developer could outperform another one by a factor of 10. I now have no doubt of it when you take into account the total cost of a project. Back to the figures, it means that if you're starting salary for a new grad is 40K (doesn't necessarily mean they are the worst), you've got a steal on your hands paying 100K for an actual no-BS senior guru. I don't know about everyone else, but 100K for a non-consultant in Ottawa isn't going to happen. Instead, what you end up seeing are lazy HR departments flatten out salaries and lump them into a few categories (or maybe just 1: “Programmer”). All this isn't to say that you shouldn't hire new grads. You might end up paying a little more for what you get in the short run, but in the long run the investment will be worth it.

    I will go off a little and point out that Microsoft doesn't make it very easy to determine a developer's skill. I'm specifically talking about their certification program. Maybe it makes sense for I.T. professionals (you know, network people, help desk, cicsco/active directory/novell…), but when it comes to software developers, the MCP/MCAD/MCSD are total failures. Microsoft needs to cancel the MCP/MCAD/MCSD program for developers. I took an MCP test, thinking that I would get my MCSD. It was a joke of jokes – 20 minutes of my time, answering superficial questions. A LOT of the questions actually asked for answers or gave examples that promoted BAD practices. Worse, it's extremely easy to cheat on these exams. If you see a job description asking for MCAD/MCSD certified people, DON'T APPLY – unless you absolutely have to. It's a tell-tell sign of a shop that doesn't know HOW to look for people. Even if you are the right person, you'll be working with, or replacing someone who isn't.

    Thanks for letting me fume a bit :)
  • Integrated Source Control and Bug Tracking

    Even though Rational's suite of products is my second most hated piece of sotfware ever, it did introduce me to tightly integrated source control and bug tracking. Basically any changes you do to your source code needs to be associated with a bug/feature already logged into your bug tracker. Normally this is done at checkin or checkout.

    For a lot of teams, the process is probably too heavy handed/bureaucratic, but most systems allow some flexibility in configuration. The benefit is absolute accountability (which is always good) and better tracking. It can also help managers manage their resources and time, and developers work better as a team (you can see exactly which changes Brian made to the source before reassigning it to you).

    Now, I'm a pretty big fan of SourceGear's Vault as a source control tool. It's a product that should fit in well almost anywhere (it's more than affordable, but still rock solid). Frankly, all it's missing is something ala TortoiseCVS. Anyways, the best part about Vault is it's integration with bug trackers. SourceGears sells its own web-based bug tracker, Dragnet, which I've heard mixed reviews about (it's pretty basic). Vault also integrates with FogBugz (or maybe FogBugz integrates with Vault, I'm not sure), which is one of the more popular bug trackers out there. A last note about all of SourceGear's product - they are free for a single license.

    Whatever tool you are using, do explore the possibility of integrating your bug tracking and source control.

    P.S. - In case anyone's wondering, Tribes 2 is #1 on my list - I'm a bitter man.
  • Captcha Control

    I dug something else up while doing some cleaning : a captcha control. The core functionality is taken from this codeproject article. I've gone ahead and wrapped it in a custom server control as well as taking advantage of HttpHandlers.

    This was actually incorporated into a bigger library, so I had to rework some stuff to make it more stand-alonish. I also noticed that I could have exposed more properties to make it more flexible - oh well.

    Since it makes use of HttpHandlers and custom server controls, I think it really highlights some of the best tools ASP.NET offers when it comes to reuse. Sure it might seem like a lot of code, but it's contained set of code which is ready to be reused in any projects - write once, reuse often. (That said, I'm not actually including a .dll file (just the source), because I don't want to give anyone the impression that it's a solid 3rd party control.)

    To set it up, add the 4 .cs files to your App_Code folder (or a separate project). Add these line to your web.config's system.web element:
    <httpHandlers>
      <add type="Fuel.Web.CaptchaHandler, App_Code" verb="GET" path="captcha.ashx" />
     </httpHandlers>

    And then Register the namespace:
    <%@ Register Assembly="App_Code" Namespace="Fuel.Web" TagName="Fuel" %>

    All you need to do then is use the control:
    <Fuel:Captcha runat="Server" />

    If you aren't using 2.0, or aren't placing these in your App_Code folder, simply replace "App_Code" with the name of the .dll it'll get compiled to.

    Finally, if you are using 2.0, don't forget that you can register controls site-wide now via:
    <pages>
          <controls>
            <add assembly="App_Code" namespace="Fuel.Web" tagPrefix="Fuel"/>
          </controls>
    </pages>


    in system.web of the web.config

    Download it here


  • Access 2007 - Worth installing to see how bad it is

    So I double click on an access file a client sent over, and realize it's my first time loading up Access 2007. Whereas the tabbed-menu system of Word is pretty quick to get accustomed to, it's just a pain to work with in Access. Maybe Access 2007 has a lot of great features, but I didn't stick around to discover them - after 20 minutes of gettnig frustrated, I dumped the two tables into SQL Server.

    I know it's a beta. I know Office 2007 beta needs a lot of work (Outlook is crashing more and more -I hope those reports I'm sending in our helping). But Access 2007 is a disaster waiting to happen - I'm glad I rarely have to use it.


  • TDD Lesson 3 - Teasing the data layer...

    Sooner or later during your TDD experimentation, you'll start to creep up against your data layer. I wouldn't be surprised if a lot of new TDD'ers find themselves brushing up against their database sooner than they ought to. I know I did, but try and put it off as I might, I knew it was something I had to start tackling.

    Basically, all I want is to be able to pull out all Indicators from my store. Something like a static Indicator.GetAllIndicators() would do nicely (I realize some would prefer to have that off in it's own class). So I write my first test:

    [Test]
    public void GetAllIndicatorsDoesntReturnNullWhenEmpty()
    {
       Assert.IsNotNull(Indicator.GetAllIndicators());
    }


    My build breaks. I fix it by adding the static method to my Indicator class:

    public static List<Indicator> GetAllIndicators()
    {
      return null;
    }


    My test is breaking, and the easiest way to make it pass is to simply do:

    return new List<Indicator>();

    The above test is nice because it ensures that the consumer won't have to worry about nulls (I might need to add a few more tests to guarantee that). Let's face it though, what I'm really after is making sure GetAllIndicators() works well with my data access layer! So I'm going to take a big step - maybe too big, but it's what I think is necessary:

    [Test]
    public void CanGetAllIndicators()
    {
       AddIndicator("Test Name 1");
       AddIndicator("Test Name 2");

       List<Indicator> results = Indicator.GetAllIndicators();
       Assert.AreEqual(2, results.Count);
       Assert.AreEqual("Test Name 1", results[0].Name);
    }


    private void AddIndicator(string name)
    {
     
    //todo
    }


    Ok, so my test fails, and I have a lot of work ahead of me (relative to what I've had to do so far) to get it working. I still think I'm taking on more than I should - but once I get this infrastructure set up, it'll be easier to do other similar test. (Not only do I feel like I'm taking too big a step, but I also feel like I'm jumping into infrastructure way too early, still, I see real value here!) First though, I realize that my 2nd assert is wrong. I don't have a requirement for a first-in first-out, I'll probably have a different default ordering, so I just take it out and do something like:

    [Test, Ignore]
    public void GettingAllIndicatorsIsInCorrectOrder()
    {
    }


    Back to the main test. I'll be using a simple DataProvider class that follows the much overhyped provider pattern. I want to do something like DataProvider.Instance.GetAllIndicators(). So I change my Indicator.GetAllIndicator() code to do just that:

    public static List<Indicator> GetAllIndicators()
    {
      DataProvider.Instance.GetAllIndicators();
    }


    I'm back with a broken build. I create an abstract DataProvider class, add an Instance property and declare an abstract GetAllIndicators function. Here's what it might look like:

    internal abstract class
    DataProvider
    {
       private DataProvider _instance;
       public DataProvider
       {
          get { return _instance; }
       }

       internal abstract List<Indicator> GetAllIndicators();
    }


    So the real gem here, as far as I'm concerned, is that I don't have to build a SqlDataProvider class yet. I can simply build a TestDataProvider class, put a minimal amount of effort to get it up and running and focus again on my domain:

    internal class TestDatarovider : DataProvider
    {
       private List<Indicator> _indicators = new List<Indicator>();
       internal override List<Indicator> GetAllIndicators()
       {
          return _indicators;
       }
    }


    Things are starting to come together, but there are two really important things I still need to do in order to get a test that'll pass. First, I need to be able to add indicators, second I need to get the DataProvider to return an instance of TestDataProvider. At first I was tempted to simply create a new abstract method "AddIndicator" to my DataProvider and implement it. Problem is, this system doesn't take care of adding indicators, it only reads them, and I'm not a fan of burdening my entire system just for the sake of being able to test properly. My solution is to add the AddIndicator method directly into my TestDataProvider, not the base DataProvider class:

    internal void AddIndicator(Indicator indicator)
    {
       _indicators.Add(indicator);
    }


    Now, to inject my DataProvider with my TestDataProvider, I expose a simple function to overwrite _instance:

    internal static void OverwriteInstance(DataProvider newInstance)
    {
       _instance = newInstance;
    }


    I can now create a Setup method in my test:

    private TestDataProvider _dataProvider;
    [SetUp]
    public void FixtureSetup()
    {
       _dataProvider = new TestDataProvider();
       DataProvider.OverwriteInstance(_dataProvider);         
    }


    This not only ensures that DataProvider.Instance always returns a TestDataProvider, but also makes sure that each tests runs in a clean environment (a new instance of TestDataProvider is created for each test). Finally, coding my AddIndicator helper method and running my test gives me a pass:

    private void
    AddIndicator(string name)
    {
      _dataProvider.AddIndicator(new Indicator(name));
    }

    To recap:
    • We used the provider pattern so that we can easily inject a stub
    • We've created a stub of our data access layer so that we can continue to focus on our domain
    • We had to create extra functionality (adding an indicator), but kept that isolated in our test classes
    Technorati Tags: , ,


    Posted Jul 05 2006, 01:34 PM by karl with 6 comment(s)
    Filed under:
  • Javascript Management with ASP.NET

    Over the weekend, I dug up an ASP.NET article I wrote a while ago and never put up anywhere. It was actually meant as a practical example of using HttpHandlers - which I've talked about before.

    Basically, the idea is to store of JavaScript into a store (I use XML). Have the JavaScript grouped up into like functionality, such as "Tabbing", "BrowserDetection", "MouseOver", etc. The a page developer simply says, "I need Tabbing on this page", ala JavaScript.EmitJavascript(JavascriptType.Tabbing, JavascriptType.BrowserDetection);

    What's really cool about the article is that is uses Dean Edward's Javascript packer. So blocks of JavaScript are obfuscated on the fly (and cached). That means that in development you're dealing with easy-to-read JavaScript, but in production it's compact code.

    For example, if you put the HUGE atlas.js (239Kb) file through it, it'll come out at just about 1/2 the size (roughly 123kb). That's insane!

    You can read the article here.

    Technorati Tags: ,




More Posts

Our Sponsors

Proudly Partnered With