Autofac OnActivated for all registrations

Nowadays, I’m working with WPF using MVVM pattern. To manage NHibernate session in viewmodels, I’m using the approach shown by Ayende, where session is a property of viewmodel. The problem is simple – sessions need to be disposed of and replaced after they throw an exception. That means we cannot use constructors to inject sessions to viewmodels. Due to architectural constraints, I also do not want all the viewmodels to reference session factory. I chose to inject Func<ISession> to every derivative of a base ViewModelBase class as a property.

Now how to set this up with Autofac? We could use OnActivated method for every viewmodel registration, but that would be a lot of repetitive code. Refactoring it to a custom registration method does not satisfy me either – it’s not foolproof and I want to inject things to ALL of the derivatives of ViewModelBase.

The working solution that I found looks like this:

var builder = new ContainerBuilder();
builder.RegisterCallback(x =>
	x.Registered += (sender, args) =>
		args.ComponentRegistration.Activated += (o, eventArgs) =>
			if (eventArgs.Instance is ViewModelBase)
				var viewModel = eventArgs.Instance as ViewModelBase;
				viewModel.SessionFactory = eventArgs.Context.Resolve<Func<ISession>>();

So what this code does is add an Activated event handler (just like OnActivated method) to every single registration that Autofac container is aware of. Any time an object is created by the container, this handler will run and you can modify it as needed.

It actually even works good so far even when resolving concrete types using AnyConcreteTypeNotAlreadyRegisteredSource:

var builder = new ContainerBuilder();
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());

This registration source allows us to ask Autofac to resolve a concrete type without the need to register it upfront.

So with the approach demonstrated in this post, we can get a truly global OnActivated alternative.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s