More servicesWindows Live
HomeHotmailSpacesOneCare
 
MSN
Sign in
 
 
Spaces home  So long, and thanks for ...ProfileFriendsBlogMore Tools Explore the Spaces community

So long, and thanks for all the chips

July 21

Rant: $%!#(* Grid

I'm a tad frustrated by the default templates used by VisualStudio and Expression Blend for WPF.  The XAML always starts you out with a Grid.  WTF?

The Grid panel is the most inefficient of the panels.  It's also not all that easy to use for most layouts.  In other words, its the layout I would expect most developers to use the second least often (Canvas takes the bottom spot).

Don't get me wrong.  There's plenty of scenarios in which Grid is your best layout choice.  However, there's even more scenarios where it's not.  Rarely is it the panel I'll want my Window/Page to use by default.  I almost always rip that Grid out of the generated XAML and replace it with either a DockPanel or a StackPanel.

So why the harsh tone to this rant?  After all, it's not that big of a deal to replace it, if it's not appropriate.

The tone is harsh, because having Grid as the default panel generated by tools is leading the unwashed developers into some bad habits.  Most developers don't understand why Grid isn't as appropriate as other panels.  When they see it being used by default, they think it's the panel they should fall back on by default.  This leads to an overuse of the panel.  That really bothers me.  How many times have you seen a Grid used when there's a single column and/or row, for instance?

Sorry, this is partially a religious debate.  The performance of a Grid isn't so bad as to matter most of the time.  But I still have the hairs on the back of my neck stand on end the majority of the time I see a Grid used in WPF.  The fact that the generated XAML encourages this doesn't help.

Update:  Here's a classic example.  The recently released Prism contains a "view" called OrdersToolbar.  The OrdersToolbar.xaml file contains some lovely code in which the default template's Grid element was left in the source.  It's only child element is a horizontal StackPanel that really defines the layout for the user control.  Remove the Grid and the resulting user control is functionally identical, with easier to understand XAML markup and theoretically better performance (yeah, the perf hit here is not noticeable to the user and probably very difficult to measure, so I don't want to make too much out of that, but it is still there).  Maybe the template shouldn't include anything but the Window/Page/UserControl, but it certainly shouldn't include a Grid, IMHO.

May 21

An object you can depend on

Sorry for that.  I needed a catchy title ;).

Well, now that I'm a WPF Disciple I should probably blog more about WPF.  What's interesting though, is despite the fact that I'm now working on a WPF project, most of the coding I've been doing lately has not been UI related.  So, not much to blog about WPF.

Well, over lunch today my mind was wandering over the stuff I have worked on lately.  Among them was the IoC container I've been tooling about with.  One of the things I did with the container was to extend the functionality through extension methods.  Worked great, but occasionally your extensions needed new state information that didn't exist on the object.  Well now, this ties back to WPF after all.

See, there's this concept in WPF that directly addresses this.  It's called an "attached property".  An attached property is a property associated with an object instance, but the backing store isn't the object itself.  This is accomplished through DependencyObject and DependencyProperty classes.  A DependencyObject has GetValue() and SetValue() methods that take a DependencyProperty as a parameter, and get/set values for that dependency property through some magical backing store that's not actually part of the object (basically the storage is some giant HashMap).  An attached property is a special type of DependencyProperty that allows you to attach values to any DependencyObject, not just the object on which the DependencyProperty is defined.

So, by turning my ObjectContainer into a DependencyObject, I can allow extension methods to maintain their own state information on the container they are extending!  Such a simple concept, and yet it didn't dawn on me to do this in my initial implementations.  I rolled all of the necessary plumbing to track associated external state information by hand, and did it every time I needed new state information in a new extension method.  What a waste of time and effort! :)

I think I'm starting to fall in love all over again with DependencyObjects.  I've avoided using them anywhere but at the UI layer.  I thought it was wrong to bring in all of this baggage at the data/domain layer.  After all, INotifyPropertyChanged gave me everything I need at that level, and Don Box agreed with me.  Well, now I think Don and I were wrong.

