Skip to content

Commit

Permalink
Merge branch '4.0.0' of github.com:iappert/ninject into 4.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
remogloor committed Apr 25, 2014
2 parents 894be4b + 795f186 commit d5d884f
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 91 deletions.
4 changes: 2 additions & 2 deletions src/Ninject.Test/ExtensionsForIEnumerable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ public static void Map<T>(this IEnumerable<T> series, Action<T> action)
}

public static T ShouldContainSingle<T>(this IEnumerable<T> source)
{
{
return Assert.Single(source);
}
}
}
}
127 changes: 76 additions & 51 deletions src/Ninject/Activation/Providers/StandardProvider.cs
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
#region License
//
// Author: Nate Kohari <nate@enkari.com>
// Copyright (c) 2007-2010, Enkari, Ltd.
//
// Dual-licensed under the Apache License, Version 2.0, and the Microsoft Public License (Ms-PL).
// See the file LICENSE.txt for details.
//
#endregion
#region Using Directives
using System;
using System.Linq;

using Ninject.Infrastructure.Introspection;
using Ninject.Parameters;
using Ninject.Planning.Directives;
using Ninject.Planning.Targets;

#endregion
//-------------------------------------------------------------------------------
// <copyright file="StandardProvider.cs" company="Ninject Project Contributors">
// Copyright (c) 2009-2014 Ninject Project Contributors
//
// 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>
//-------------------------------------------------------------------------------

