ILMerge + Castle + Log4Net

At work we have recently merged the various Castle assemblies into one with ILMerge. It has worked great, but we found one gotcha with the Log4Net facility. Castle’s LoggingFacility class defines class types of various logging factories as static strings, which aren’t picked up by ILMerge.

The solution has two parts:
1. Use the CustomLoggerFactory config parameter:

<facility id="LoggingFacility" loggingApi="Custom" customLoggerFactory="Castle.Services.Logging.Log4netIntegration.Log4netFactory, <Your Merged Assembly>" type="Castle.Facilities.Logging.LoggingFacility, <Your Merged Assembly>" />

2. Place your actual logging configuration into a file called “log4net.config” and place that file in the same folder as the file that contains the above facility definition.

Sources: Castle-Project-Users mailing list and Castle Monorail docs.

I'm a winner!

I won a license to Telerik’s premium collection last night at my local .NET user group meeting. I’m incredibly excited to start playing with their controls — right now WinForms and reporting are of most interest to me, but I can see myself branching out into WPF soon.

I don’t have any Windows-based hosting available to me at the moment, so the ASP.NET controls will just have to wait. It’s just as well. I’m sure the rest will keep me busy for quite a while.

Extension methods in .NET 2.0

Due to the nature of our client base, we still target .NET 2.0 at work. The side-effect being, of course, the inability to use the latest and greatest and sexiest of what C# has to offer these days.

I was setting out to write some static helper methods this morning, and on a lark decided to Google for extension method support. Sometimes the compiler is nice enough to take 3.0 features (such as the var keyword) and translate them into code that’s palatable for .NET 2.0.

Truly, ask and ye shall receive! Success! While in newer versions of the framework, you’d import System.Core.dll to add extension support, all that’s really needed is the definition of the ExtensionAttribute class. This can be added anywhere in your code that targets .NET 2.0:

namespace System.Runtime.CompilerServices
{
    public sealed class ExtensionAttribute : Attribute { }
}

Extensions work like a charm after that.

XamlParseException during application startup

If a WPF application encounters any problems during the creation of the main window, you will be presented with a rather useless System.Windows.Markup.XamlParseException:

“Cannot create instance of ‘Window1’ defined in assembly ‘YourAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’. Exception has been thrown by the target of an invocation. Error in markup file ‘Window1.xaml’ Line 1 Position 9.”

The inner exception is similarly not giving much information:

{“Exception has been thrown by the target of an invocation.”}

The trick to getting to the root of the problem is simple. There are a couple ways to do so:

  1. Wrap the code in the constructor of the Window in a try/catch block. This will provide you with access to the actual exception and its stack trace.
    public MainWindow()
    {
        try
        {
            InitializeComponent();
    
            // other code, if any
        }
        catch(Exception ex)
        {
            // log the exception -- this is the real culprit
        }
    }
  2. Open the Exceptions window in Visual Studio (Debug -> Exceptions…) and check the “Common Language Runtime Exceptions” checkbox in the Thrown column. Re-run your application with the debugger attached, and the application will break on the exception that’s getting wrapped in XamlParseException.

Creating a New Application: First Lessons Learned

It may or may not come as a surprise, but writing software is hard. Having spent the last 3 years doing it for a living, I’m finally making time to develop a side project. I don’t have a proper name for it yet, but I don’t think I have to worry about that for quite a while.

I’m struck by how easy it is for me to write code at my job, where all products are in well-known locations and I’m very familiar with the code base. Creating an application from scratch is turning out to be a whole different animal.

I’ve been going back and forth on design decisions, agonizing over which features to start with and how to go about implementing it all together. And the main thing I learned is that writing code right away really is the worst thing to do. I made the mistake of ignoring that rule and paid for it by re-writing the same feature 4 or 5 times.

So below is my list of recently learned through experience things to know about writing a new application.

Lesson 1: Gather All Your Features in One Place

No, “it’s in my head” doesn’t count. Have a piece of paper or a text document that lists every feature you can think of. Then walk away from that list. Come back to it in a bit and read it over again — remove features that aren’t essential at first. Trim it down to the bare minimum that gives you a functional application. It may take a few iterations to get down to a short list of prime features.

Once that list is ready, prioritize core features over fancy “wouldn’t it be cool if…?” ones. And last but not least, think over every feature — what is needed to implement it? Will you need to pull in some third-party frameworks? Are there any particular design considerations or concerns?

Lesson 2: Figure Out All Workflows

For each feature on your short list, write out a detailed workflow. For example, in my application, the user can create new “To Do” items. So I write out that workflow:
1. Click File->New…
2. A dialog comes up where the user sets task parameters and notes.
3a. User clicks Cancel and the dialog is closed, discarding the information.
3b. User clicks OK and a new task is created.