You see, even at the domain layer, it's not that unusual to need an "extension mechanism".  Some way for a known domain object to be extended with more features under certain circumstances.  We've all rolled specialized mechanisms for allowing this in the past.  However, with a DependencyObject this functionality is baked in, using a mechanism that's well supported by the rest of the framework.  I used to think that dependency properties were too much of a PITA to deal with unless you absolutely had to... but I think I'm changing my mind.  The flexibility and functionality you gain by deriving from DependencyObject is probably enough to outweigh the development cost, especially if you use a good set of snippets.

I've done a lot of programming in dynamic languages.  The ability to add functions and data to an existing object always proved invaluable in those languages.  Of course, the lack of compile time checks on all of that made maintaining those code bases a bit of a PITA.  It's kind of exciting to realize now that I have most of the capability to do this but in a statically checked at compile time nature.

May 02

Newest WPF Disciple

You have GOT to check out the newest WPF Disciple.  I'm not sure I can count all of the contributions he's made to the community.

OCD - Oh is that Code Disgusting!

This is a little rant.  If you don't like those, move along.

I think coders have been slowly becoming lazier, and now it's really started to get on my nerves.  I've seen SOOO much public code lately that is just frightening!  I'm not referring to the algorithms or other technical aspects of the code here, but rather to the lack of formatting.

I'm not starting a religious war here.  I don't care if you put your opening brace on the same line or the next.  I don't care if the braces are indented or not.  I don't care if you use tabs or spaces.  I don't care if indents are 3 spaces or 12.  I don't care if you mark members with an "_", an "m_" or any other wart.  (Well, to be fair, I do have opinions on all of those, I just don't care if your opinion differs.)

No, what I care about is consistency.  It's the lack of consistency that I've been seeing lately that's lead to this rant.  In fact, it goes beyond a lack of consistency.  Developers aren't even TRYING to make their code readable or maintainable.  Want an example of what I'm ranting about?  Check out the published code in this article on CodeProject.  I don't even know how hard you have to work to get code this unformatted, considering all editors today at the very least auto-indent for you.  VisualStudio will even indent pasted code that originally had a different indent properly.  And one of my bigger pet peeves is with extraneous blank lines.  A single blank line in logical places to call out sections of code is very appropriate.  I use a lot of them in my own code.  But in that first code snippet there's no consistency in the way blank lines are used, and I count at least 8 lines that have no purpose existing.  Worse, some of those are consecutive.

Are we really becoming to lazy to bother making our code look professional, instead of looking like it was mashed out on a keyboard by a monkey with 3 missing fingers?

Disclaimer: I don't mean to pick on the author of that CodeProject article.  I've not read the article yet, and it may be of high quality, ignoring this glaring issue.

April 24

The "var" controversy

There's some blog buzz going on right now about the appropriateness of using the new C# "var" keyword.  I first ran across the meme from Jean-Paul S. Boodhoo's blog, with this post.  He later linked to a post by Ilya Ryzhenkov on the same subject.  One of the responses on Ilya's blog read:

"The upshot here is that vars generate some serious code - all for good reason when using LINQ. But NOT for a good reason if you’re being lazy - which is the point of this whole post. If you find yourself using “var” anywhere that’s not within a LINQ statement, it’s probably not a good idea."

This response was quoting a post by Rob Conery.  Let me first say, I have not read all of Rob's post (mostly because the formatting is so bad, it makes it hard to read the post, and I don't have the time to spend on the effort).  Maybe this quote is taken out of context, so take what I say next with a grain of salt.  This quote is utter hogwash.  The "var" keyword produces no extra code.  Prove it to yourself.

public class Foo
{
}

class Program
{
    static void Main(string[] args)
    {
        Foo explicitFoo = new Foo();
        var inferredFoo = new Foo();
    }
}

The resultant IL that's generated is this.

