Programming Languages Hacks

Importanti regole per linguaggi di programmazione rilevanti come Java, C, C++, C#…

  • Subscribe

  • Lettori

    I miei lettori abituali

  • Twitter

Ninject: Replace without unbind

Posted by Ricibald on August 10th, 2012

In Ninject the method Rebind<T> does the following:

  • Unbind<T>: removes all binding for that types, also named binding!
  • Bind<T>: add the specified binding

This means that using Rebind<T>().To<U>().Named(“X”) you are not just replacing the binding named “X” but you are clearing all existing binding registered with T!

If you want to just replace it just use this:

Bind<T>().To<U>.Named("X").ReplaceExisting();

 

Here the source code to achieve this (works in Ninject 2+):
 

using System.Linq;
using Ninject.Planning.Bindings;
using Ninject.Syntax;

// ReSharper disable CheckNamespace
namespace System
// ReSharper restore CheckNamespace
{
    public static class ExtensionsNinject
    {
        /// <summary>
        /// Replace existing binding.
        /// To replace a binding you should never use rebind becauses unbind all existing
        /// binds and then bind yours.
        /// You should first configure the entire binding using Bind and only as last 
        /// operation you should declare to replace it using this method.
        /// </summary>
        public static void ReplaceExisting<T>(this IBindingInSyntax<T> bindingInSyntax)
        {
            ReplaceExistingImpl<T>(bindingInSyntax);
        }

        /// <summary>
        /// Replace existing binding.
        /// To replace a binding you should never use rebind becauses unbind all existing
        /// binds and then bind yours.
        /// You should first configure the entire binding using Bind and only as last 
        /// operation you should declare to replace it using this method.
        /// </summary>
        public static void ReplaceExisting<T>(this IBindingOnSyntax<T> bindingInSyntax)
        {
            ReplaceExistingImpl<T>(bindingInSyntax);
        }

        /// <summary>
        /// Replace existing binding.
        /// To replace a binding you should never use rebind becauses unbind all existing
        /// binds and then bind yours.
        /// You should first configure the entire binding using Bind and only as last 
        /// operation you should declare to replace it using this method.
        /// </summary>
        public static void ReplaceExisting<T>(this IBindingWhenSyntax<T> bindingInSyntax)
        {
            ReplaceExistingImpl<T>(bindingInSyntax);
        }

        private static void ReplaceExistingImpl<T>(IBindingSyntax bindingInSyntax)
        {
            var kernel = bindingInSyntax.Kernel;
            var bindingsToRemove = kernel.GetBindings(typeof(T)).Where(b => string.Equals(b.Metadata.Name, bindingInSyntax.BindingConfiguration.Metadata.Name, StringComparison.Ordinal));
            foreach (var bindingToRemove in bindingsToRemove)
            {
                kernel.RemoveBinding(bindingToRemove);
            }
            
            var binding = new Binding(typeof(T), bindingInSyntax.BindingConfiguration);
            kernel.AddBinding(binding);
        }
    }
}

Leave a Reply

You must be logged in to post a comment.