Resolve Anything

  • January 3, 2010 10:36 am

Ward Bell, one of the most diligently pragmatic programmers out there, just wrote about bootstrapping Prism with containers other than Unity.

One of the pain points that Ward observes is Prism’s use of “resolve anything” – a Unity feature that causes the container to act as though all concrete types are registered.

// Works, even though Foo isn't registered,
// because Foo is concrete.
var container = new UnityContainer();
var foo = container.Resolve<Foo>();

Other containers have different behaivours – by default, Autofac will throw ComponentNotRegisteredException in this case.

I’m not a fan of Unity’s behaviour – I rarely use concrete types as services, and generally would want to configure them first anyway.

However, for those with different views, there are simple ways to make this work with Autofac.

Autofac 1.4 – RegisterTypesMatching()

Autofac 1.4 includes a configuration method that can help here. The parameter is a predicate on a requested Type, and if the result is true the container will happily resolve instances of the type.

var builder = new ContainerBuilder();
builder.RegisterTypesMatching(t => t.IsClass && !t.IsAbstract);
var container = builder.Build();

// Now works
var foo = container.Resolve<Foo>();

Autofac 2.1 – ResolveAnythingSource

Autofac 2 doesn’t have an equivalent to RegisterTypesMatching(). This is because Autofac 2′s assembly scanner, RegisterAssemblyTypes() does a much better job in similar scenarios.

Those who’ve been following along with this blog lately will have seen how registration sources provide a simple way to extend the container to understand new component types (like Lazy Dependencies.)

Well, the registration source to implement “resolve anything” is just a few lines, included here in its entirety. If you need this behaviour, feel free to include it in your project.

class ResolveAnythingSource : IRegistrationSource
{
    public IEnumerable<IComponentRegistration> RegistrationsFor(
        Service service,
        Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
    {
        var ts = service as TypedService;
        if (ts != null && !ts.ServiceType.IsAbstract && ts.ServiceType.IsClass)
        {
            var rb = RegistrationBuilder.ForType(ts.ServiceType);
            return new[] { RegistrationBuilder.CreateRegistration(rb) };
        }

        return Enumerable.Empty<IComponentRegistration>();
    }
}

Configuring the container to use the new source is easy.

var builder = new ContainerBuilder();
builder.RegisterSource(new ResolveAnythingSource());
var container = builder.Build();

// Works now
var foo = container.Resolve<Foo>();

One Small Caveat

You should probably be aware of one small gotcha that both of these samples exhibit. If you actually do register an implementation of Foo, then resolve all instances of Foo, you’ll find that both your registered component, plus the automatically-generated one, will be there. This is a very unlikely situation, but it might pay to keep it in mind.

If you found your way here looking for Autofac’s Prism integration, good news is right around the corner! The source for AutofacContrib.Prism is in the trunk, and just needs a few updates before it will get a proper release.

Parsing strings to System.Linq.Expression

  • January 3, 2010 8:57 am

The example included with the last post is probably a bit underwhelming, so I thought I’d include another.

LinqyCalculator

This variation on the “good old calculator example” takes a string input like 1 + 2 * (3 + 4) and produces an equivalent System.Linq.Expression that can be executed to get the numeric value.

You can also play around with the very minimal included error handling abilities.

Check out the code for the parser and the driver program.

Sprache C#

  • January 2, 2010 7:37 pm

No, I haven’t reverted to my ancestors’ tongue.* Sprache is a small library for parsing text from C#.

// Parse a number of capital 'A's in a row, e.g. "AAAA"
var parseA = Parse.Char('A').AtLeastOnce();

If you’ve spent any time with Haskell, you’ll be familiar with Parsec, a beautiful framework for building parsers in a functional manner.

Sprache is based on the same design (yes, the ‘m’ word applies here) ported to C# with some help from a couple of excellent tutorials.

I built Sprache as a learning exercise, but posted it to Google Code because there seems to be no other implementation with controlled source, an issue tracker, and a well-defined license. It could use some input from someone who really knows their stuff, so hopefully the public site will help find that person.

Check out the Sprache homepage for some examples and links.

*’Sprache C#’ as far as my limited German takes me, means ‘C# Language’.

Declarative Context Adapters in Autofac 2