.method private hidebysig static void Main(string[] args) cil managed
{
    .entrypoint
    .maxstack 1
    .locals init (
        [0] class Playground.Foo explicitFoo,
        [1] class Playground.Foo inferredFoo)
    L_0000: nop 
    L_0001: newobj instance void Playground.Foo::.ctor()
    L_0006: stloc.0 
    L_0007: newobj instance void Playground.Foo::.ctor()
    L_000c: stloc.1 
    L_000d: ret 
}

The code for the explicitly declared variable and the inferred though "var" variable is identical.  Do NOT fear using "var" because of performance concerns, as there is none.

With that out of the way, where do I fall in opinion on this subject?  Well, reading the various posts in this meme, there seems to be two camps.  I think both are extremes.  The first extreme is the "Microsoft Camp".

“Overuse of var can make source code less readable for others. It is recommended to use var only when it is necessary, that is, when the variable will be used to store an anonymous type or a collection of anonymous types.”

I simply can't agree with this extreme viewpoint.  Tell me how the following code can possibly be considered less readable for others?

var inferredFoo = new Foo();

The other camp, which I'll call the Boodhoo camp, though I don't have proof that Mr. Boodhoo specifically takes this extreme point of view, believe that you should always use "var".  I can't agree with that extreme either.  Can anyone tell me what the type of the following declaration is?

var current = Foo.Current;

We can have arguments until we're blue in the face about how better naming would have prevented this confusion.  I don't buy the argument, though.  First, names aren't always under your control.  Second, even with better naming it's still possible to find yourself in situations where you don't have enough type information available to you in situations like this.  C# is still a strongly typed language, and knowing the exact type your dealing with is important.  Relying on the IDE is a no go for me, and relying on naming isn't always possible.

So, what do I think?  Out of habit, I'm still not using "var" that frequently, but I see no harm in using it for your typical "new" statements like the first example.  I don't know if I'll get into the habit of doing that or not, but I see no reason to try and talk anyone out of doing so.  For other declarations like the second example, unless the type is anonymous, I'd probably favor the Microsoft guideline of not using "var" here.  You can probably get away with it 80% of the time and I won't care, but that other 20% is enough reason for me to not recommend getting into this habit.

Edit:  From a reply to Ilya's post by "Simon" we get a list of rules much closer to what I think makes sense.

  • Do use var for anonymous types
  • Do use var for initialization from constructors (var list = new List();)
  • Do use var for casts (var list = (IList)list;)
  • Consider using var where naming implies the type of the variable (var xmlSerializer = GetXmlSerializer();)

The last bullet point is the most controversial, but I can agree with it as long as developers are consciously considering the choice.  For the rest, I can see no reason to recommend not using "var" in any of those situations.

March 26

IoC I can live with

I've been working on that IoC container I've blogged about.  You know, the ultra-lightweight, delegate based at the root with reflection as optional, simple container.  While doing so, I've also been learning about some of the other capabilities in other containers.  One of the things I discovered was Guice and the "annotation" (that would be an attribute for us .NET developers) based configuration it uses.  By itself, not all that exciting as I'd already expected to use attributes for specifying what to inject.  But then I noticed that they allow you to annotate an interface.  Wow.  Now the following is working with my container.

ObjectContainer container = new ObjectContainer();
container.RegisterDynamicConstruction();
IFoo foo = container.Resolve<IFoo>();