namespace Ninject.Activation.Providers
{
using System;
using System.Linq;
using System.Reflection;

using Ninject.Infrastructure.Introspection;
using Ninject.Infrastructure.Language;
using Ninject.Parameters;
using Ninject.Planning.Bindings;
using Ninject.Planning.Directives;
using Ninject.Planning.Targets;
using Ninject.Selection;
using Ninject.Selection.Heuristics;

Expand All @@ -31,27 +37,27 @@ namespace Ninject.Activation.Providers
/// </summary>
public class StandardProvider : IProvider
{
/// <summary>
/// Gets the type (or prototype) of instances the provider creates.
/// </summary>
public Type Type { get; private set; }

/// <summary>
/// Gets or sets the selector component.
/// </summary>
public IConstructorScorer ConstructorScorer { get; private set; }

/// <summary>
/// Initializes a new instance of the <see cref="StandardProvider"/> class.
/// </summary>
/// <param name="type">The type (or prototype) of instances the provider creates.</param>
/// <param name="constructorScorer">The constructor scorer component.</param>
public StandardProvider(Type type, IConstructorScorer constructorScorer)
{
Type = type;
ConstructorScorer = constructorScorer;
this.Type = type;
this.ConstructorScorer = constructorScorer;
}

/// <summary>
/// Gets the type (or prototype) of instances the provider creates.
/// </summary>
public Type Type { get; private set; }

/// <summary>
/// Gets the selector component.
/// </summary>
public IConstructorScorer ConstructorScorer { get; private set; }

/// <summary>
/// Creates an instance within the specified context.
/// </summary>
Expand All @@ -60,23 +66,11 @@ public StandardProvider(Type type, IConstructorScorer constructorScorer)
public virtual object Create(IContext context)
{
context.BuildPlan(this.GetImplementationType(context.Request.Service));
if (!context.Plan.Has<ConstructorInjectionDirective>())
{
throw new ActivationException(ExceptionFormatter.NoConstructorsAvailable(context));
}

var directives = context.Plan.GetAll<ConstructorInjectionDirective>();
var bestDirectives = directives
.GroupBy(option => this.ConstructorScorer.Score(context, option))
.OrderByDescending(g => g.Key)
.First();
if (bestDirectives.Skip(1).Any())
{
throw new ActivationException(ExceptionFormatter.ConstructorsAmbiguous(context, bestDirectives));
}
var directive = this.DetermineConstructorInjectionDirective(context);

var directive = bestDirectives.Single();
var arguments = directive.Targets.Select(target => this.GetValue(context, target)).ToArray();

return directive.Injector(arguments);
}

Expand Down Expand Up @@ -109,9 +103,15 @@ public Type GetImplementationType(Type service)
/// Gets a callback that creates an instance of the <see cref="StandardProvider"/>
/// for the specified type.
/// </summary>
/// <param name="prototype">The prototype the provider instance will create.</param>
/// <param name="selector">The selector</param>
/// <returns>The created callback.</returns>
/// <param name="prototype">
/// The prototype the provider instance will create.
/// </param>
/// <param name="selector">
/// The selector.
/// </param>
/// <returns>
/// The created callback.
/// </returns>
public static Func<IContext, IProvider> GetCreationCallback(Type prototype, ISelector selector)
{
var provider = new StandardProvider(prototype, selector.ConstructorScorer);
Expand All @@ -134,14 +134,39 @@ public static Func<IContext, IProvider> GetCreationCallback(Type prototype, Cons
/// <summary>
/// Assigns the provider callback to the building configuration.
/// </summary>
/// <param name="bindingConfiguration">The building configuration</param>
/// <param name="prototype">The prototype</param>
/// <param name="bindingConfiguration">
/// The building configuration.
/// </param>
/// <param name="prototype">
/// The prototype.
/// </param>
public static void AssignProviderCallback(IBindingConfiguration bindingConfiguration, Type prototype)
{
var provider = new StandardProvider(prototype, null);
bindingConfiguration.ProviderCallback = ctx => provider;
bindingConfiguration.InitializeProviderCallback =
selector => provider.ConstructorScorer = selector.ConstructorScorer;
}

private ConstructorInjectionDirective DetermineConstructorInjectionDirective(IContext context)
{
var directives = context.Plan.ConstructorInjectionDirectives;
if (directives.Count == 1)
{
return directives[0];
}
IGrouping<int, ConstructorInjectionDirective> bestDirectives =
directives
.GroupBy(option => this.ConstructorScorer.Score(context, option))
.OrderByDescending(g => g.Key)
.FirstOrDefault();
if (bestDirectives == null)
{
throw new ActivationException(ExceptionFormatter.NoConstructorsAvailable(context));
}

return bestDirectives.SingleOrThrowException(
() => new ActivationException(ExceptionFormatter.ConstructorsAmbiguous(context, bestDirectives)));
}
}
}
74 changes: 58 additions & 16 deletions src/Ninject/Infrastructure/Language/ExtensionsForIEnumerableOfT.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,46 @@
#region License
//
// Author: Nate Kohari <nate@enkari.com>
// Copyright (c) 2007-2010, Enkari, Ltd.
//
// Dual-licensed under the Apache License, Version 2.0, and the Microsoft Public License (Ms-PL).
// See the file LICENSE.txt for details.
//
#endregion
#region Using Directives
using System;
using System.Collections.Generic;
using System.Linq;
#endregion
//-------------------------------------------------------------------------------
// <copyright file="ExtensionsForIEnumerableOfT.cs" company="Ninject Project Contributors">
// Copyright (c) 2009-2014 Ninject Project Contributors
//
// 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>
//-------------------------------------------------------------------------------

namespace Ninject.Infrastructure.Language
{
using System;
using System.Collections.Generic;
using System.Linq;

/// <summary>
/// Provides extension methods for see cref="IEnumerable{T}"/>
/// Provides extension methods for see IEnumerable.
/// </summary>
public static class ExtensionsForIEnumerableOfT
{
/// <summary>
/// Executes the given action for each of the elements in the enumerable.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="T">Type of the enumerable.</typeparam>
/// <param name="series">The series.</param>
/// <param name="action">The action.</param>
public static void Map<T>(this IEnumerable<T> series, Action<T> action)
{
foreach (T item in series)
{
action(item);
}
}

/// <summary>
Expand All @@ -42,5 +53,36 @@ public static IEnumerable<T> ToEnumerable<T>(this IEnumerable<T> series)
{
return series.Select(x => x);
}

/// <summary>
/// Returns single element of enumerable or throws exception.
/// </summary>
/// <param name="series">
/// The enumerable.
/// </param>
/// <param name="exceptionCreator">
/// The exception creator.
/// </param>
/// <typeparam name="T">
/// Type of IEnumerable.
/// </typeparam>
/// <returns>
/// Single element of enumerable.
/// </returns>
/// <exception cref="ActivationException">
/// Exception specified by exception creator.
/// </exception>
public static T SingleOrThrowException<T>(this IEnumerable<T> series, Func<ActivationException> exceptionCreator)
{
var e = series.GetEnumerator();
e.MoveNext();
var result = e.Current;
if (e.MoveNext())
{
throw exceptionCreator();
}

return result;
}
}
}
5 changes: 5 additions & 0 deletions src/Ninject/Planning/IPlan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ public interface IPlan
/// </summary>
Type Type { get; }

/// <summary>
/// Gets the directives defined in the plan.
/// </summary>
IList<ConstructorInjectionDirective> ConstructorInjectionDirectives { get; }

/// <summary>
/// Adds the specified directive to the plan.
/// </summary>
Expand Down
Loading

0 comments on commit d5d884f

Please sign in to comment.