I’d even sketch out the UI for each step, as needed. It helps.

Lesson 3: Write Some Tests!

It may be hard to wrap your head around how it will all fit together. The easiest way to get some progress is to write some unit tests. This will help you figure out what your classes might look like and help you arrive at a more easily usable interface.

Lesson 4: Don’t Settle on First Version of Anything

For each of the above lessons, I’ve found it helps to walk away for a bit and think things over. When you come back, you can look at things with fresh eyes and sometimes see things you missed the first time.

Lesson 5: Do One Thing At a Time

I find that I get distracted a lot while I code. Not by outside things like email or Twitter, but by tangential thoughts or ideas about what I’m doing. I keep thinking “oh, it’ll just take 30 seconds to fix up this one thing over here…” and before I know it, it’s been half an hour and I completely forgot what I was working on in the first place.

It is important to stay on track and on target. Make notes of things you think of along the way and schedule them in later.

Conclusion

It all boils down to staying focused and organized. Charging in keyboard blazing and starting to type out code will only slow you down in the end. It’s best to slow down, take stock of where you are and where you need to be, and form a plan to get there. Then work the plan and enjoy the feeling of productivity and motivation as you check things off and see your work produce tangible results.

Happy New Decade

I’ve seen some arguments going on around whether or not 2010 is the start of a new decade or the end of the “old” one. Among them was the best argument I’ve ever seen for zero-based counting: if 2010 is ending a decade, then by the same logic, 1980 is a part of the 70s and that’s just wrong. I really don’t think I can (or want to) argue with that, so I’m choosing to think of today as not only the beginning of a new year but also of a new decade.

Ten years is a bit too far in advance for me to even begin to contemplate planning. One year, however, is still doable. So, what do I think is on the docket for me?

  • Guitar Lessons — I’m going to continue taking guitar lessons and step up my actual practice time. I’m ashamed to admit that I have very little to show for the years I’ve been “playing” the instrument. That will change. When I do practice, I notice an almost immediate improvement, which tells me that I do have at least some talent for it. All that I need is practice and proficiency will come.
  • Side Projects — I will spend more time developing my own projects. I’m going to start with programming, of course, since that’s what I know best, but I’m sure others will come in time.
  • This Blog — I learned something obvious in 2009: without doing anything noteworthy, I don’t have anything noteworthy to write about. I will be expanding this blog to cover a few more topics, instead of trying to just blog about software development. At least until I do enough of the latter to be able to fill at least some regular posting schedule.
  • Debt Reduction/Conscious Living — I have some debt incurred during university, some for legitimate reasons, and some just because I didn’t know any better. It is well past time to deal with it all. My goal is to put thought behind everything I do. Even if I choose to spend my time on things that others might consider unproductive, I want it to be because I thought about it and consciously made the choice. It is time to reevaluate, and in some cases evaluate for the first time, what I spend my time on and why I do the things I do.
  • Theatre — I will continue my involvement with the Kitchener-Waterloo Little Theatre. I find it deeply fulfilling, and it’s good to have hobbies that get you out of the house once in a while.

Of course, it remains to be seen how much of the above will actually happen. I think the odds are in my favour. It will be interesting to look back at the end of next year and see how it all went.

Test your serialization!

Something I learned today: when making use of user profile support in ASP.NET 2.0, make sure to get the XML serialization of your objects right. Otherwise System.Web.Profile.ProfileBase will happily swallow any and all exceptions while loading your profile objects and you will spend 6 hours tearing your hair out.

*sigh*

The Nike Principle

I often find that I dawdle. I think of a great idea and then … never put it in action. I say I will do it “some day”. “When the time is right.” Trouble is, I never quite get around to defining what it means for the time to be right. To combat that, I now remind myself to either do what I said I would do or to come up with a set of well-defined criteria to determine when I’ll do it instead. No more excuses.

I call this the “Nike principle” because of their slogan: Just Do It.

That’s really all that matters. Waiting for the perfect moment to develop a new habit or try a new approach to something is often just a waste of time. When trying to learn something or make a change in your routine, don’t wait for the stars to align. Just do it. If it doesn’t work, refine your approach. Repeat that until you’re happy with what you’ve got. It’s as simple as that.

There's Always a Reason

Back in middle school, my algebra teacher had a saying. Every time one of us would try to get through a proof by declaring that “we can just see that [some assertion] is true”, she would interrupt us and emphatically declare that she couldn’t see anything. Meaning, of course, that not even the most basic things are always obvious and we should do our due diligence and be precise in our proofs.

Every once in a while something happens that reminds me of that lesson. One such thing happened last night.