No, nothing was left out there (other than the definition of IFoo and some other class that implements it).  I've done no configuration.  I just registered dynamic construction which allows the container to create types that haven't been registered by using reflection.  Then I instantiated an IFoo.  Resolve looked for a registered factory for IFoo, and when it didn't find one it looked at the attributes on IFoo to discover a "default" implementation type and instantiated that.  This eliminates 90% of what I dislike about IoC containers.  You don't have to specify a long list of configurations (in code or in some config file, doesn't really matter) to register types with the container even though 90% of the time you'll want the same type.  Why should I configure a container, just because I may want to mock a service out during testing?

Granted, I'm still specifying what types to create.  However, it's done in code, when defining the interface, and is applied any time I use that interface (unless overriden) in every application with out doing any further configuration.  Nearly nirvana.

Unity (as well as other containers) may have this capability... I haven't looked that close.  It does allow you to instantiate concrete types through reflection, which will still do injection, so it wouldn't surprise me too much if they went the extra few inches to this.  If not, I believe it could be trivially added through an extension. So, the only major difference with what I'm building is the complexity/size.  So there's probably not a lot of interest in what I'm building to other folks.  But I want it, and it's been a fun project for discovery.

March 17

Build Your Own IoC Container

A while ago, I wrote a blog that was critical of the Unity IoC container.  A lot of what I wrote I think still stands.  One complaint, though, does need a (partial) retraction.  I complained that Unity was reflection based instead of being delegate based.  Well, this is true of Unity proper, but the Unity project includes a StaticFactoryExtension which provides an extension to do delegate based construction.  This can be used like this:

container.Configure<IStaticFactoryConfiguration>().RegisterFactory<SqlConnection>(() => new SqlConnection());

This is very flexible, and does provide full functionality.  It's disappointing (to me) that the base functionality is reflection based, and an extension is required to use delegates (after all, the above syntax is a bit ugly), but at least the functionality is there.  Still not what I'd consider a "light weight" IoC container, and I'm still hoping to see some IoC interfaces in the BCL, but this isn't a bad container.

Anyway, because it's still not my ideal container and since I need a container for the M-V-Poo library I'm working on, I've been working on my own container.  I have a long way to go, to ensure the proper balance of features while maintaining a very lightweight code base, but I thought I'd share some of what I've come up with.  So, in this blog post I'm going to provide the basis for a lightweight container that you can extend into a container that fits your needs.  Before we begin, I'll point out that there are a couple of other simple containers you can find in other blogs.  This one is slightly different in design (and heavier), because I'm focusing on providing a lightweight container while still providing all of the plumbing necessary to extend it until it provides all of the same functionality as Unity and other larger containers.

I'll start with the container interface.  As I said in my critic of Unity, I'd prefer separate interfaces for both the locator and the container.  However, I'm keeping things simple here and providing only a single interface.  I'm also following some of the naming conventions from Unity, though this is not a clone of the Unity APIs.  When designing the interface for the container, I provided only the most verbose version of each function.  The other overloads are just convenience versions, and so I'm keeping them out of the interface.  That might sound odd right now, but you'll see in a moment that this is actually a fairly flexible design.  That said, here's the interface.

public delegate object ObjectFactoryCallback(IObjectContainer container);

public interface IObjectContainer
{
    IObjectContainer RegisterType(Type type, string name, ILifetimePolicy liftetime, ObjectFactoryCallback callback);
    object Resolve(Type type, string name);
    IEnumerable<object> ResolveAll(Type type);
}

Oh, there's an ILifetimePolicy type in there that we've not defined yet.  Let's look at it.

public interface ILifetimePolicy
{
    object GetValue(IObjectContainer conatiner, ObjectFactoryCallback callback);
}

If you've seen Unity, most of what's here should be obvious.  This is a minimalist design, with all of the fluff removed.  Further, you'll notice that RegisterType is delegate based instead of reflection based by the lack of a second Type parameter and the addition of an ObjectFactoryCallback delegate parameter.  So, we have a very simple interface design, now let's provide an implementation.

public sealed class ObjectContainer : IObjectContainer
{
    private class Registration
    {
        public Registration(ObjectFactoryCallback callback, ILifetimePolicy lifetime)
        {
            Callback = callback;
            LifetimePolicy = lifetime;
        }

        public ObjectFactoryCallback Callback { get; set; }
        public ILifetimePolicy LifetimePolicy { get; set; }
    }

    private ObjectContainer _parent;
    private Dictionary<Type, Dictionary<string, Registration>> _registry = new Dictionary<Type, Dictionary<string, Registration>>();

    public ObjectContainer()
    {
    }

    public ObjectContainer CreateChildContainer()
    {
        ObjectContainer child = new ObjectContainer();
        child._parent = this;
        return child;
    }

    #region IObjectContainer Members

    public IObjectContainer RegisterType(Type type, string name, ILifetimePolicy liftetime, ObjectFactoryCallback callback)
    {
        Dictionary<string, Registration> registrations;
        if (!_registry.TryGetValue(type, out registrations))
        {
            registrations = new Dictionary<string, Registration>();
            _registry[type] = registrations;
        }

        Registration registration = new Registration(callback, liftetime);
        registrations[name ?? string.Empty] = registration;

        return this;
    }

    public object Resolve(Type type, string name)
    {
        object result = TryResolve(type, name);
        if (result == null && _parent != null)
            result = _parent.Resolve(type, name);
        return result;
    }

    public IEnumerable<object> ResolveAll(Type type)
    {
        Dictionary<string, Registration> registrations;
        if (_registry.TryGetValue(type, out registrations))
        {
            foreach (Registration registration in registrations.Values)
            {
                yield return Resolve(registration);
            }
        }
    }

    #endregion

    private object TryResolve(Type type, string name)
    {
        Dictionary<string, Registration> registrations;
        if (!_registry.TryGetValue(type, out registrations))
            return null;

        Registration registration;
        if (!registrations.TryGetValue(name ?? string.Empty, out registration))
            return null;

        return Resolve(registration);
    }

    private object Resolve(Registration registration)
    {
        if (registration.LifetimePolicy != null)
            return registration.LifetimePolicy.GetValue(this, registration.Callback);
        return registration.Callback(this);
    }
}

There you go, a complete IoC container that can be easily extended to have the full capabilities of Unity and other containers.

OK, I won't leave you hanging.  Obviously when given just this, it seems like a very poor implementation.  Even for only a delegate based container, the convenience overloads are missing, which seems like it would make this awfully cumbersome to use.  And I'm sure several of you are confused about how you could possibly extend this container.  There's no built in extension mechanism, like there is in Unity, and the container is sealed, for Pete's sake.  Well, don't worry, I'll provide more.

First, I'll explain how to extend this.  Instead of derivation or a fancy extension mechanism, I'm going to use extension methods.  I created an ObjectContainerExtensions static class where I provided a host of extensions.  First, let's look at how you'd define some of the convenience overloads.

public static IObjectContainer RegisterType(this IObjectContainer self, Type type, ObjectFactoryCallback callback)
{
    return self.RegisterType(type, null, null, callback);
}
public static IObjectContainer RegisterType<T>(this IObjectContainer self, ObjectFactoryCallback callback)
{
    return self.RegisterType(typeof(T), null, null, callback);
}

Pretty simple, really.  From those two examples, you should be able to implement all of the the other convenience methods.  One very nice benefit here is that any IObjectContainer concrete type will get the added benefit of these methods with out having to implement anything.

OK, now what about instance registration?  We'll write another extension method for that, with a few convenience overloads (I'll leave the overloads as an exercise for the reader).

