Home » 2011 » February

Monthly Archives: February 2011

How to completely disable Autofac components

This week I started working with the Autofac Inversion of Control container at the Day Job. The first project I tried to introduce Autofac to needed a plugin system. I figured this was a perfect use of Autofac’s implicit relationship handlers. Sure enough, a

container.Resolve<IEnumerable<IPlugin>>()

did the trick – I got a nice list of plugin instances for the application to use.

This isn’t enough, though. We need to disable certain components via configuration. One option would be to remove the components from the configuration file, but I wanted to make it easy to restore the plugins (and their original configuration) should the need arise. After poring over the Autofac documentation, it seemed like adding an “Enabled” flag in the components’ metadata would be the best way to handle toggling them between on and off.

Setting up the config file was straightforward,

<autofac defaultAssembly="DisableComponents">
  <components>
    <component type="DisableComponents.Plugin1" service="DisableComponents.IPlugin">
      <metadata>
        <item name="Enabled" value="false" type="System.Boolean" />
      </metadata>
    </component>
    <component type="DisableComponents.Plugin2" service="DisableComponents.IPlugin">
      <metadata>
        <item name="Enabled" value="true" type="System.Boolean" />
      </metadata>
    </component>
  </components>
</autofac>

as was filtering the components list.

var enabledComponents = container.Resolve<IEnumerable<Meta<IPlugin>>>()
    .Where(ComponentIsEnabled)
    .Select(c=>c.Value);

...

private static bool ComponentIsEnabled<T>(Meta<T> component)
{
    const string enabled = "Enabled";
    return !component.Metadata.ContainsKey(enabled) || (bool)component.Metadata[enabled];
}

They’re still created, though

This approach worked, but all all components are instantiated, including the disabled ones which are made just so we can throw them away. This seems a little wasteful. Worse, a particular installation may have a plugin disabled because it can’t (or doesn’t want to) support its creation. So I sought a way to prevent the instantiation of the unwanted plugins.

I tried to find a way to remove or disallow registration based on the metadata, or to intercept component creation, but came up short. The best I could come up with was a modification to the approach above:

var enabledComponents = container.Resolve<IEnumerable<Meta<Func<IPlugin>>>>()
    .Where(ComponentIsEnabled)
    .Select(c=>c.Value());

(I would have preferred to use a Lazy over a Func, but I’m working with .Net 35.)

This works—the plugins are only created when they’re enabled—but it feels inelegant.
I can’t help but think that my Autofac knowledge is too shallow to have discovered the “right” way to do this. Hopefully deeper understanding will come in time…

Growing an MVVM Framework in 2003, part V – Reflections and Regrets

This post is from a series on my experiences starting to grow an MVVM Framework in .NET 1.1.

Full source code can be found in my Google Code repository.

I haven’t added any articles to this series in a while. The main reason is that I’ve not done any more work on the framework. I was able to complete my application using the tools using the Framework So Far, and I’ve long since moved on to other projects. I wanted, though, to take a quick look back and evaluate the project.

I did it!

Way back in part 1, I said that I wanted to create an application that

  • had testable logic, even in the GUI layer,
  • had no “codebehind” in the view, and
  • shunted the tedious wiring up of events and handlers into helpers (or a “framework”)

I’m very pleased with how all this turned out. Taking things in reverse order:

  • The little framework does an excellent job of handling the tedious event-wiring. Handling an View event requires nothing more than declaring a method with a convention-following name and the correct signature, such as
    public void FindClick(object sender, EventArgs e)

    Properties are wired up in a similar way, by declaring a public field with a convention-following name and an appropriate type (StringProperty, BoolProperty, or ListProperty).

  • Aside from setting some properties on View elements (for example, the Find button is initial disabled), there was no need to crack open the View’s .cs file – I never saw the inside of it.
  • The easily-invoked event handlers and the property bindings made writing unit test as easy as writing tests for a non-GUI component: set some initial properties, poke the ViewModel by invoking an event handler, and check the properties. Done! Injecting mock model components was the hardest thing, and that’s no different than in any other test.

If only I had

There was one nagging problem that I left unresolved. My Model contains only synchronous operations, so the View doesn’t update while we’re accessing the data store. As it turns out, the operations are very quick, so the user is unlikely to notice.

I could have implemented asynchronous operations on the view, or used delgates or background threads to explicitly invoke the model in the background. I really would’ve liked to implement something that would be applicable to a larger problem set. Something like Caliburn.Micro’s IResult and Coroutines:
Returning an IResult or a collection of them to be executed on background threads by the framework, while the GUI updates and the ViewModel is none the wiser.

Ah well, time was running out, and there didn’t seem to be that much benefit. Maybe next time…

I would have liked to

There are a few other “features” that I would’ve liked to add to the framework, but there wasn’t time, nor did there seem to be an immediate need:

  • a View binder — After writing a class to bind the ViewModel to the fake storage properties, I realized that that was a nicer approach than having the binding code in the ViewModelBase. I’d like create a “production binder” to hook up the ViewModel and View.
  • composable ViewModels — BookFinder is very simple, with only a TextBox and a few ListBoxes and Buttons on its View, so a single View and ViewModel was sufficient. It would be useful to be able to build up a more complicated GUI by walking a tree of ViewModels and composing a GUI out of corresponding View components.
  • deregistering event handlers — The framework registers event handlers between the ViewModel and View, with no provision for unregistering them when components are no longer neeed. In BookFinder, the single View/ViewModel pair hang around until the application is closed, but in a more complicated application there might be an opportunity to leak resources.

Summing up

I’m happy with how the framework and tool turned out. I could probably have written the application more quickly if I hadn’t bothered trying to extract the framework, but it wouldn’t have been as testable (and therefore likely not as well tested). I think the extra effort was worthwhile both because it created a better application and because I learned more about WinForms programming and how I can leverage conventions to reduce programmer workload – if the framework were used for a second application, development would just fly. And the exercise was fun. Not only writing the framework, but using it — it’s extremely liberating having event handlers just work by creating a properly-named method, and having the handler be immediately testable is a joy. If I had any expectations that I’d be writing similar tools on .NET 1.1 again, I’d definitely continue extending the framework.

)

There. I feel better.