Extensibility

Jan 13, 2010 at 6:46 PM

Here's what I want to do.  I want to observe every registration that comes through Ninject.  If the reg meats certain requirements, I want to alter the reg, essentially by adding a custom provider to replace the default provider. This is because in certain situations, I want to delegate the instantiation to DynamicProxy.  My implementation of the proxy factory along with all metadata and methods of determining whether or not interception should occur must not dependent on Ninject.  I've found a way to do this with every major IoC container, but I'm struggling with Ninject.  Can anyone assist?

Jan 13, 2010 at 11:40 PM

Ok. I figured it out.  I was quite simeple.  Remove the IInjectorFactory from the Kernel's components and add a custom factory.  Here's how:

Kernel.Components.RemoveAll<IInjectorFactory>();
Kernel.Components.Add<IInjectorFactory, ProxyInjectorFactory>();
public class ProxyInjectorFactory : IInjectorFactory
{
    private readonly DynamicMethodInjectorFactory _inner = new DynamicMethodInjectorFactory();

    public void Dispose()
    {
        _inner.Dispose();
    }

    public INinjectSettings Settings
    {
        get { return _inner.Settings; }
        set { _inner.Settings = value; }
    }

    public ConstructorInjector Create(ConstructorInfo constructor)
    {
        var type = constructor.DeclaringType;
        var behaviors = type.GetAttributes<IBehavior>(true).ToArray();

        return behaviors.Length > 0
                   ? new ConstructorHelper(constructor.DeclaringType, behaviors).CreateConstructor
                   : _inner.Create(constructor);
    }

    public PropertyInjector Create(PropertyInfo property)
    {
        return _inner.Create(property);
    }

    public MethodInjector Create(MethodInfo method)
    {
        return _inner.Create(method);
    }

    private class ConstructorHelper
    {
        private readonly Type _implementation;
        private readonly IBehavior[] _behaviors;

        public ConstructorHelper(Type implementation, IBehavior[] behaviors)
        {
            _implementation = implementation;
            _behaviors = behaviors;
        }

        public object CreateConstructor(params object[] args)
        {
            var factory = ServiceLocator.Current.GetInstance<IProxyFactory>();
            return factory.CreateProxy(
                _implementation,
                _behaviors,
                args
                );
        }
    }
}