public static IObjectContainer RegisterInstance(this IObjectContainer self, Type type, string name, object instance)
{
    return self.RegisterType(type, name, null, c => instance);
}

This starts to show off the power of the delegate based approach.  Our concrete container only knows how to register a delegate, yet we've trivially implemented an extension method that allows you to register an instance.

Great, now what about adding reflection based registration?  How can I possibly do that with only a delegate based container?  Why, with some extension methods, of course.  I'll start with an InjectProperties method that's similar in usage to the BuildUp method in Unity.  It injects properties on an existing object by using reflection and looking for properties marked with an InjectAttribute (left as an exercise for the reader).

public static object InjectProperties(this IObjectContainer self, string name, object existing)
{
    Type type = existing.GetType();
    PropertyInfo[] properties = type.GetProperties();
    foreach (PropertyInfo propertyInfo in properties)
    {
        object[] inject = propertyInfo.GetCustomAttributes(typeof(InjectAttribute), true);
        if (inject != null && inject.Length > 0)
        {
            object value = self.Resolve(propertyInfo.PropertyType, name);
            propertyInfo.SetValue(existing, value, null);
        }
    }
    return existing;
}

Again, you can provide convenience overloads for this.

Now we have the functionality we need to do property injection via reflection, but we still need a way to do constructor injection.  Obviously the Resolve method should do this, but we can't extend that beyond providing special delegates when we register a type with the container.  So, I'll add a couple of private static methods that we'll use as the implementation of our delegates later on.  I'll also provide a private static method that can be used to create an ObjectFactoryDelegate that constructs a Type via reflection.

