Friday, January 23, 2009

A simple plug-in framework for .NET apps

If you want to add plug-in support to your application then you might start looking at Microsoft’s Managed Extensibility Framework or System.Addin. Whilst I have no experience of these frameworks, when I looked at them I decided they were just too complicated for my needs. Also I was targeting .NET 1.1 so couldn’t use either of them. All I wanted to be able to do was to write a class that implements a particular interface (for importing files from one of a number of external file formats), dump it in the application’s directory and for the application to recognise the assembly and add the supported file type to its list of available file types. I won’t bore you with the details of the interface, since it’s obviously specific to the application being developed, but here’s the code for loading the assemblies and creating instances of the available importers.

      // load all importers
      string applicationDirectory = System.IO.Path.GetDirectoryName(
        Assembly.GetExecutingAssembly().Location);
      DirectoryInfo info = new DirectoryInfo(applicationDirectory);
      FileInfo[] files = info.GetFiles();
      List<Type> types = new List<Type>();
      for (int i = 0; i < files.Length; i++)
      {
        // load assemblies and see what is in there
        if (files[i].Extension.ToLower() == ".dll")
        {
          Assembly thisAssembly = Assembly.LoadFrom(files[i].FullName);
          Type[] assemblyTypes = thisAssembly.GetTypes();
          for (int j = 0; j < assemblyTypes.Length; j++)
          {
            if (assemblyTypes[j].GetInterface("IImport") != null)
            {
              ConstructorInfo wfConstructor = assemblyTypes[j].GetConstructor(Type.EmptyTypes);
              object obj = wfConstructor.Invoke(null);
              IImport importer = (IImport)obj;

              importers.Add(importer);
            }
          }
        }
      }

This worked well for me. I’m sure it wouldn’t work in all scenarios and MEF/System.Addin may be more appropriate to more complex scenarios (if you are worried about versioning or running your add-in in a sandbox for instance) but it’s a quick and dirty method for implementing plug-ins.

Thursday, January 22, 2009

Turn on script debugging!

The other day I was pointed in the direction of a new website for a company I know. The owner was very pleased with the work a web design agency had done for him. Unfortunately the first thing I saw was a script error, then another then finally the page appeared. Pretty nice it was too, but the whole experience was somewhat spoiled by those script errors. Of course most people have script debugging turned off so they don’t see these errors but if you’re paying someone to develop your website it is something you need to do.

I wouldn’t recommend having it turned on all the time, the fact is the web is almost unusable if you do have script debugging enabled. Some websites cause so many errors that the only solution is to kill your browser and a large number of high profile websites have some kind of script error. Of course, some would say this is only an IE problem and point to the crappy way IE implements the debugger notification in a modal dialog box and that is certainly true. Perhaps it was done that way so that it is so in your face, that if you’re the developer of the site you just have to do something about it. I think the actual consequence is that anybody who has turned it on turns it off at the earliest opportunity.

But I digress, the point is if you’ve paid somebody to develop your website, make sure they’ve actually done a decent job, even if the only people who’ll notice they haven’t are anal geeks like me.

Wednesday, January 21, 2009

The value violated the integrity constraints for the column

I was trying to import some data from an Excel spreadsheet into SQL Server today and kept getting this error message.

Error 0xc020901c: Data Flow Task: There was an error with input column "PHNUMBR1" (207) on input "Destination Input" (96). The column status returned was: "The value violated the integrity constraints for the column.".
(SQL Server Import and Export Wizard)

I was having trouble working out what SQL Server was trying to tell me. The table didn’t have any constraints that I could see so I was at a loss. The only seemingly related post was this one, unfortunately in Chinese. But it gave me a clue. I saw the words ‘NOT NULL’ and realised that was the problem. The table had some columns that did not allow NULL entries. I removed these restrictions and the import worked.

So the questions for today are - am I just stupid? Should SQL Server provide a better error message? Should it just populate NOT NULL columns with empty strings?

Monday, January 12, 2009

Waiting for ever to be an overnight success

Mister Coding Horror Jeff Atwood talks some sense about overnight success, namely that it doesn’t generally happen. Success is a long road, it can takes years for a blog or software to reach any kind of critical mass. But I think he misses an important point. Namely, that success may never come, all that hard work may be for nothing. Take blogging. How many blogs are out there? Millions probably. How many are successful? A few thousand perhaps, so the chances of hitting it big are pretty remote. What about software? Since the barriers to entry are a little higher, there’s not so much software around but how many successful bits of software are there in each mature category you look at? Two or three generally. How many software products have fallen by the wayside? Generally many more. Websites? The same kind of success rates I’d guess.

So if you enjoy writing your blog, cool. If you enjoy hacking code, great. But don’t assume you’ll be successful, over any time span. Don’t think you will be able to retire to your own private island, however much effort you put into it. Have a plan B. Get a job that pays a reasonable wage (not just piles of stock options), put some money away, pay down your debts. Oh, and don’t call your blog ‘Bell End’.

