As you found out for yourself, what comes closest to doing something on instanciation for every binding - without requiring the binding to be altered - is an IActivationStrategy.
for example (example taken from here:
public class StartableStrategy : ActivationStrategy
{
public override void Activate(IContext context, InstanceReference reference)
{
reference.IfInstanceIs<IStartable>(x => x.Start());
}
public override void Deactivate(IContext context, InstanceReference reference)
{
reference.IfInstanceIs<IStartable>(x => x.Stop());
}
}
which is added to the ninject kernel the following way:
kernel.Components.Add<IActivationStrategy, StartableActivationStrategy>();
Alternative - binding syntax sugar
let me go into more detail about the OnActivation()
extension i mentioned in the comments:
public static IBindingOnSyntax<T> RegisterEvents<T>(this IBindingOnSyntax<T> binding)
{
// todo check whether <T> implements the IHandle<> interface, if not throw exception
return binding
.OnActivation((ctx, instance) => ctx.Kernel.Get<EventAggregator>().Subscribe(instance));
}
this you would employ manually to the binding:
kernel.Bind<FooViewModel>().ToSelf()
.RegisterEvents()
.InSingletonScope();
(the InSingletonScope()
isn't needed - it's just to show that you can use the other binding extensions/features as before).
Now i think you want to employ this rather "by convention". If you create your bindings by convention (ninject.extensions.conventions), you can use an IBindingGenerator
to create the binding accordingly (with or without the call to RegisterEvents
). If not, it get's trickier. I'd say you'd have to extend ninject's pipeline.