private override

27Aug/102

Never implement INotifyPropertyChanged again

I hate every time I am working on something and I have to implement INotifyPropertyChanged.  My DRY-dey sense tingles.  Not only am I forced to not use auto-properties (1st DRY violation), I’m forced to fire the event in each setter (2nd DRY violation), and specify the name of the property that is getting set, inside of that property’s setter (3rd DRY violation).  That much WET (read: not-DRY), for something so simple leaves me a little grumpy.

I’ve been on this quest before, to simplify this a bit, but it was still a little hackety, and limiting.

This time, I set out to do it right.

I’ll spare you most of the technical details, but it’s backed by Castle’s DynamicProxy project, and there’s some integration with StructureMap to make it super easy, though you don’t really have to use StructureMap if you don’t want to.  [note:  I’ll probably add more container support as I find time.  If you have a specific need, let me know, or submit a patch.]

Here are the codez to show it in action:

Basics

Using it for a class with an interface

// note the attribute goes on the interface, not the class

[AutoNotify]

public interface IFoo

{

    string Value { get; set; }

}

 

public class Foo : IFoo

{

    public string Value { get; set; }

}

 

Using it for a class

[AutoNotify(Fire = FireOptions.OnlyOnChange)]

public class Foo

{

    // note for autonotify to work, the property must be virtual

    public virtual string Value { get; set; }

}

 

The previous example shows how to get the event to fire only when the value is different also.  It defaults to always firing, whether the value changes or not.  It’s also important to note that your properties need to be virtual so the calls to the setter can be intercepted.

Dependent Properties

Sometimes (usually) you’ve got calculated properties that need to fire the notified event too, these usually turn into WET mess as well.  We’ve got the problem solved, and you’ve got a few different options, hopefully one of them suits you.

Dependency Map – DependsOn

You specify the type that defines the DependencyMap on the attribute, and then set up your dependencies in that type’s constructor.  This style is somewhat influenced by the FluentNHibernate API.

[AutoNotify(DependencyMap = typeof(ProjectDependency))]

public class Project

{

    public virtual string Name { get; set; }

    public virtual string[] Files { get; set; }

    public virtual int FileCount { get { return Files.Length; } }

}

 

class ProjectDependency : DependencyMap<Project>

{

    public ProjectDependency()

    {

        Property(x => x.FileCount).DependsOn(x => x.Files);

    }

}

 

Dependency Map – Updates

If you’d rather express your dependency the other way around, that’s fine too.  The two are equivalent.

[AutoNotify(DependencyMap = typeof(ProjectDependency))]

public class Project

{

    public virtual string Name { get; set; }

    public virtual string[] Files { get; set; }

    public virtual int FileCount { get { return Files.Length; } }

}

 

class ProjectDependency : DependencyMap<Project>

{

    public ProjectDependency()

    {

        Property(x => x.Files).Updates(x => x.FileCount);

    }

}

 

Dependency Map – UpdatesWith

If you want to stick with an auto-property, and leave the calculated property logic somewhere else, you can hook it in via your dependency map too.  This example, again, is equivalent to the previous two.

[AutoNotify(DependencyMap = typeof(ProjectDependency))]

public class Project

{

    public virtual string Name { get; set; }

    public virtual string[] Files { get; set; }

    public virtual int FileCount { get; set; }

}

 

class ProjectDependency : DependencyMap<Project>

{

    public ProjectDependency()

    {

        Property(x => x.Files).Updates(x => x.FileCount).With(p => p.Files.Length);

    }

}

 

DependsOn Attribute

If you don’t like any of those options and are looking for something a little more simple, maybe you’ll like this one.  Just specify which things your property depends on in an attribute.  You lose your 100% static typing help, but it’s more concise.

[AutoNotify]

public class Project

{

    public virtual string Name { get; set; }

    public virtual string[] Files { get; set; }

 

    [DependsOn("Files")]

    public virtual int FileCount { get { return Files.Length; } }

}

 

Containers and otherwise

Hooking it into StructureMap

There are a couple conventions you can use to hook into StructureMap.  There is the attribute convention (which is what you’re seeing above), and there is a generic predicate convention that you can use any predicate logic.  Below you can see the attribute one getting hooked in.

var container = new Container(config => config.Scan(scanConfig =>

{

    scanConfig.With(new AutoNotifyAttrConvention());

    scanConfig.TheCallingAssembly();

    scanConfig.WithDefaultConventions();

}));

 

var project = container.GetInstance<Project>();

Using it without StructureMap

If you’re using another container, or no container at all, but want to use some other factory or something, you can do that too.  This example is for something with an interface.  It’s very similar to do the same for a concrete class… you just don’t instantiate the object first.  You also have an opportunity to hook into the dependent property structure here as well with the DependencyMap parameter.

var foo = new Foo();

