logo
  • Jobs
  • About Me
  • Contact
  • Home

Archive for October, 2004

Congratulations, Boston

Congratulations to the Boston RedSox who have finally broken the “curse of the Bambino“. While Im not a RedSox fan (go Dodger Blue), I gotta say that starting in the ninth inning of game 4 of the ALCS , they were completely dominating.

They have been bringing their A game every single night and it shows. To come back from 0-3 to beat the Yankees, and then sweep the St Louis Cardinals is incredibly impressive. They so dominated the Cardinals that the Cardinals never even had a lead at any point in the World Series… Stunning…

The toughness and determination shown by the RedSox team is something for the ages. Curt Schilling could hardly walk for game 6 of the ALCS (due to a ruptured tendon in his ankle) and was out on the mound bleeding through his sock to pitch the ball for his team. For game 2 of the World Series, he had deep tissue stitches. The morning of game 2, he could not walk because of a damaged nerve. Doctors were able to get him stitched up in time to throw the ball that night. Keep in mind that they stitched things in the *wrong* place, intentionally. Once he was done, he went in and had the stitches removed, only to have to look forward to off-season surgery. Schilling’s performance in this postseason is easily the grittiest performance I have seen in sport. Ever.

As I close this post, I do hope that Boston fans remember their sanity tonight in their celebrations. Please be safe…

No Comments

ASP.NET pluggable module implementation

For an ASP.NET project that I’ve been working on for quite a while, we wanted to have a pluggable module type of page architecture. We would have one main page (default.aspx) which would have a panel control which could get different controls loaded into it.

The way that we originally implemented this was to have a base control that all of our ASCX files would derive from. As detailed in a previous post, creating base classes is something I always do when creating a new project.

public class ControlBase : Control
{
    public SessionManager SessionManager
    {
        return SessionManager.Instance;
    }
}

Now, in our original implementation, we added all the modules to the web.config file.

<modules>
    <add key="myModule" value="~/path/to/myModule.ascx" />
</modules>

Modules were then loaded in the main page class like this:

protected override void OnInit(EventArgs e)
{
    base.OnInit();
 
    Hashtable modules = ConfigurationSettings.GetConfig("modules");
    ControlBase ctl = Page.LoadControl((string)modules[Request.QueryString["module"]]);
    myContainerPanel.Controls.Add(ctl);
}

The more I worked with this and added new controls into our framework, the more disgruntled I became with it. It always seemed like there was more to adding a new control that really should be there. I also had tied a dependency to using ASCX files for my controls, which I didnt really care for either. There are some wierd cases where you may want to have code completely render a control.

Because of this, I started to think about ways that I could improve this idea. Design patterns to the rescue…

The idea would be that a class would be responsible for creating the control, rather than the OnInit method of the page. This led to the realization that I would have some common interface to key and create a control.

public interface IControlFactory
{
    string Name { get; }
    ControlBase CreateControl();
}

Now, my derived controls have a code structure that looks something like this:

public class MyControl : ControlBase
{
    class Factory : IControlFactory
    {
        public Name { get { return "MyControl"; } }
        public ControlBase CreateControl()
        {
            Page page = (Page)HttpContext.Current.Handler;
            return (ControlBase)page.LoadControl("~/path/to/myControl.ascx");
 
            // note that this works with ascx files, but we could just as easily
            // do return new MyControl(); if our control is completely rendered with code.
        }
    }
 
    // rest of MyControl class goes here
}

The missing component now is a class that tracks these IControlFactory implementations and returns the appropriate instance based on a passed in key. Introducing the WebControlFactory class…

class WebControlFactory
{
    private static Hashtable factories;
 
    private WebControlFactory()
    {
    }
 
