Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Bind<TInterface> syntax to bind a specific interface #18

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion ReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
Version 3.2.0
Version 3.2.0.1
-------------
- Add: Support for specific service type binding IBindSyntax.Bind<
E.g.
kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<IFoo>()
.Bind<IFoo>());

Version 3.2.0.0
-------------
- Add: Support for multiple configurations in one BindWith
E.g.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@

#if !NO_MOQ
namespace Ninject.Extensions.Conventions.BindingBuilder
{
{
using System;
using System.Text.RegularExpressions;
using Moq;
using Ninject.Extensions.Conventions.BindingGenerators;
Expand Down Expand Up @@ -64,11 +65,39 @@ public void BindWith()
this.testee.BindWith(generator);

this.conventionBindingBuilderMock.Verify(b => b.BindWith(generator));
}

[Fact]
public void BindGeneric()
{
Type serviceType = typeof(string);
var generator = new Mock<IBindingGenerator>().Object;
this.bindingGeneratorFactoryMock
.Setup(g => g.CreateSpecificTypesBindingGenerator(serviceType))
.Returns(generator);

this.testee.Bind<string>();

this.conventionBindingBuilderMock.Verify(b => b.BindWith(generator));
}

[Fact]
public void Bind()
{
Type[] serviceTypes = { typeof(string), typeof(object) };
var generator = new Mock<IBindingGenerator>().Object;
this.bindingGeneratorFactoryMock
.Setup(g => g.CreateSpecificTypesBindingGenerator(serviceTypes))
.Returns(generator);

this.testee.Bind(serviceTypes);

this.conventionBindingBuilderMock.Verify(b => b.BindWith(generator));
}

[Fact]
public void BindToAllInterfaces()
{
{
var generator = new Mock<IBindingGenerator>().Object;
this.bindingGeneratorFactoryMock.Setup(g => g.CreateAllInterfacesBindingGenerator()).Returns(generator);

Expand All @@ -79,7 +108,7 @@ public void BindToAllInterfaces()

[Fact]
public void BindToAllBaseClasses()
{
{
var generator = new Mock<IBindingGenerator>().Object;
this.bindingGeneratorFactoryMock.Setup(g => g.CreateAllBaseClassesBindingGenerator()).Returns(generator);

Expand All @@ -90,7 +119,7 @@ public void BindToAllBaseClasses()

[Fact]
public void BindToBase()
{
{
var generator = new Mock<IBindingGenerator>().Object;
this.bindingGeneratorFactoryMock.Setup(g => g.CreateBaseBindingGenerator()).Returns(generator);

Expand All @@ -101,7 +130,7 @@ public void BindToBase()

[Fact]
public void BindToDefaultInterface()
{
{
var generator = new Mock<IBindingGenerator>().Object;
this.bindingGeneratorFactoryMock.Setup(g => g.CreateDefaultInterfaceBindingGenerator()).Returns(generator);

Expand All @@ -112,7 +141,7 @@ public void BindToDefaultInterface()

[Fact]
public void BindToDefaultInterfaces()
{
{
var generator = new Mock<IBindingGenerator>().Object;
this.bindingGeneratorFactoryMock.Setup(g => g.CreateDefaultInterfacesBindingGenerator()).Returns(generator);

Expand All @@ -123,7 +152,7 @@ public void BindToDefaultInterfaces()

[Fact]
public void BindToSelf()
{
{
var generator = new Mock<IBindingGenerator>().Object;
this.bindingGeneratorFactoryMock.Setup(g => g.CreateSelfBindingGenerator()).Returns(generator);

Expand All @@ -134,7 +163,7 @@ public void BindToSelf()

[Fact]
public void BindToSingleInterface()
{
{
var generator = new Mock<IBindingGenerator>().Object;
this.bindingGeneratorFactoryMock.Setup(g => g.CreateSingleInterfaceBindingGenerator()).Returns(generator);

Expand All @@ -146,7 +175,7 @@ public void BindToSingleInterface()
[Fact]
public void BindToSelection()
{
ServiceSelector selector = (t1, t2) => t2;
ServiceSelector selector = (t1, t2) => t2;
var generator = new Mock<IBindingGenerator>().Object;
this.bindingGeneratorFactoryMock.Setup(g => g.CreateSelectorBindingGenerator(selector)).Returns(generator);

Expand All @@ -158,7 +187,7 @@ public void BindToSelection()
[Fact]
public void BindToRegex()
{
const string Pattern = "ThePattern";
const string Pattern = "ThePattern";
var generator = new Mock<IBindingGenerator>().Object;
this.bindingGeneratorFactoryMock.Setup(g => g.CreateRegexBindingGenerator(Pattern)).Returns(generator);

Expand All @@ -171,7 +200,7 @@ public void BindToRegex()
public void BindToRegexWithOptions()
{
const string Pattern = "ThePattern";
const RegexOptions Options = RegexOptions.Multiline;
const RegexOptions Options = RegexOptions.Multiline;
var generator = new Mock<IBindingGenerator>().Object;
this.bindingGeneratorFactoryMock.Setup(g => g.CreateRegexBindingGenerator(Pattern, Options)).Returns(generator);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,51 +57,60 @@ public IKernel Object
public List<IBindingWhenInNamedWithOrOnSyntax<object>> ReturnedSyntax { get; private set; }

public void VerifyBindingCreated<TInterface, TImplementation>()
{
this.VerifyBindingCreated(typeof(TInterface), typeof(TImplementation));
{
this.VerifyBindingCreated(new[] { typeof(TInterface) }, typeof(TImplementation));
}

public void VerifyBindingCreated(Type interfaceType, Type implementationType)
public void VerifyBindingCreated(Type[] interfaceTypes, Type implementationType)
{
this.Bindings.Should().Contain(new Binding(interfaceType, implementationType));
this.Bindings.Should().Contain(new Binding(interfaceTypes, implementationType));
}

public void VerifyAllBindingsCreated(IEnumerable<Type> interfaceTypes, Type implementationType)
{
this.Bindings.Count.Should().Be(interfaceTypes.Count());

foreach (var interfaceType in interfaceTypes)
{
this.VerifyBindingCreated(interfaceType, implementationType);
foreach (Type interfaceType in interfaceTypes)
{
this.VerifyBindingCreated(new[] { interfaceType }, implementationType);
}
}

private IBindingToSyntax<object> CreateBindToMock(Type[] interfaceTypes)
{
var interfaceType = interfaceTypes.Single();
var bindToMock = new Mock<IBindingToSyntax<object>>();
bindToMock.Setup(m => m.To(It.IsAny<Type>())).Returns<Type>(implementationType => this.CreateConfigSyntax(interfaceType, implementationType));
bindToMock.Setup(m => m.ToSelf()).Returns(() => this.CreateConfigSyntax(interfaceType, interfaceType));
return bindToMock.Object;
}
bindToMock.Setup(m => m.To(It.IsAny<Type>())).Returns<Type>(implementationType => this.CreateConfigSyntax(interfaceTypes, implementationType));

if (interfaceTypes.Length == 1)
{
bindToMock.Setup(m => m.ToSelf()).Returns(() => this.CreateConfigSyntax(interfaceTypes, interfaceTypes.Single()));
}
else
{
bindToMock.Setup(m => m.ToSelf())
.Throws(new Exception(".Bind(type1, type2,..).ToSelf() is not supported. To self is only supported for .Bind(oneType).ToSelf()"));
}

private IBindingWhenInNamedWithOrOnSyntax<object> CreateConfigSyntax(Type interfaceType, Type implementationType)
return bindToMock.Object;
}

private IBindingWhenInNamedWithOrOnSyntax<object> CreateConfigSyntax(Type[] interfaceTypes, Type implementationType)
{
var configSyntax = new Mock<IBindingWhenInNamedWithOrOnSyntax<object>>().Object;
this.ReturnedSyntax.Add(configSyntax);
this.Bindings.Add(new Binding(interfaceType, implementationType));
this.Bindings.Add(new Binding(interfaceTypes, implementationType));
return configSyntax;
}

public class Binding
{
public Binding(Type interfaceType, Type implementationType)
{
this.InterfaceType = interfaceType;
public Binding(Type[] interfaceTypes, Type implementationType)
{
this.InterfaceTypes = interfaceTypes;
this.ImplementationType = implementationType;
}

public Type InterfaceType { get; private set; }
}
public Type[] InterfaceTypes { get; private set; }

public Type ImplementationType { get; private set; }

Expand All @@ -115,12 +124,12 @@ public override bool Equals(object obj)

return
this.ImplementationType.Equals(other.ImplementationType) &&
this.InterfaceType.Equals(other.InterfaceType);
this.InterfaceTypes.SequenceEqual(other.InterfaceTypes);
}

public override int GetHashCode()
{
return this.ImplementationType.GetHashCode() + (13 * this.InterfaceType.GetHashCode());
return this.ImplementationType.GetHashCode() + (13 * this.InterfaceTypes.GetHashCode());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//-------------------------------------------------------------------------------
// <copyright file="SingleInterfaceBindingGeneratorTests.cs" company="Ninject Project Contributors">
// Copyright (c) 2009-2011 Ninject Project Contributors
// Authors: Remo Gloor ([email protected])
//
// Dual-licensed under the Apache License, Version 2.0, and the Microsoft Public License (Ms-PL).
// you may not use this file except in compliance with one of the Licenses.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// or
// http://www.microsoft.com/opensource/licenses.mspx
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
//-------------------------------------------------------------------------------

#if !SILVERLIGHT_30 && !SILVERLIGHT_20 && !NO_MOQ && !NO_GENERIC_MOQ
namespace Ninject.Extensions.Conventions.BindingGenerators
{
using System;
using System.Linq;
using FluentAssertions;

using Ninject.Extensions.Conventions.BindingBuilder;
using Ninject.Extensions.Conventions.Fakes;
using Xunit;

public class SpecificTypesBindingGeneratorTests
{
private static readonly Type[] ServiceTypes = { typeof(IFoo), typeof(IBar), typeof(IService) };

private readonly IBindingGenerator testee;
private readonly KernelMock kernelMock;

public SpecificTypesBindingGeneratorTests()
{
this.kernelMock = new KernelMock();
this.testee = new BindingGeneratorFactory(null).CreateSpecificTypesBindingGenerator(ServiceTypes);
}

[Fact]
public void ExceptionIsThrownWhenTypeDoesNotImplementServiceType()
{
var type = typeof(Foo);

var exception = Assert.Throws<InvalidOperationException>(() => this.testee.CreateBindings(type, this.kernelMock.Object).ToList());

exception.Message.Should()
.Contain(type.FullName)
.And.Contain(typeof(IBar).FullName)
.And.Contain(typeof(IService).FullName)
.And.NotContain(typeof(IFoo).FullName);
}

[Fact]
public void AllServiceTypesAreBound()
{
var type = typeof(MultipleInterfaceCrazyService);

this.testee.CreateBindings(type, this.kernelMock.Object).ToList();

this.kernelMock.VerifyBindingCreated(ServiceTypes, type);
}

[Fact]
public void SyntaxForBindingIsReturned()
{
var type = typeof(MultipleInterfaceCrazyService);

var syntax = this.testee.CreateBindings(type, this.kernelMock.Object).ToList();

syntax.Should().Contain(this.kernelMock.ReturnedSyntax);
}
}
}
#endif
Loading