I am looking to intercept the creation of instances that implement a certain interface, or have a certain attribute. I am able to do something similiar with the interception extension, but that only seems to do method and property interception.
Here is how I can intercept method and property calls, but it doesn't intercept the constructor call:
_kernel.Bind<IInterceptor>().To<LogInterceptor>().InSingletonScope();
_kernel.Intercept(x =>
{
if (x.Plan.Type.GetInterface(typeof(ITriggerLoggingInterception).FullName) != null)
{
return true;
}
return false;
}).With<LogInterceptor>();
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.