    public static void Register()
    {
        factories = new Hashtable();
        foreach(string file in Directory.GetFiles(HttpContext.Current.Server.MapPath("~/bin"), "*.dll"))
        {
            try
            {
                FileInfo fileInfo = new FileInfo(file);
                string assemblyPath = fileInfo.Name.Replace(fileInfo.Extension, "");
                Assembly asm = AppDomain.CurrentDomain.Load(assemblyPath);
 
                foreach(Type t in asm.GetTypes())
                {
                    if(!t.IsInterface &amp;&amp; !t.IsAbstract &amp;&amp; typeof(IControlFactory).IsAssignableFrom(t))
                    {
                        try
                        {
                            IControlFactory controlFactory = (IControlFactory)Activator.CreateInstance(t);
                            factories.Add(controlFactory.Name, controlFactory);
                        }
                        catch (Exception e)
                        {
                            Trace.WriteLine("Exception encountered loading type '" + t.FullName +  "': " + e.ToString());
                            // this is deliberately ignored, as any error in loading the type should just involve
                            // continuing on
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Trace.WriteLine("Exception encountered loading control: " + e.ToString());
                // this is deliberately ignored, as any error in loading the assembly should just involve
                // continuing on
            }
        }
    }
 
    public static ControlBase CreateWebControl(string name)
    {
        if (factories.ContainsKey(name))
        {
            IControlFactory factory = (IControlFactory)factories[name];
            return factory.CreateControl();
        }
 
        throw new InvalidOperationException("No factory registered to handle '" + name + "' controls.");
    }
}

Now, the final steps to implement this new method would be to add a call to WebControlFactory.Register() to the Application_Start method in Global.asax. The register method is responsible for scanning any assemblies in the bin folder, scanning their types for IControlFactory implementations, and adding them to a hashtable if they do.

The second thing to do here is to modify our OnInit method to take advantage of this new class:

protected override void OnInit(EventArgs e)
{
    base.OnInit();
 
    ControlBase ctl = WebControlFactory.CreateWebControl(Request.QueryString["module"]);
    myContainerPanel.Controls.Add(ctl);
}

This has solved my problems with the original implementation. I no longer am limited to ascx files for controls, and I also dont have to jump through the hoops of adding new modules to the web.config file. Using this object model, I am able to create web controls in a separate assembly, drop them in the bin folder and go.

I understand that this technique will be obsoleted by VS.NET 2005 and master pages, but for now, I think this is an elegant technique and I hope you find some value from it…

5 Comments

Edit and Continue in C# 2.0

I’m sure that by now everyone has heard that Edit and Continue will be a part of Visual C# 2005. It’s taken me a while to get my thoughts in order regarding this major announcement.

First off, let me say that I’m really pleased that Microsoft is listening to its user base and implementing features that they are asking for.

Given that, I want to go on record as saying that Edit and Continue is one of the worst things to happen to programming. Ever.

In my experience, I’ve noticed when handling a bug, the first thing that most people do is load up the project, hit F5, and off they go. Why not execute the program, find where the bug occurs, take a look at the error message and *think*. Think about what might be causing the issue. This can be a lot quicker than single stepping through 200 lines of code.

Now, I’ve heard the arguments from people that say that edit and continue is a godsend for those quick typos, incorrect connection strings, etc. The way I look at it, users have been asking for three things from Whidbey (in no particular order): refactoring, edit and continue, and unit testing. I believe that E&C would be unnecessary if more effort was placed on the other two items. You dont need to modify running code, if you have a effective unit tests. The unit tests should have caught these typos. The tests that fail should be so isolated that there is no question of where the error is occuring. This means that you can go to the source of the problem, and fix it… without ever running your program in debug mode.

Lastly, another drawback to E&C is that it can be quickly used to fix something. However, I personally believe that it also leads to band-aid programming. Patching something quickly to make it work, rather than looking at the root cause of the problem. This is bad, and just leads to more issues down the road.

Edit and continue is just a quick way to hack and bang on something to make it work, without investigating the root cause of the problem, and I personally wish that MS would give refactoring and unit testing the time that is now being taken up by edit and continue.

Of course, thats just my opinion. I could be wrong…

No Comments

Steve Ambron

I got a note today from a very good friend of mine. Steve and I have known each other for almost 14 years now. Several years back, Steve joined the Army and last November, he got called on by our country to serve in Iraq. He spent almost a year over there in the desert in conditions I cant even begin to imagine.

His note today let me know that he was home at last, decompressing and spending time with his wife.

I’ve repeatedly expressed my gratitude to Steve for doing what he does. We have the freedoms that we do because people like Steve stand up to protect our country. Regardless of your politics, I think everyone should thank a soldier for the sacrifices made on our behalf.

Thank you, Steve. You’re my hero.

No Comments

VM Goodness

Virtual PC 2004 Service Pack 1 is finally available for download. Also available today from MSDN subscriber downloads is Virtual Server 2005.

Hopefully, this resolves my problems with XP SP2 on my VPC images. I’m also looking forward to working with Virtual Server 2005 and the Yukon betas.

Enjoy!

No Comments

Goodbye, Superman

By now, most of you have heard that Christopher Reeve passed away yesterday at the age of 52. There is something to say about Reeve’s optimism and steely determination to walk again after his tragedy. This was a story that should have ended differently.

Rest in peace, Superman…

No Comments

ASP.NET Security Vulnerability

A lot of discussion has been going on in the blogsphere over the last few days regarding a severe security vulnerability in ASP.NET. This vulnerability is present in all versions of IIS.

What You Should Know About a Reported Vulnerability in Microsoft ASP.NET
This page was updated October 7, 2004, to include information about a newly released mitigation option, an HTTP module installer. This module protects all ASP.NET applications on a Web server against canonicalization problems that are currently known to Microsoft as of the publication date. We will continue to update this page as additional guidance and resources become available.

Microsoft has also released an ASP.NET ValidatePath Module that web administrators can apply to their web server. This will protect all ASP.NET applications against all canonicalization problems known to Microsoft.

Make sure you get your systems patched, people…

No Comments

DateTime and Quarters

This has been driving me absolutely up the wall. I’m trying to calculate the fiscal year quarter for a specific date…

I can get the calendar quarter using this formula…

quarter = (month + 2) / 3

Quarter 1 : 07.01 – 09.30
Quarter 2 : 10.01 – 12.31
Quarter 3 : 01.01 – 03.31
Quarter 4 : 04.01 – 06.30

Your mission, should you choose to accept it, is to write a formula that gets the correct quarter based on the table above. I want a pure formula, no if/else conditions…

*The prize:* I’ve got a GMail invite for the first one to post a working formula for this problem. Make sure that you leave an email address so that I can send you the GMail invite. Your email address is never shared, nor published on the website.

A hint: (((calendarQuarter + 2) % 4) + 1) works if the FY starts in April.

*Update:* A coworker emailed me privately with the solution to this problem.

public static void Main(string[] args)
{
    for (int month = 1; month <= 12; month++)
    {
        Console.WriteLine("Month {0} is in fiscal quarter {1}", month, GetQuarter(month));
    }
}
 
private static int GetQuarter(int month)
{
    int calendarQuarter = (month + 2) / 3;
    float f = 2.5f - (float)calendarQuarter;
 
    return calendarQuarter + ((int)(f / Math.Abs(f)) * 2);
}

Thanks, Eric…

No Comments
flag
Favorite Charity
wounded warrior project
Search
Social
  • mattberther on twitter
  • mattberther on linkedin
Syndication
Archives
  • January 2010
  • September 2009
  • July 2009
  • June 2009
  • February 2009
  • January 2009
  • December 2008
  • November 2008
  • September 2008
  • August 2008
  • June 2008
  • May 2008
  • April 2008
  • March 2008
  • February 2008
  • January 2008
  • December 2007
  • November 2007
  • October 2007
  • September 2007
  • August 2007
  • July 2007
  • June 2007
  • May 2007
  • April 2007
  • March 2007
  • February 2007
  • January 2007
  • December 2006
  • November 2006
  • October 2006
  • September 2006
  • August 2006
  • July 2006
  • June 2006
  • May 2006
  • April 2006
  • March 2006
  • February 2006
  • January 2006
  • December 2005
  • November 2005
  • October 2005
  • September 2005
  • August 2005
  • July 2005
  • June 2005
  • May 2005
  • April 2005
  • March 2005
  • February 2005
  • January 2005
  • December 2004
  • November 2004
  • October 2004
  • September 2004
  • August 2004
  • July 2004
  • June 2004
  • May 2004
  • April 2004
  • March 2004
  • February 2004
  • January 2004
  • December 2003
  • November 2003
  • October 2003
  • September 2003
  • August 2003
  • July 2003
  • June 2003
  • May 2003
  • April 2003
  • March 2003
mattberther.com © 2003 - 2010