Friday, January 09, 2009

XslTransform not generating XML declarations

I’d just started having a look at some .NET 1.1 code using the XslTransform class and I was having a bit of trouble. The program that read the generated XML expected an XML declaration at the top of the document. No problem I thought, just add an omit-xml-declaration="no" attribute to the XSLT. I did that and the XML declaration still didn’t turn up. So I checked the XslTransform class to see if that had some property to force the declaration to appear but no. Then I tried fiddling with the other xsl:output attributes in the XSLT, but still nothing.

So what about the XmlTextWriter class then? No, nothing on that to control the XML declaration (although it looks like later versions of the .NET Framework do include support for this). But hang on, why am I using the XmlTextWriter class anyway? The XslTransform class will take a stream instead. And tada! That fixed the problem and also saved a few lines of code. So only an hour of my life wasted. Hopefully this will save you that time.

Wednesday, January 07, 2009

Easy SQL

Accessing databases on Windows has been a constantly moving target over the years. First there was ODBC, a pretty simple C based API. When COM came along, MS decided that they needed to have an object based data access library so out came DAO, followed pretty swiftly by RDO, OLEDB and ADO. When .NET came out we got ADO.NET and then recently we've had LINQ to SQL and now Entity Framework. LINQ to SQL lasted such a short time that I didn't even have time to look at it properly before it died. And there's probably others I've forgotten about.

Some may not think this is a problem. After all, the older technologies are still available so there's nothing stopping you continuing to use them, but the chances are you'll have to maintain a project at some point that uses another data access technology so you'll need to have a passing knowledge of all of them.

So I have an idea, Microsoft. How about adding a common API to all your data access technologies? Here's my suggested interface.

public interface IEasySQL
{
  void Connect(string connectionString);

  void ExecuteSQL(string sql);

  object[][] SelectSQL(string sql);
}

I think it's fairly obvious how this interface works, so I won't bore you with the details. Now some of you are probably thinking it's missing a few features. Things like transactions, parameterised queries, that kind of thing. Fair point, but for me at least, this would be adequate 90% of the time. If I need the more complicated stuff I can always go to the underlying API, but for most of the time I can just throw a query at the database, because that's all I need to do. Yeh, it's not scalable, but generally my queries only return a few results, maybe a thousand, and this will work fine. So how about it, MS? And if anybody is interested, I can knock together an implementation using ADO.NET.

Sunday, January 04, 2009

The Black Swan - Nassim Nicholas Taleb

I don't think the author of this book is the person who coined the saying 'black swan' but that isn't really important. What is important is what he's trying to say, that we tend to ignore the impact of highly improbable events, mostly because we aren't able to predict them. The saying comes from the fact that we thought all swans were white until somebody found a black one and our definition of a swan was turned on its head.

I think this book has become a commercial success due to a little bit of serendipity, it arrived on the shelves of bookshops at about the same time as the financial meltdown kicked off, arguably a black swan in itself (although I'd argue quite a few people saw this coming but not many realised how serious it would become). I think that's what they call ironic.

Anyway onto the book. For me it only really comes into itself in the last few chapters where he gets into the technical details of our failure to predict, which is mostly down to our use of the Gaussian/normal distribution where it isn't applicable. We should be using fractals instead (before reading this I thought fractals were purely used to produce pretty pictures). The earlier chapters could have been shortened more for my liking, there's only so many ways you can say we fail to take notice of the impact of the highly improbable (except after the event when we manage to produce a narrative to explain why it happened and wasn't totally unexpected). I guess I'm more interested in the hard facts, rather than the philosophical musings. But that said, it's still a very good read and certainly makes one think. I guess the important point is that we should try to increase our exposure to potential positive black swans (business opportunities etc) whilst reducing our exposure to potential negative ones.

Saturday, January 03, 2009

Recycling is wrong

Our council finally got its recycling strategy sorted out recently. This means that recycling is collected once a week instead of every other week and they now collect cardboard and food waste which they didn't do previously. I'm quite happy with this since it means I don't have to make regular trips to the tip anymore. Of course there have been some teething problems and I'm seriously bored of all the complaints from my neighbours. It's no wonder that Australians call us whinging poms...

But I do keep thinking there is something wrong with the whole concept of recycling. I buy a bottle of wine, drink it, then the bottle gets taken away and recycled and made into another bottle. But, but... How much energy is being used up in producing a bottle that is only used once? When I was a lad, we returned bottles to the shop (fizzy pop rather than wine in those days) and got back 2p for our bother. The bottle then got sent back to the fizzy drinks company who refilled it and sent it out again. In fact, go to India and many other 'less developed' countries today and you'll find the same thing. When you buy a drink, it comes in a scratched old bottle that has obviously been used several hundred times before. Isn't this the model we should be adopting? It seems a much better use of resources. The thing is the supply chain is already in place, all those bottles get delivered to the shops, so the same lorries could be used to return the empties back to their original source. What am I missing?