private static ConstructorInfo FindConstructor(Typetype)
{
    ConstructorInfo[] constructors = type.GetConstructors();
    if (constructors.Length == 0)
        throw newInvalidOperationException();

    ConstructorInfo constructorInfo = constructors[0];
    if (constructors.Length > 1)
    {
        int argCount = -1;
        bool injectFound = false;
        foreach (ConstructorInfo cur inconstructors)
        {
            object[] inject = cur.GetCustomAttributes(typeof(InjectAttribute), false);
            if (inject != nul l&& inject.Length > 0)
            {
                if (injectFound)
                    throw newInvalidOperationException();
                constructorInfo = cur;
                injectFound = true;
            }
            if (!injectFound)
            {
                ParameterInfo[] parameters = cur.GetParameters();
                if (parameters.Length > argCount)
                {
                    constructorInfo = cur;
                    argCount = parameters.Length;
                }
            }
        }
    }

    return constructorInfo;
}

private static object Create(IObjectContainer container, ConstructorInfo constructorInfo)
{
    ParameterInfo[] parameters = constructorInfo.GetParameters();
    if (parameters.Length == 0)
        return constructorInfo.Invoke(null);

    object[] parameterValues = new object[parameters.Length];
    for (int i = 0; i < parameters.Length; ++i)
    {
        parameterValues[i] = container.Resolve(parameters[i].ParameterType);
    }
    return constructorInfo.Invoke(parameterValues);
}

private static ObjectFactoryCallback TypeFactoryAdapter(Typetype)
{
    ConstructorInfo constructorInfo = FindConstructor(type);
    if (constructorInfo == null)
        throw new InvalidOperationException();

    return c =>
    {
        object result = Create(c, constructorInfo);
        return c.InjectProperties(result);
    };
}

Given this private implementation, we can now provide the RegisterType overloads for reflection based construction (again, most of the overloads are left for the reader to do).

public static IObjectContainer RegisterType(this IObjectContainer self, Type from, Type to, string name, ILifetimePolicy lifetime)
{
    return self.RegisterType(from, name, lifetime, TypeFactoryAdapter(to));
}

There you go, a lightweight container that provides a good portion of the functionality found in Unity.  There's plenty of room for improvement.  The code provided is not production worthy yet, and there's still functionality missing.  For instance, Unity will construct a type through reflection even if the type isn't registered with the container.  All you do is call Resolve with a concrete class type, and the container will construct it and do appropriate injections.  With the current code, it's non-trivial to do this, because we've hard-coded the reflection into our ObjectContainerExtensions class.  To keep this lightweight, I'd move that functionality out into it's own extension class, and put it into a different namespace.  This allows anyone to use the functionality when implementing extensions, but keeps them out of the normal view for consumers.

Oh, there's one final thing to illustrate.  You've seen the ILifetimePolicy interface, but how do you implement a policy?  Here's the requisite SingletonLifetimePolicy.

public class SingletonLifetimePolicy : ILifetimePolicy
{
    private object lockObject = new object();
    private object value;

    #region ILifetimePolicy Members

    public object GetValue(IObjectContainer container, ObjectFactoryCallback callback)
    {
        if (value == null)
        {
            lock (lockObject)
            {
                if (value == null)
                {
                    value = callback(container);
                }
            }
        }
        return value;
    }

