Skip to content

Commit

Permalink
Added fluent syntax to define multiple interfaces for one implementat…
Browse files Browse the repository at this point in the history
…ion.
  • Loading branch information
remogloor committed Dec 18, 2011
1 parent 64086b1 commit 83c8f53
Show file tree
Hide file tree
Showing 35 changed files with 2,475 additions and 764 deletions.
1 change: 1 addition & 0 deletions ReleaseNotes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Version 3.0.0.0
- Added: Open generic bindings can be overriden by closed generics for specific types.
- Added: Support for extensions that they can define bindings that return the same instance for different interfaces (interface segregation principle).
- Added: Generic Overloads for OnActivation and OnDeactivation that can be used to cast the implementation type.
- Added: Bind<T1,T2, ...>() to define multiple interfaces for one service.

- Changed: WhenInjectedInto matches also if the target derives from the specified type.
- Changed: ToConstant bindings are in singleton scope by default
Expand Down
15 changes: 15 additions & 0 deletions src/Ninject.Test/Fakes/ICleric.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Ninject.Tests.Fakes
{
public interface ICleric
{
void Pray();
}

public interface IHuman
{
}

public interface ILifeform
{
}
}
8 changes: 4 additions & 4 deletions src/Ninject.Test/Fakes/Monk.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Ninject.Tests.Fakes
{
public class Monk : IWarrior, ICleric
public class Monk : IWarrior, ICleric, IHuman, ILifeform
{
public IWeapon Weapon
{
Expand All @@ -9,9 +9,9 @@ public IWeapon Weapon
return null;
}
}
}