var notifiableFoo = Notifiable.MakeForInterface(

    typeof(IFoo),

    foo,

    FireOptions.Always,

    new ProxyGenerator(),

    DependencyMap.Empty);

 

Assert.That(notifiableFoo is INotifyPropertyChanged);

 

Whew, done

So… that’s a lot of ‘how to’, but hopefully it’ll be somewhat complete introduction to get you working with it.  I really don’t see much of any reason to ever implement INotifyPropertyChanged ever again (unless you are in an environment where you can’t use DynamicProxy).  It can automatically be done for you from now on.

The code is up on github, and there is a gem up on rubygems if you’re using nu or noodle+bundler.  Fork it, send me a patch, use it, send feedback, etc.  I hope you love it!

29Jun/103

Syntax highlighting for technical presentations

Ever wanted a quick/easy/automated way to get syntax highlighted code from your editor of choice into PowerPoint?

EVERY time I do a technical presentation I need this.  Usually I resort to taking a screenshot, or finding an “export to html” type plugin for the editor I’m using at the time (Visual Studio, Vim, IntelliJ IDEA, etc.) and then try to get that somehow into my slides.

The problem I usually run into, is that while I like coding on a dark background with a 14pt font, that’s not usually that great for presentations.  So I switch to my “presentation settings” that has a light background and bigger font size, and then switch back once I’m done taking screenshots or outputting to html. [ugh, what a pain… terribly manual].

Then what happens when I spot a bug in code that’s in PowerPoint, or I want to add a comment, or I need to change the syntax highlighting theme of the entire presentation because it doesn’t go well with the lighting in the room.  UGH!  What a disaster.

Basically, it’s always an uphill struggle, and it really bothered me… so I decided to fix it once and for all.

Solution

I’m going to solely discuss PowerPoint (for Windows or Mac) here.  I don’t have a copy of iWork, and I’m too cheap to buy one.  The reason I have Office for the Mac, is because I got it for free… KeyNote/Mac zealots: feel free to be zealous, but don’t hate on me because I’m frugal… unless you want to buy me a copy of iWork.

First, download: http://www.andre-simon.de/doku/highlight/en/highlight.html

Windows Solution

The highlight tool can output many formats, but the important one for Windows is RTF.

So something like:

highlight < infile > outfile –-rtf --syntax=rb  --style=vim --font=”Lucida Console” --font-size=18

This will  take the source code file ‘infile’ and syntax color it as Ruby to an RTF file and output it to ‘outfile’.  The text will be 18pt Lucida Console and syntax highlighted with the “vim” color scheme.

There are lots of themes included, you can ask highlight for help (highlight --help), and it’ll tell you all the options available, as well as all the options available for output, and for languages that it supports.

Next, in PowerPoint, do “Insert Object” on your target slide, and choose “Create from file”.  Make sure you check the “Link” checkbox before pressing OK.

Now, whenever your source changes, re-run your command line, then you can choose “Update Link” on your embedded object in PowerPoint, or if you close and then re-open PowerPoint, it’ll give you the option to update all your links.

Mac Solution

My version of PowerPoint for Mac doesn’t like being able to link to RTF files, but it does allow linking to images.

Highlight can output to SVG, but my PowerPoint doesn’t like that either.

Now download inkscape, if you haven’t already.  It will allow you to rasterize the SVG into a PNG, which PowerPoint does like.  You can export your PNG from inkscape from the command line like this:

<path to inkscape> –export-png=<png file> <svg file>

The path to my inkscape command line runner is at:

/Applications/Inkscape.app/Contents/Resources/bin/inkscape

It turns out that inkscape doesn’t like external CSS files, which is what highlight gives you with your SVG, so you can merge your CSS file into your SVG file with a little script.  The other cool bit about SVG, is you can tweak it, if you want, since it’s just XML.

Now, in PowerPoint, choose “Insert Picture” and browse to your newly generated PNG.  Make sure the “Link to File” checkbox is checked.

I wrote a script to do this for the latest presentation I did on dependency injection.  You can take a look at the script here [source.rb].   It’s Ruby, and you can see where I merge the CSS and SVG files together, and where I mess with the line spacing as well (I wasn’t happy with the default line spacing, so I tweaked it to my preference).  All the source/images/PowerPoint for that presentation are available here [dependencies presentation] if you want to check them out to see how the whole process works.

Now, when I need to change the font and syntax theme throughout my entire presentation because it doesn’t match the lighting in the room, it’s super-simple: I change the configuration, re-run my script, update PowerPoint, and chill.

Tagged as: , , 3 Comments
4Jun/103

Teaching StructureMap About C# 4.0 Optional Parameters and Default Values

This week I ran into wanting to use C# 4.0 optional parameters, but wanted StructureMap (my IoC tool of choice) to respect the default value specified for those optional parameters.

The Problem

