In Ninject 2, how do I have two cores with different settings binding settings?

I have one Ninject 2 core for my application that contains all the bindings. One application section must have different settings in the kernel than the rest of the application, but it needs the same bindings (this part is for NHibernate and needs to be configured InjectNonPublic = trueand InjectAttribute). How to make a kernel that shares bindings with the current kernel, but has different settings?

I believe that in other IOC containers this will be achieved using a "nested container", however, I do not see support for nested containers in Ninject?

+3
source share
2 answers

. , , , NHibernate. , Ninject internal IOC .

, Ninject ISelector , . , ( , ). SelectConstructorsForInjection().

public class HydratingSelector : DisposableObject, ISelector
{
    private readonly ISelector standardSelector;
    private const BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;

    public HydratingSelector(IConstructorScorer constructorScorer,
                             IEnumerable<IInjectionHeuristic> injectionHeuristics)
    {
        standardSelector = new Selector(constructorScorer, injectionHeuristics);
    }

    public IEnumerable<ConstructorInfo> SelectConstructorsForInjection(Type type)
    {
        if(Settings.GetHydratedTypeSelector()(type))
        {
            var constructors = type.GetConstructors(Flags);
            return constructors.Length != 0 ? constructors : null;
        }

        return standardSelector.SelectConstructorsForInjection(type);
    }

    // Omitted implementations of other methods that just forward to standardSelector
}

, InjectNonPublic = true . InjectAttribute . , HydratingConstructorScorer :

public class HydratingConstructorScorer: DisposableObject, IConstructorScorer
{
    private readonly IConstructorScorer standardScorer = new StandardConstructorScorer();

    public int Score(IContext context, ConstructorInjectionDirective directive)
    {
        if(Settings.GetHydratedTypeSelector()(directive.Constructor.DeclaringType)
            && directive.Constructor.HasAttribute(Settings.GetHydrateAttribute()))
            return int.MaxValue;

        return standardScorer.Score(context, directive);
    }

    // Omitted implementations of other methods that just forward to standardSelector
}

, ​​ :

public class HydratingKernel : StandardKernel
{
    public HydratingKernel(params INinjectModule[] modules)
        : base(modules)
    {

    }

    public HydratingKernel(INinjectSettings settings, params INinjectModule[] modules)
        : base(settings, modules)
    {
    }

    protected override void AddComponents()
    {
        base.AddComponents();
        SetupComponentsForHydratingKernel(Components);
    }

    internal static void SetupComponentsForHydratingKernel(IComponentContainer components)
    {
        components.RemoveAll<ISelector>();
        components.Add<ISelector, HydratingSelector>();
        components.RemoveAll<IConstructorScorer>();
        components.Add<IConstructorScorer, HydratingConstructorScorer>();
    }
}
+1

Source: https://habr.com/ru/post/1767910/


All Articles