public interface ICleric
{
public void Pray()
{
}
}
}
2 changes: 1 addition & 1 deletion src/Ninject.Test/Integration/ActivationStrategyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public void NullIsNotActivated()
{
kernel.Components.Add<IActivationStrategy, TestActivationStrategy>();
kernel.Bind<IWarrior>().To<Samurai>();
kernel.Bind<IWeapon>().ToConstant(null);
kernel.Bind<IWeapon>().ToConstant((IWeapon)null);
var testActivationStrategy = kernel.Components.GetAll<IActivationStrategy>().OfType<TestActivationStrategy>().Single();

kernel.Get<IWarrior>();
Expand Down
6 changes: 3 additions & 3 deletions src/Ninject.Test/Integration/ConditionalBindingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public void GivenAMixtureOfBindings_OnlyNonImplicitBindingsWillResolve()

kernel.Bind<IWeapon>().ToConstant(shortSword);
kernel.Bind<IWeapon>().ToConstant(sword);
kernel.Bind<IWeapon>().ToConstant(shuriken).Binding.IsImplicit = true;
kernel.Bind<IWeapon>().ToConstant(shuriken).BindingConfiguration.IsImplicit = true;
var result = kernel.GetAll<IWeapon>();
result.Should().Contain(shortSword);
result.Should().Contain(sword);
Expand All @@ -127,8 +127,8 @@ public void GivenOnlyImplicitBindings_AllBindingsWillResolve()
var shortSword = new ShortSword();
var shuriken = new Shuriken();

kernel.Bind<IWeapon>().ToConstant(shortSword).Binding.IsImplicit = true;
kernel.Bind<IWeapon>().ToConstant(shuriken).Binding.IsImplicit = true;
kernel.Bind<IWeapon>().ToConstant(shortSword).BindingConfiguration.IsImplicit = true;
kernel.Bind<IWeapon>().ToConstant(shuriken).BindingConfiguration.IsImplicit = true;
var result = kernel.GetAll<IWeapon>();
result.Should().Contain(shortSword);
result.Should().Contain(shuriken);
Expand Down
4 changes: 2 additions & 2 deletions src/Ninject.Test/Integration/ConstantTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ public void ConditionalBindingShouldNotAffectUnconditionalBinding()
public void TheBindingShouldOnlyBeResolvedOnce()
{
var builder = kernel.Bind<IWeapon>().ToConstant(new Sword());
var provider = new ResolveCountingProvider(builder.Binding.ProviderCallback);
builder.Binding.ProviderCallback = ctx => provider.Callback(ctx);
var provider = new ResolveCountingProvider(builder.BindingConfiguration.ProviderCallback);
builder.BindingConfiguration.ProviderCallback = ctx => provider.Callback(ctx);


kernel.Get<IWeapon>();
Expand Down
35 changes: 0 additions & 35 deletions src/Ninject.Test/Integration/InterfaceSegregationTests.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
namespace Ninject.Tests.Integration
{
using System;
using FluentAssertions;

using Ninject.Activation;
using Ninject.Tests.Fakes;
using Xunit;

public class InterfaceSegregationWithThreerServicesTests : IDisposable
{
private readonly StandardKernel kernel;

public InterfaceSegregationWithThreerServicesTests()
{
this.kernel = new StandardKernel();
}

public void Dispose()
{
this.kernel.Dispose();
}

[Fact]
public void MultipleServicesBoundWithGenericToReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric, IHuman>().To<Monk>().InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

[Fact]
public void MultipleServicesBoundWithToReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric, IHuman>().To(typeof(Monk)).InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

[Fact]
public void MultipleServicesBoundWithToConstantReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric, IHuman>().ToConstant(new Monk()).InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

[Fact]
public void MultipleServicesBoundWithToMethodReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric, IHuman>().ToMethod(ctx => new Monk()).InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

[Fact]
public void MultipleServicesBoundWithToProviderReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric, IHuman>().ToProvider(new MonkProvider()).InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

[Fact]
public void MultipleServicesBoundWithGenericToProviderReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric, IHuman>().ToProvider<MonkProvider>().InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

private void VerifyAllInterfacesAreSameInstance()
{
var warrior = this.kernel.Get<IWarrior>();
var cleric = this.kernel.Get<ICleric>();
var human = this.kernel.Get<IHuman>();

warrior.Should().BeSameAs(cleric);
human.Should().BeSameAs(cleric);
}

public class MonkProvider : Provider<Monk>
{
protected override Monk CreateInstance(IContext context)
{
return new Monk();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
namespace Ninject.Tests.Integration
{
using System;
using FluentAssertions;

using Ninject.Activation;
using Ninject.Tests.Fakes;
using Xunit;

public class InterfaceSegregationWithFourServicesTests : IDisposable
{
private readonly StandardKernel kernel;

public InterfaceSegregationWithFourServicesTests()
{
this.kernel = new StandardKernel();
}

public void Dispose()
{
this.kernel.Dispose();
}

[Fact]
public void MultipleServicesBoundWithGenericToReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric, IHuman, ILifeform>().To<Monk>().InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

[Fact]
public void MultipleServicesBoundWithToReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric, IHuman, ILifeform>().To(typeof(Monk)).InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

[Fact]
public void MultipleServicesBoundWithToConstantReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric, IHuman, ILifeform>().ToConstant(new Monk()).InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

[Fact]
public void MultipleServicesBoundWithToMethodReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric, IHuman, ILifeform>().ToMethod(ctx => new Monk()).InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

[Fact]
public void MultipleServicesBoundWithToProviderReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric, IHuman, ILifeform>().ToProvider(new MonkProvider()).InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

[Fact]
public void MultipleServicesBoundWithGenericToProviderReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric, IHuman, ILifeform>().ToProvider<MonkProvider>().InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

private void VerifyAllInterfacesAreSameInstance()
{
var warrior = this.kernel.Get<IWarrior>();
var cleric = this.kernel.Get<ICleric>();
var human = this.kernel.Get<IHuman>();
var lifeform = this.kernel.Get<ILifeform>();

warrior.Should().BeSameAs(cleric);
human.Should().BeSameAs(cleric);
lifeform.Should().BeSameAs(cleric);
}

public class MonkProvider : Provider<Monk>
{
protected override Monk CreateInstance(IContext context)
{
return new Monk();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
namespace Ninject.Tests.Integration
{
using System;
using FluentAssertions;

using Ninject.Activation;
using Ninject.Tests.Fakes;
using Xunit;

public class InterfaceSegregationWithTwoServicesTests : IDisposable
{
private readonly StandardKernel kernel;

public InterfaceSegregationWithTwoServicesTests()
{
this.kernel = new StandardKernel();
}

public void Dispose()
{
this.kernel.Dispose();
}

[Fact]
public void MultipleServicesBoundWithGenericToReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric>().To<Monk>().InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

[Fact]
public void MultipleServicesBoundWithToReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric>().To(typeof(Monk)).InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

[Fact]
public void MultipleServicesBoundWithToConstantReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric>().ToConstant(new Monk()).InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

[Fact]
public void MultipleServicesBoundWithToMethodReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric>().ToMethod(ctx => new Monk()).InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

[Fact]
public void MultipleServicesBoundWithToProviderReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric>().ToProvider(new MonkProvider()).InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

[Fact]
public void MultipleServicesBoundWithGenericToProviderReturnSameInstance()
{
this.kernel.Bind<IWarrior, ICleric>().ToProvider<MonkProvider>().InSingletonScope();

this.VerifyAllInterfacesAreSameInstance();
}

private void VerifyAllInterfacesAreSameInstance()
{
var warrior = this.kernel.Get<IWarrior>();
var cleric = this.kernel.Get<ICleric>();

warrior.Should().BeSameAs(cleric);
}

public class MonkProvider : Provider<Monk>
{
protected override Monk CreateInstance(IContext context)
{
return new Monk();
}
}
}
}
Loading

0 comments on commit 83c8f53

Please sign in to comment.