In this example, we’ll be pulling a command out of the container.  The important part is the optional constructor parameter (level), and it’s default value (Level.Info).

public class LogCommand

{

    IDestination _destination;

    Level _level;

 

    public LogCommand(

        IDestination destination, Level level = Level.Info)

    {

        _destination = destination;

        _level = level;

    }

 

    /* logging code here */

}

 

Here is your basic usage, but doesn’t work since StructureMap doesn’t know how to take advantage of the optional parameters with default values.

var container = new Container(config =>

{

    config.Scan(scanner =>

    {

        scanner.TheCallingAssembly();

        scanner.AddAllTypesOf<IDestination>();

        scanner.WithDefaultConventions();

    });

});

 

var logCommand = container.GetInstance<LogCommand>();

 

The last line results in an exception because StructureMap doesn’t know how to fill in the level parameter.

The Solution

We can solve this by adding a new convention.  One that adds information about default constructor arguments.  Here is the implementation of the convention:

public class DefaultCtorParameterConvention : IRegistrationConvention

{

    public void Process(Type type, Registry registry)

    {

        if(type.IsAbstract || type.IsEnum)

            return;

 

        var ctor = type.GetGreediestCtor();

 

        if(!ctor.HasOptionalParameters())

            return;

 

        var inst = registry.For(type).Use(type);

 

        foreach(var param in ctor.GetOptionalParameters())

            inst.Child(param.Name).Is(param.DefaultValue);

    }

}

Note: GetGreediestCtor, HasOptionalParameters, and GetOptionalParameters are extension methods.  We’ll see their implementation shortly.

The convention inherits from the IRegistrationConvention, which is how you implement new conventions in StructureMap.  It has only one method: Process.  We filter out types that are abstract, are enums, or have constructors that don’t have optional parameters.  Once we realize we have a constructor we want to deal with, we use the Child method, that sets either a property or a constructor argument (for our case, it’ll always be a constructor argument), and then we set it’s value to the parameter’s default value, as provided by the ParameterInfo object, for each optional parameter.

Minor Details

Curious about the implementation of GetGreediestCtor or the *OptionalParameters methods?  If not, skip this section.

public static bool HasOptionalParameters(

    this ConstructorInfo ctor)

{

    return ctor.GetOptionalParameters().Any();

}

 

public static IEnumerable<ParameterInfo> GetOptionalParameters(this ConstructorInfo ctor)

{

    return ctor.GetParameters().Where(

        param => param.Attributes

            .HasFlag(ParameterAttributes.Optional));

}

 

public static ConstructorInfo GetGreediestCtor(

    this Type target)

{

    return target.GetConstructors()

        .WithMax(ctor => ctor.GetParameters().Length);

}

 

public static T WithMax<T>(

    this IEnumerable<T> target, Func<T, int> selector)

{

    int max = -1;

    T currentMax = default(T);

 

    foreach(var item in target)

    {

        var current = selector(item);

        if(current <= max)

            continue;

 

        max = current;

        currentMax = item;

    }

 

    return currentMax;

}

 

 

The Usage

Here’s how to use your new convention.

var container = new Container(config =>

{

   config.Scan(scanner =>

   {

       scanner.TheCallingAssembly();

       scanner.AddAllTypesOf<IDestination>();

       scanner.WithDefaultConventions();

       scanner.Convention<DefaultCtorParameterConvention>();

   });

});

 

var logCommand = container.GetInstance<LogCommand>();

 

Now, when we pull the LogCommand out of the container, the level parameter gets defaulted to Level.Info, just like we specified in the constructor.  Sweet!

Conclusion

This implementation is somewhat limiting, but the version I have in my github repo is a little more open and configurable.  It allows you to customize the instance key/name you use when registering your type, and also allows you to do additional, non-standard registrations if you need to.

Also, this doesn’t work if you’ve selected a constructor using the SelectConstructor config API from StructureMap, I’m not sure how to tap into that facility to look for that constructor rather than the greediest.

Am I missing something?  Did something not make sense?  Leave me a note!

12Apr/100

The file exists

Maybe I should title this post ‘How to write a better error message’ instead.

I just went on a wild goose chase trying to find the solution to an error I kept seeing in SQL Server Management Studio every time I tried to run a query or open a table for editing (or anything else that would end up executing a SQL query).  The error message?

The file exists

Not exactly useful.

It turns out my temp directory was ‘full’.  The message sort of makes sense, now that I know what the problem was, but it isn’t really possible to draw the correct conclusion from that error message.

So two takeaways (for me):

  1. Craft error messages carefully.  The whole reason for showing/logging error messages in the first place is to create some kind of traceability to a problem.  The information contained in an error message should lead the user to a better understanding of the problem and possibly an indication of if they might be able to fix it.
  2. The file exists means clear your temp directory first, before chasing that goose.
Tagged as: No Comments