  • January 1, 2010 10:39 am

The previous post on this blog showed how Autofac 2 can provide Lazy<T> dependencies whenever T is registered.

Other types that Autofac provides via the same mechanism are:

  • Func<T>, Func<T,U> &c., to create components on-the-fly;
  • Owned<T> to manually control the lifetime of a component;
  • IEnumerable<T> to get all implementers of a service; and
  • Instances of a particular generic type, e.g. IRepository<Customer>, when the open generic type, e.g. Repository<T>, is registered.

Each of these can be thought of as a declarative context adapter. Each of these types supports a scenario involving some kind of interaction between a component and the container that hosts it. Instead of having the component call the container directly, the component expresses requirements declaratively using these little adapter types, and the container provides the implementation.

Don’t worry if it is a stretch to imagine how each of these works. For today, we’ll examine the implementation of Lazy<T>, and that should give you enough background to figure out the others if you want to.

IRegistrationSource: a better Service Locator?

Context adapters like these are provided to Autofac via IRegistrationSources.

public interface IRegistrationSource
{
    IEnumerable<IComponentRegistration> RegistrationsFor(
        Service service,
        Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor);
}

A registration source is much like a Service Locator: when the container needs to provide service, it queries the registration source to get any available implementations.

The registration source can use the passed-in registrationAccessor to get information about other components registered with the container.

At first glance this seems to be a Service Locator plain and simple, however there is an important distinction. The IComponentRegistration‘s returned from RegistrationsFor() tell the container how to make components supporting the service. They are not instances of the services themselves.

This means that among other benefits, a registration source is called only once for any particular service (e.g. Lazy<IFoo>) no matter how many times the service is resolved. The performance overhead, compared with using a Service Locator this way, is very low.

LazyRegistrationSource

If you’re using Autofac on .NET 4.0, you can use LazyRegistrationSource (by registering LazyDependencyModule) to get support for the context adapter System.Lazy<T>.

LazyRegistrationSource is a very simple implementation of IRegistrationSource.

class LazyRegistrationSource : IRegistrationSource
{
    public IEnumerable<IComponentRegistration> RegistrationsFor(
        Service service,
        Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
    {
        var swt = service as IServiceWithType;
        if (swt == null ||
            !swt.ServiceType.IsGenericType ||
            swt.ServiceType.GetGenericTypeDefinition() != typeof(Lazy<>))
            return Enumerable.Empty<IComponentRegistration>();

        var valueType = swt.ServiceType.GetGenericArguments()[0];

        var valueService = swt.ChangeType(valueType);

        var registrationCreator = CreateLazyRegistrationMethod.MakeGenericMethod(valueType);

        return registrationAccessor(valueService)
            .Select(v => registrationCreator.Invoke(null, new object[] { service, v }))
            .Cast<IComponentRegistration>();
    }

    static readonly MethodInfo CreateLazyRegistrationMethod = typeof(LazyRegistrationSource)
        .GetMethod("CreateLazyRegistration", BindingFlags.Static | BindingFlags.NonPublic);

    static IComponentRegistration CreateLazyRegistration<T>(
        Service providedService,
        IComponentRegistration valueRegistration)
    {
        var rb = RegistrationBuilder.ForDelegate(
            (c, p) => {
                var context = c.Resolve&ltIComponentContext>();
                return new Lazy<T>(() => (T)c.Resolve(valueRegistration, p));
            })
            .As(providedService);

        return RegistrationBuilder.CreateRegistration(rb);
    }
}

Let’s break this down.

RegistrationsFor()

The whole purpose of RegistrationsFor() is to map a service to components that can provide it:

public IEnumerable<IComponentRegistration> RegistrationsFor(
    Service service,
    Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{

In LazyRegistrationSource we’re looking for services that are based on the Lazy<T> type.

So, the first part of RegistrationsFor checks to see if the service fits this description, and if not, the method returns an empty list of components, since it can’t provide anything.

var swt = service as IServiceWithType;
if (swt == null ||
    !swt.ServiceType.IsGenericType ||
    swt.ServiceType.GetGenericTypeDefinition() != typeof(Lazy<>))
    return Enumerable.Empty<IComponentRegistration>();

If we get past this test, then we know we’re dealing with Lazy<T>. Since we provide Lazy<T> on top of T, we extract T and construct a Service with it so that we can find implementations.

var valueType = swt.ServiceType.GetGenericArguments()[0];
var valueService = swt.ChangeType(valueType);

Lazy<T> is a generic type, but we’re deep in the land of reflection here. Rather than clog our code up with tonnes of reflective goop, we use a generic method parameterised on T to switch over into strongly-typed code to create a registration for Lazy<T>.

var registrationCreator = CreateLazyRegistrationMethod.MakeGenericMethod(valueType);

We’ll come back to the implementation of CreateLazyRegistration in just a second.

Once we have a method that can create a IComponentRegistration for Lazy<T> based on a component registration for T, we use registrationAccessor to find all the T registrations, and use our function to map them to a result.

return registrationAccessor(valueService)
    .Select(v => registrationCreator.Invoke(null, new object[] { service, v }))
    .Cast<IComponentRegistration>();

Now to the implemenation behind registrationCreator.

CreateLazyRegistration

This method takes an IComponentRegistration for T and wraps it in an IComponentRegistration for Lazy<T>. The providedService parameter is the service that our registration is going to provie to the container (some kind of service based on Lazy<T>.)

static IComponentRegistration CreateLazyRegistration<T>(
    Service providedService,
    IComponentRegistration valueRegistration)
{

Autofac 2 provides some helpers for creating registrations. The syntax below is the implementaiton equivalent of calling Register((c, p) => ...).As(providedService) on a ContainerBuilder.

var rb = RegistrationBuilder.ForDelegate(
    (c, p) => {
        var context = c.Resolve<IComponentContext>();
        return new Lazy<T>(() => (T)c.Resolve(valueRegistration, p));
    })
    .As(providedService);

return RegistrationBuilder.CreateRegistration(rb);

Some noteworthy points stick out:

  • The context is re-resolved from c, since we need the underlying context and not the temporary one used for the current operation;
  • We’re using a new Resolve() overload that takes an IComponentRegistration; and
  • We forward the parameters p on to the value resolve call, so that parameters passed when resolving Lazy<T> will be available to T.

Wrapping Up

This isn’t the kind of code you’ll write day-to-day when using Autofac 2. What’s exciting though, is how easy it can be to write sophisticated IoC-driven applications without having infrastructure concerns scattered through your code.

Next time you hear the question “but how do I do X without calling the container directly?” remember that there’s probably a declarative context adapter for that, based on IRegistrationSource.

Lazing Around with Autofac2

  • December 31, 2009 11:43 pm

.NET 4.0 includes two handy little classes, Lazy<T> and Lazy<T, TMetadata>.

Lazy<T> represents a value that is initialised the first time it is accessed.

// No counting done here
var lineCount = new Lazy<int>(() => CountLines("bigfile.txt"));

// Count happens when value is accessed
Console.Write(lineCount.Value);

// No counting here either - once the value is initialised it is stored
Console.Write(lineCount.Value);

Lazy<T, TMetadata> works exactly the same way as Lazy<T>, but adds a Metadata property that can be used to get information about the value before it is instantiated.

var filename = "bigfile.txt";

// The filename passed in the constructor is stored in the Metadata property
// of type string
var lineCount = new Lazy<int, string>(() => CountLines(filename), filename);

// Metadata (i.e. the filename) can be accessed without causing the value to be initialised
Console.Write(lineCount.Metadata);

Metadata becomes very useful when you have more than one lazy item, and need to choose between them before accessing and initialising the value.

Lazy Dependencies

Components in an IoC container can use the lazy types to express dependencies, and thus delay the construction of part of the object graph either for functional or performance reasons.

One of the very nice features of the Managed Extensibility Framework (MEF) in .NET 4.0 is the way lazy dependencies are handled. An ‘import’ (MEF terminology) of type Lazy<T> will be injected automatically so long as T is registered with the CompositionContainer.

In Autofac’s latest 2.1 beta,  an extension called LazyDependencyModule gives a similar result.

Autofac 2 still supports .NET 3.5. The only Autofac assembly that requires .NET 4.0 is Autofac.Integration.Mef.dll, while all others target .NET 3.5.

Simple Lazy<T> Example

Let’s imagine that in our particular ASP.NET application, creating repositories is fairly expensive. In some of the code paths through ContactsController we don’t use the injected contacts repository, and would like to avoid the cost of instantiating it.

Yes dear reader, you need to use your imagination here rather than a profiler… :)

To communicate this requirement to Autofac, you use Lazy<IContactRepository> as the type of the controller constructor parameter:

public class ContactsController : Controller
{
    Lazy<IContactRepository> _contacts;

    public ContactsController(Lazy<IContactRepository> contacts)
    {
        _contacts = contacts;
    }

    public ActionResult Show(int contactId)
    {
        ViewData.Model = _contacts.Value.Load(contactId);
        return View();
    }
}

When configuring your Autofac ContainerBuilder, add the LazyDependencyModule from Autofac.Integration.Mef.dll.

var builder = new ContainerBuilder();

builder.RegisterModule(new LazyDependencyModule());

// No special configuration for the controller...
builder.RegisterType<ContactsController>().Named<IController>("controller.contacts");

// ...or the repository.
builder.RegisterType<ContactRepository>().As<IContactRepository>();

And that’s it! Wherever Lazy<T> is resolved, Autofac will do the right thing.

Using Metadata

I’ve included downloadable code for a more complete example Lazy in Autofac 2 demonstrating metadata use.

The Log component accepts a list of appenders, each with metadata. Based on the logging request, the logger selects an appender (instantiating if necessary) and writes a message to it.

public class Log
{
    readonly IEnumerable<Lazy<ILogAppender, ILogAppenderMetadata>> _appenders;

    public Log(IEnumerable<Lazy<ILogAppender, ILogAppenderMetadata>> appenders)
    {
        _appenders = appenders;
    }

    public void Write(string destination, string message)
    {
        var appender = _appenders.First(a => a.Metadata.AppenderName == destination);
        appender.Value.Write(message);
    }
}

You can see in this example how Autofac 2′s automatic support for IEnumerable dependencies works just as well combined with laziness.

The metadata view ILogAppenderMetadata has a single property AppenderName. The value of this property will be retrieved from the implementing component’s extended properties.

builder.Register(c => new ScreenAppender())
    .As<ILogAppender>()
    .WithMetadata("AppenderName", "screen");

Binding of ILogAppenderMetadata to the underlying dictionary of extended properties is done using the same mechanism as MEF uses, and you can find more information on that via the MEF site.

Under the Hood

If you’re interested to see how easy Autofac 2 makes supporting these ‘context adapters’, check out the implementation handling Lazy<T, TMetadata>, weighing in at 52 lines including braces, using statements and whitespace :)

Downloads

First Autofac 2 Beta Available

  • December 31, 2009 6:59 pm

What does beta mean? Here are the good things you can expect from Autofac 2.1.5:

  • Everything you need to build a working application is in there
  • All the tests that should pass, pass
  • If you find bugs, they’ll be fixed
  • Between now and the full release, API breakage will be taken seriously

You should also be aware that:

  • There will be some bugs
  • Documentation on the wiki doesn’t reflect the new version
  • There’s no matching AutofacContrib release yet
  • Upgrading an existing application will take a little time

Long-time Autofac users will find the new version a bit strange at first, but the most visible differences are name changes. There’s a summary of API changes on the wiki.

I hope you have fun test-driving the new version. You can get the binaries from the Autofac downloads page.

Autofac 2 Status Update

  • December 24, 2009 10:34 pm

Revision: 398Autofac 2 Sketch
Author: nicholas.blumhardt
Date: 8:06:55 AM, Monday, 21 July 2008
Message:
Added 2.0-experimental branch for exploration of internal refactorings.

Yes, work on Autofac 2 began a year and a half ago! While work all but stopped while I did other things in Redmond, I’m pleased to say that a beta is finally in sight.

You might be curious just how close is ‘close’: there are six items in the issue tracker that I think need to be addressed:

  • 98 Support named registrations for open generics
  • 140 Cache constructor bindings in ReflectionActivator
  • 150 Human-readable display strings and [DebuggerDisplay]
  • 154 Update ConfigurationSettingsReader (XML Config Support)
  • 155 Update contrib and examples to 2.1
  • 160 Scan assemblies for modules

Most of these are pretty unexciting – minor features, niceties and dependent project updates.

Issue 98, however, has been in the system a while. One of the core improvements in Autofac 2 makes it easier and much more efficient to add support for dynamically-generated component registrations.

As an example, if IFoo is registered, Autofac provides or can be extended to provide:

  • Owned<IFoo> for explicit ownership/Iifetime control
  • Func<IFoo> for dynamically creating IFoo components
  • Lazy<IFoo> and Lazy<IFoo, IFooMetadata> for lazy instantiation

These can even be composed automatically to give Func<Owned<IFoo>> and so-on.

Under the hood, each extension is a handler that can look at a requested Service, query other available services, and generate a component on-the-fly that is able to fulfill the request.

The same underlying mechanism supports open generic types.

builder.RegisterGeneric(typeof(Bar<>)).As(typeof(IBar<>));

var container = builder.Build();

container.Resolve<IBar<int>>();

The handler checks to see if the requested Service is a closed instance of the open generic service type it is watching for (IBar<>). If it is, the handler creates a regular component by closing the generic component type (Bar<> becomes Bar<int>), and from that point on the container will used the closed type to provide that particular closed service.

Now, all is well-and-good if the service is requested by type, as in Resolve<IFoo>().

Autofac uses NamedService and TypedService to represent services requested by name and by type respectively. When a component is resolved by name, as in Resolve<IFoo>(“foo”), the dynamic registration handlers get an instance of NamedService { ServiceName = “foo” }.

NamedService, in Autofac 1.x and Autofac 2 today, doesn’t carry type information, just a string, so while Resolve<IFoo>(“foo”) succeeds, there’s no way to automatically support Resolve<Func<IFoo>>(“foo”) – the handler can’t see that the returned object should be of type Func<IFoo>.

And that is at the crux of issue 98. Adding type information to NamedService doesn’t seem like a big deal, but it does touch a lot of APIs and will break some existing apps in potentially confusing ways. It may be that issue 98 is put to the side this time around. Either way a decision has to be reached before Autofac 2 can be released as a beta.

Stay tuned, and have a safe holiday if you’re lucky enough to be taking one!

One blog to rule them all…

  • December 5, 2009 12:17 pm

Welcome to my new blog, perhaps a little more permanent than my last two. If you’re looking for something to read while I work on new content for this site, why don’t you take a walk down memory lane with some of my earlier articles?

Implementing the Specification Pattern with Linq – a great data access pattern for domain-driven .NET applications. Follow up with some really interesting additions from Luke Marshall, Rinat Abdullin, Steven Burman and Fredrik Kalseth.

State Machines in Domain Models – a primer on the Stateless hierarchical state machine framework. The title is a bit vague – Stateless is useful wherever a problem can be modelled in terms of states and transitions. Follow up with a look at the new features in version 2.

Implementing Optional Exports with MEF Stable Composition – if you’re working with the Managed Extensibility Framework, you need to understand Stable Composition (and how to debug it!)

Where does the Container Belong? – in answer to what is becoming an age-old question of IoC container users. Leads in to a discussion on context dependencies, and the foundation for declarative context adapters like Autofac’s generated factories and MEF’s PartCreator.

And I hear you ask… Where is Autofac in all of this? Much of my recent hiatus from writing owes to work on version 2. You can follow progress on the mailing list, or watch a summary of changes evolve. For those not familiar with the project, the introductory article on CodeProject still applies.

Ciao!