    #endregion
}
I considered other designs here.  Initially, I just provided delegate adapters instead of providing an ILifetimePolicy.  This works great, but I think the usage would be a little foreign to a lot of C# developers who've never done any functional programming.  I also considered designing the ILifetimePolicy interface so that it had an Adapt method instead of a GetValue method.  This makes the API familiar to the user, but the policy developer still has to understand functional programming.  I'm thinking that might be the more appropriate compromise, since it removes the concern about user's reusing a policy instance in multiple RegisterType calls, which as you can see from the implementation above would simply not work.  With a functional design, it's not too difficult to provide implementations that are safe from this.  I'm pretty sure I'll go with that design in my own library, but I kept the implementation here simple, in order to not detract from the lessons meant to be learned.
March 13

Prism Drop 03-12-2008

In case you haven't heard, Prism has it's first drop available.  Prism is the Pattern's & Practices next take on "composite applications", which are a very specific form of M-V-Poo.  Obviously, I'm interested in M-V-Poo, especially as the patterns apply to WPF.  I've been tracking Prism for a while now, and I've commented on the spikes and other information leaked to us in the past, so some of you have some idea what to expect out of this post ;).  Well, I might surprise you a little, actually.

This drop of Prism, though not with out serious design problems from my point of view, actually is fairly promising.  One of the most important design criteria I had for a framework such as this was actually a design goal of Prism: that it be lightweight (not an all-imposing framework, limited "Prism stuff" footprint in your applications and limited number of abstractions with a small API surface area).  Looking at the StockTrader reference application's source, I'd say they've done a fair job with it.  In my opinion, the code for this application is a bit of a spaghetti mess.  It took me a while to understand the flow and relationships/responsibilities of the various classes.  I simply would have structured the code differently.  However, the lightweight nature of the emerging framework (it's not yet a framework) looks like it would allow for using the concepts in an application structure more like I would prefer (specifics one what I'd prefer aren't important here).

Currently, the reference application is leaning very heavily on the UnityContainer and Dependency Injection.  For those who have their own favorite DI container, don't fear, you're not locked into UnityContainer.  However, I still strongly believe that DI is overused, and there are certainly applications that would prefer to not have to deal with this concept at all.  So, I hope the emphasis on this pattern can be reduced.  At the very least, there should be no requirements for DI within the framework, even if the reference applications rely on it.  Since there's no framework yet, I can't say for sure wether or not there currently is such a dependency.

My one major complaint so far is that there's currently no solution to my one big complaint with WPF in general: event handling requires codebehind.  I'm a very firm believer that the declarative approach with strong data binding is the most important aspect of WPF and other competing technologies, such as XUL.  This enables very rapid UI development, and allows the UIs to be done by designers (using design tools) instead of developers (using code editors).  Not that I don't believe many people will fill both roles, mind you.  The one major failing with this in WPF from my point of view is that we don't have a useful equivalent to data binding for events.  In XAML, event handlers (and this includes command handlers) can only specify methods that exist in the codebehind.  There's a couple of problems with this.  First, the codebehind is very tightly coupled to the XAML (they are part of the same partial class!), which makes it awkward to maintain the separation between design and development.  In fact, it almost requires the designer to be enough of a developer to be able to create the handlers and implement them to call into the business objects.  Otherwise, the developer and designer can wind up in a situation where they step on each other's toes.  This isn't the end of the world, as we're still in a much better situation here than we've ever been in the past, but I want full separation!  Then there's the other problem with this, namely that a good portion of the time you want events to be handled by other objects and it's awkward even for one person to have to create little stub handlers in the codebehind just to bridge between the two.

The reference application punts here.  All the Views create stub event handlers in their codebehinds, which then raise specific events published from the View that the Presenters (or anyone else) can subscribe to.  Obviously this works, and is the easiest (and a very flexible) solution.  But the amount of tedious code required is depressing, even if you don't mind using codebehind, like I do.  This is the ONE thing I absolutely demand from an M-V-Poo framework.  (Actually, I'd much prefer a solution in WPF proper for this, but as long as we don't have a solution there, any M-V-Poo framework I'd choose to use would need to supply a solution.)  There were a few concepts that were included in the spikes, that aren't used in the reference application, that seemed to be attempts to address this issue.  In particular, I'm referring to the CommandDispatcher stuff.  Unfortunately, I found that to be a very poor answer.  First, it wasn't general enough, only allowing you to handle Commands (and RoutedUICommands at that, due to a reliance on the Name property in a way that I don't think is reliable, since I'm not aware of any requirements for this property to contain a unique value).  I demand a solution that will work with any event.