First, a bit of backstory. I picked up an Acer Aspire One back in September 2008. It was one of the Linux models with a solid state harddrive and 1GB RAM, running Acer’s idea of a mainstream user friendly Linux OS — Linpus. It was a little basic and rather ugly, but worked well enough for someone like me who had dabbled in Red Hat 5 back in the day but hasn’t stepped outside the Windows box in a few years.

Then a few months later, wireless stopped working. No amount of fiddling with software settings or the wireless toggle on the front of the netbook helped. I looked at that as an opportunity to dump Linpus and move on to something a little more mainstream – Ubuntu.

If my goal had been to just fix the wireless, I really should’ve hit Google first for information. I didn’t find out until weeks later that apparently there was a known (or, at least, experienced by several people) issue with wireless on Aspire Ones running Linpus. But, by then it was too late. I was happy with Ubuntu, except for the part where neither wired nor wireless connection now worked.

The laptop sat on a shelf gathering dust for a few months until last night when I decided that that was it. It was time to fix it once and for all, and this time I was going to be prepared first. I did a bit of research and found Easy Peasy — a flavour of Ubuntu developed specifically for netbooks. Perfect!

A couple hours later, I had a bootable USB stick with the distro on it. The installation went by very smoothly, but when it was all said and done, I was disappointed to find out that the wireless connection was still broken. But, I was one step ahead of where I was with my previous attempt. This time, the wireless interface was available and seemingly configured right out of the box.

So, I dug deeper. Or so I thought. The symptoms were easy –Network Manager applet would attempt to establish a connection, but then come back with a prompt for the WPA password. I knew the password was correct and the network was properly configured, since I had two other laptops and a game console connecting to it without trouble. The issue, I thought, must surely have been with the OS. Somehow the password I’m entering isn’t being used properly.

Google to the rescue! I found a couple sites that reported similar issues and blamed the password store Easy Peasy comes with, the Gnome Keyring. They advised removing the password on the default keyring to trade off security for a working wireless connection. “Great!”, I thought. Lowering security on passwords isn’t a good idea by any means, but I wasn’t planning on using the netbook for anything important and above all, I just wanted to get a connection going to prove that it could be done at all.

None of the suggestions I’d read worked. I thought I was going insane. I came quite close to replacing the network manager app and even the wireless drivers. By this point, it was pushing 1:30 a.m. and I’d been at this for about 3 hours. Up to that point, I’d held off on ranting on Twitter and Facebook, but this was it. The proverbial straw breaking the proverbial back.

A couple 140-character posts later, I decided to make one last-ditch effort: reinstall Easy Peasy, make sure I didn’t miss anything during the installation, and get back to a clean slate before I messed around with deleting keyrings and compromising security and configuration. Sometime during that, I pushed the wireless switch on the front of the netbook… and once the installation completed, the connection “magically” same to life.

The LED that’s supposed to indicate whether the card is enabled or not doesn’t work out of the box in Ubuntu and I’d forgotten about the switch entirely, assuming that the card was enabled because the interface appeared in the ifconfig report.

So the moral of the story is, I can’t see anything. Nothing is obvious. Always check all your assumptions, no matter how trivial they seem, because a problem elsewhere in the system may be leading you down the wrong path. And whatever you do, hold your public ranting until you’ve eliminated possibilities and know for sure what’s going on.

As for that LED, I hear there’s a fix. I think I’ll look for it tonight.

But I shouldn't have to!

It amazes me sometimes how dismissive developers and advanced computer users can be of issues people have with applications. For example, FireFox 3.5 came out and Frans Bouma is reporting uncomfortably long start-up times on his blog. Now, I haven’t run FF3.5 myself and therefore can’t comment on my own experience running it, but I want to talk about a trend I’m noticing in the comments on that post.

Quite a number of people think it is acceptable to say things along the lines of “well, you should just clear out your cache”. Well, no. He shouldn’t. There is absolutely no reason for a user to change the way they work to accomodate an application as common and replaceable as a browser. For that matter, there should never be a reason to accomodate any finicky application, but I can see how in some niche markets that could be unavoidable. This is a problem in user experience design that seems to be quite prevalent, especially in the realm of open source development.

In a similar vein are posts on Coding Horror and bitquabit, calling out calling out developers for claiming a complex site like StackOverflow is “trivial”. Guess what, folks? As developers, we should be paying more attention to user experience, testing more scenarios, and not dismissing bad experience reports with nothing but a “oh, you should just use it the way we do and then it’s great”. It is naturally impossible to please everyone, but opting to use algorithms that do not depend on a state of the user’s system that’s completely outside the developer’s control seems to me a good start in the “consistent experience” direction.