diff --git a/src/Ninject.Extensions.ChildKernel.Test/ChildKernelTest.cs b/src/Ninject.Extensions.ChildKernel.Test/ChildKernelTest.cs
index cd8a972..7f38568 100644
--- a/src/Ninject.Extensions.ChildKernel.Test/ChildKernelTest.cs
+++ b/src/Ninject.Extensions.ChildKernel.Test/ChildKernelTest.cs
@@ -31,13 +31,66 @@ namespace Ninject.Extensions.ChildKernel
using Ninject.Parameters;
using Ninject.Planning.Bindings;
using Ninject.Planning.Bindings.Resolvers;
+ using Ninject.Selection;
+ using Ninject.Syntax;
using Xunit;
-
+
+ public class ChildKernelTestWithIResolutionRoot : BaseChildKernelTest
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ChildKernelTestWithIResolutionRoot()
+ {
+ this.parentKernel = new StandardKernel();
+ this.testee = new ChildKernel((IResolutionRoot)this.parentKernel);
+ }
+ }
+
+ public class ChildKernelTestWithParentAndSettings : BaseChildKernelTest
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ChildKernelTestWithParentAndSettings()
+ {
+ this.parentKernel = new StandardKernel();
+ this.testee = new ChildKernel(this.parentKernel, this.parentKernel.Settings);
+ }
+ }
+
+ public class ChildKernelTestWithComponents : BaseChildKernelTest
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ChildKernelTestWithComponents()
+ {
+ this.parentKernel = new StandardKernel();
+ this.testee = new ChildKernel(
+ this.parentKernel,
+ this.parentKernel.Settings,
+ this.parentKernel.Components);
+ }
+ }
+
+ public class ChildKernelTestWithOnlyKernel : BaseChildKernelTest
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ChildKernelTestWithOnlyKernel()
+ {
+ this.parentKernel = new StandardKernel();
+ this.testee = new ChildKernel(this.parentKernel);
+ }
+ }
+
///
/// Tests the implementation of .
///
- public class ChildKernelTest
+ public abstract class BaseChildKernelTest
{
///
/// Name parent's foo.
@@ -62,21 +115,12 @@ public class ChildKernelTest
///
/// The object under test.
///
- private readonly IKernel testee;
+ protected IKernel testee;
///
/// The parent kernel.
///
- private readonly IKernel parentKernel;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public ChildKernelTest()
- {
- this.parentKernel = new StandardKernel();
- this.testee = new ChildKernel(this.parentKernel);
- }
+ protected IKernel parentKernel;
///
/// All known dependencies the are resolved on child kernel.
@@ -181,6 +225,47 @@ public void SelectCorrectConstructorWhenBindingsAcrossKernels()
baz.Bar.Should().NotBeNull();
}
+ [Fact]
+ public void ChildKernelCannotAccessParentKernelComponents()
+ {
+ this.testee.Components.Add();
+
+ var nameOfBarMissingBindingResolver = nameof(BarMissingBindingResolver);
+
+ this.parentKernel.Components
+ .GetAll()
+ .Select(i => i.GetType().Name)
+ .FirstOrDefault(i => i.Equals(nameOfBarMissingBindingResolver, StringComparison.InvariantCultureIgnoreCase))
+ .Should().BeNull();
+ }
+
+ [Fact]
+ public void DisposeOfChildKernelDoesNotChangeParentKernelComponents()
+ {
+ this.parentKernel.Components.Add();
+ this.testee.Dispose();
+
+ this.parentKernel.Components.Get().Should().NotBeNull();
+ }
+
+ [Fact]
+ public void AddImmutableComponent()
+ {
+ Assert.Throws(() => this.testee.Components.Add());
+ }
+
+ [Fact]
+ public void RemoveImmutableComponent()
+ {
+ Assert.Throws(() => this.testee.Components.Remove());
+ }
+
+ [Fact]
+ public void RemoveAllImmutableComponents()
+ {
+ Assert.Throws(() => this.testee.Components.RemoveAll(typeof(ISelector)));
+ }
+
public class BarMissingBindingResolver : NinjectComponent, IMissingBindingResolver
{
private readonly IKernel kernel;
diff --git a/src/Ninject.Extensions.ChildKernel.Test/Ninject.Extensions.ChildKernel.Test.csproj b/src/Ninject.Extensions.ChildKernel.Test/Ninject.Extensions.ChildKernel.Test.csproj
index 966b863..1cebe90 100644
--- a/src/Ninject.Extensions.ChildKernel.Test/Ninject.Extensions.ChildKernel.Test.csproj
+++ b/src/Ninject.Extensions.ChildKernel.Test/Ninject.Extensions.ChildKernel.Test.csproj
@@ -10,7 +10,7 @@
Properties
Ninject.Extensions.ChildKernel
Ninject.Extensions.ChildKernel.Test
- v3.5
+ v4.5
512
false
..\Ninject.snk
@@ -34,7 +34,8 @@
false
false
true
- Client
+
+
true
@@ -61,7 +62,7 @@
False
- ..\..\lib\Ninject\net-3.5\Ninject.dll
+ ..\..\lib\Ninject\net-4.5\Ninject.dll
diff --git a/src/Ninject.Extensions.ChildKernel/ChildActivationCache.cs b/src/Ninject.Extensions.ChildKernel/ChildActivationCache.cs
index fac66f0..dfca68f 100644
--- a/src/Ninject.Extensions.ChildKernel/ChildActivationCache.cs
+++ b/src/Ninject.Extensions.ChildKernel/ChildActivationCache.cs
@@ -21,6 +21,7 @@ namespace Ninject.Extensions.ChildKernel
{
using Ninject.Activation.Caching;
using Ninject.Components;
+ using System;
///
/// The activation cache of child kernels.
@@ -38,6 +39,11 @@ public class ChildActivationCache : NinjectComponent, IActivationCache
/// The kernel.
public ChildActivationCache(IKernel kernel)
{
+ if (kernel == null)
+ {
+ throw new ArgumentNullException(nameof(kernel));
+ }
+
this.parentCache = ((IChildKernel)kernel).ParentResolutionRoot.Get().Components.Get();
}
diff --git a/src/Ninject.Extensions.ChildKernel/ChildKernel.cs b/src/Ninject.Extensions.ChildKernel/ChildKernel.cs
index 923c903..82c20f1 100644
--- a/src/Ninject.Extensions.ChildKernel/ChildKernel.cs
+++ b/src/Ninject.Extensions.ChildKernel/ChildKernel.cs
@@ -19,67 +19,105 @@
namespace Ninject.Extensions.ChildKernel
{
- using System;
using System.Collections.Generic;
using Ninject;
using Ninject.Activation;
using Ninject.Activation.Caching;
+ using Ninject.Activation.Strategies;
+ using Ninject.Components;
+ using Ninject.Injection;
using Ninject.Modules;
+ using Ninject.Planning;
+ using Ninject.Planning.Bindings.Resolvers;
+ using Ninject.Planning.Strategies;
+ using Ninject.Selection;
using Ninject.Selection.Heuristics;
using Ninject.Syntax;
+ using System;
///
/// This is a kernel with a parent kernel. Any binding that can not be resolved by this kernel is forwarded to the
/// parent.
///
- public class ChildKernel : StandardKernel, IChildKernel
+ public class ChildKernel : KernelBase, IChildKernel
{
///
- /// The parent kernel.
+ /// Initializes a new instance of the class.
///
- private readonly IResolutionRoot parent;
+ /// The parent.
+ /// The modules.
+ public ChildKernel(IResolutionRoot parent, params INinjectModule[] modules)
+ : base(CreateComponentContainerOfStandartKernel(), new NinjectSettings(), modules)
+ {
+ if (parent == null)
+ {
+ throw new ArgumentNullException(nameof(parent));
+ }
+
+ ParentResolutionRoot = parent;
+ }
///
/// Initializes a new instance of the class.
///
/// The parent.
+ /// The settings.
/// The modules.
- public ChildKernel(IResolutionRoot parent, params INinjectModule[] modules)
- : base(modules)
+ public ChildKernel(IResolutionRoot parent, INinjectSettings settings, params INinjectModule[] modules)
+ : base(CreateComponentContainerOfStandartKernel(settings), settings, modules)
{
- this.parent = parent;
+ if (parent == null)
+ {
+ throw new ArgumentNullException(nameof(parent));
+ }
- this.Components.RemoveAll();
- this.Components.Add();
-
- this.Components.RemoveAll();
- this.Components.Add();
+ ParentResolutionRoot = parent;
}
-
+
///
/// Initializes a new instance of the class.
///
/// The parent.
/// The settings.
+ /// The components.
/// The modules.
- public ChildKernel(IResolutionRoot parent, INinjectSettings settings, params INinjectModule[] modules)
- : base(settings, modules)
+ public ChildKernel(
+ IResolutionRoot parent,
+ INinjectSettings settings,
+ IComponentContainer components,
+ params INinjectModule[] modules)
+ : base(new ChildKernelComponentContainer(components), settings, modules)
{
- this.parent = parent;
+ if (parent == null)
+ {
+ throw new ArgumentNullException(nameof(parent));
+ }
+
+ ParentResolutionRoot = parent;
}
///
- /// Gets the parent resolution root.
+ /// Initializes a new instance of the class.
///
- /// The parent resolution root.
- public IResolutionRoot ParentResolutionRoot
+ /// The parent.
+ /// The modules.
+ public ChildKernel(IKernel parent, params INinjectModule[] modules)
+ : base(new ChildKernelComponentContainer(parent.Components), parent.Settings, modules)
{
- get
+ if (parent == null)
{
- return this.parent;
+ throw new ArgumentNullException(nameof(parent));
}
+
+ ParentResolutionRoot = parent;
}
-
+
+ ///
+ /// Gets the parent resolution root.
+ ///
+ /// The parent resolution root.
+ public IResolutionRoot ParentResolutionRoot { get; }
+
///
/// Determines whether the specified request can be resolved.
///
@@ -89,7 +127,7 @@ public IResolutionRoot ParentResolutionRoot
///
public override bool CanResolve(IRequest request)
{
- return base.CanResolve(request) || this.parent.CanResolve(request, true);
+ return base.CanResolve(request) || this.ParentResolutionRoot.CanResolve(request, true);
}
///
@@ -102,7 +140,7 @@ public override bool CanResolve(IRequest request)
///
public override bool CanResolve(IRequest request, bool ignoreImplicitBindings)
{
- return base.CanResolve(request, ignoreImplicitBindings) || this.parent.CanResolve(request, true);
+ return base.CanResolve(request, ignoreImplicitBindings) || this.ParentResolutionRoot.CanResolve(request, true);
}
///
@@ -120,9 +158,9 @@ public override IEnumerable