Wouldn't it be ideal if WPF proper included an EventBinding markup extension with capabilities similar to the Binding markup extension, but which created event bindings instead of data bindings?

<Button Click="{EventBinding Source={StaticResource MyBusinessObject}, Handler=OnButtonClicked}"/>

With this, M-V-Poo would be trivial to implement any way you decided you wanted to implement it.  Unfortunately, I don't believe it's possible to implement such a markup extension today, and thus it has to be implemented within WPF proper.  But oh how I wish we had this today!!!  If any WPF framework developers at Microsoft read this, please consider something like this and do anything you can to get it into this summer's service release!  If you want to discuss the concept, please reply here.

Any way, overall, even though Prism isn't the M-V-Poo I'd build, I think they're off to a better start than I originally gave them credit for.  It's very possible this will evolve into something that, even if it's not my M-V-Poo, it might allow me to implement my M-V-Poo.

February 13

Unity Project

Speaking about DI/IoC, Microsoft Patterns & Practices has just released an MSPL licensed DI container in the project Unity.  I must say, I'm disappointed.

Here's a list of things I think Unity did wrong.

  1. It's a P&P project, and not part of the BCL.  I'm not sure we need a full DI container in the BCL, but I do believe a lot of the interfaces should be there.
  2. They call this a "lightweight" container, but it contains two assemblies.  Doesn't sound too light weight to me.  I haven't fully looked into this yet, and it's possible one of the assemblies provides optional features layered on a basic container, in which case I'd have to retract what I just said in this point ;).
  3. The interfaces are designed incorrectly.  There's basically one interface, IUnityContainer, that's the driving interface.  Like mentioned, I'd prefer this in the BCL, with a more generic name, such as IObjectContainer.  Further, this should be split into two interfaces: the APIs to resolve instances should be separated from the APIs to configure a container, such as is done with IServiceProvider and IContainer in the BCL.
  4. Types are resolved through reflection.  At the basic level the container should be operating on "factory delegates" registered with the container.  This is the most flexible design, and also provides the best performance.  The reflective stuff can be built on top of this.  I'd layer it, so if you don't need it you don't have to include it, but I wouldn't argue to strongly if the container (and interfaces) provided both out of the box.  The fact that the factory delegate isn't present in the API at all, though, is a mistake.  Just as an example, this container doesn't provide support for per-thread scope, you only have Singleton (in two varieties... one where the user creates the instance and one where the container creates the instance) and per-call.  There's absolutely no way to change this, short of changing the container implementation.  If we had delegate factory registration, you wouldn't have this problem.
  5. There's still a lot of complexity here.  I want a lighter weight solution.

Over all, it's not a bad library, but it doesn't deliver what I believe we need.

February 06

Using ServiceContainer

OK, in my last post I promised to show you how to use the ServiceContainer.  I'm going to steal code from the Autofac home page, and rewrite it using ServiceContainer.

IServiceContainer container = new ServiceContainer();

container.AddService(typeof(IEngine),
   (c, t) => new Straight6TwinTurbo());

container.AddService(typeof(ICar),
   (c, t) => new Skyline(c.GetService(typeof(IEngine)), Color.Black));

ICar car = container.GetService(typeof(ICar));
car.DriveTo("Byron Bay");

Pretty darn similar.  Autofac uses a ContainerBuilder and a declarative coding style, but other than this they are very equivalent.  However, most containers allow you to specify the "scope", while the BCL ServiceContainer only provides Singleton scope, even when you supply a ServiceCreatorCallback, which is unfortunate.  So, although I'll be using IServiceProvider, I won't be able to use ServiceContainer, and may consider extending both IServiceProvider and IServiceContainer to account for generics and keyed access.

View more entries