Skip to content

Instantly share code, notes, and snippets.

@idavis
Created May 12, 2010 22:44
Show Gist options
  • Save idavis/399225 to your computer and use it in GitHub Desktop.
Save idavis/399225 to your computer and use it in GitHub Desktop.
src/Ninject/Activation/Blocks/ActivationBlock.cs | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Ninject/Activation/Blocks/ActivationBlock.cs b/src/Ninject/Activation/Blocks/ActivationBlock.cs
index b16b503..4b64376 100644
--- a/src/Ninject/Activation/Blocks/ActivationBlock.cs
+++ b/src/Ninject/Activation/Blocks/ActivationBlock.cs
@@ -68,10 +68,10 @@ namespace Ninject.Activation.Blocks
/// </summary>
/// <param name="request">The request.</param>
/// <returns><c>True</c> if the request can be resolved; otherwise, <c>false</c>.</returns>
- public bool CanResolve(IRequest request)
+ public bool HasBindingsFor(IRequest request)
{
Ensure.ArgumentNotNull(request, "request");
- return Parent.CanResolve(request);
+ return Parent.HasBindingsFor(request);
}
/// <summary>
src/Ninject/Planning/Targets/Target.cs | 18 +++++++++++++++++-
1 files changed, 17 insertions(+), 1 deletions(-)
diff --git a/src/Ninject/Planning/Targets/Target.cs b/src/Ninject/Planning/Targets/Target.cs
index 952ff94..e7de48a 100644
--- a/src/Ninject/Planning/Targets/Target.cs
+++ b/src/Ninject/Planning/Targets/Target.cs
@@ -144,7 +144,7 @@ namespace Ninject.Planning.Targets
return GetValues(service, parent).CastSlow(service);
}
- return GetValues(Type, parent).FirstOrDefault();
+ return GetValue(Type, parent);
}
/// <summary>
@@ -163,6 +163,22 @@ namespace Ninject.Planning.Targets
}
/// <summary>
+ /// Gets the value that should be injected into the target.
+ /// </summary>
+ /// <param name="service">The service that the target is requesting.</param>
+ /// <param name="parent">The parent context in which the target is being injected.</param>
+ /// <returns>The value that is to be injected.</returns>
+ protected virtual object GetValue(Type service, IContext parent)
+ {
+ Ensure.ArgumentNotNull(service, "service");
+ Ensure.ArgumentNotNull(parent, "parent");
+
+ var request = parent.Request.CreateChild(service, parent, this);
+ request.IsUnique = true;
+ return parent.Kernel.Resolve(request).Single();
+ }
+
+ /// <summary>
/// Reads whether the target represents an optional dependency.
/// </summary>
/// <returns><see langword="True"/> if it is optional; otherwise <see langword="false"/>.</returns>
src/Ninject/Syntax/IResolutionRoot.cs | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/Ninject/Syntax/IResolutionRoot.cs b/src/Ninject/Syntax/IResolutionRoot.cs
index c308b31..53e60d1 100644
--- a/src/Ninject/Syntax/IResolutionRoot.cs
+++ b/src/Ninject/Syntax/IResolutionRoot.cs
@@ -27,7 +27,7 @@ namespace Ninject.Syntax
/// </summary>
/// <param name="request">The request.</param>
/// <returns><c>True</c> if the request can be resolved; otherwise, <c>false</c>.</returns>
- bool CanResolve(IRequest request);
+ bool HasBindingsFor(IRequest request);
/// <summary>
/// Resolves instances for the specified request. The instances are not actually resolved
src/Ninject/KernelBase.cs | 48 +++++++++++++++++++++++++++++++++++++-------
1 files changed, 40 insertions(+), 8 deletions(-)
diff --git a/src/Ninject/KernelBase.cs b/src/Ninject/KernelBase.cs
index 759d62f..6844710 100644
--- a/src/Ninject/KernelBase.cs
+++ b/src/Ninject/KernelBase.cs
@@ -290,11 +290,13 @@ namespace Ninject
/// </summary>
/// <param name="request">The request.</param>
/// <returns><c>True</c> if the request can be resolved; otherwise, <c>false</c>.</returns>
- public virtual bool CanResolve(IRequest request)
+ public virtual bool HasBindingsFor(IRequest request)
{
Ensure.ArgumentNotNull(request, "request");
var resolvers = Components.GetAll<IBindingResolver>();
- return resolvers.SelectMany(r => r.Resolve(_bindings, request.Service)).Any();
+ return resolvers
+ .SelectMany(r => r.Resolve(_bindings, request.Service))
+ .Any(SatifiesRequest(request));
}
/// <summary>
@@ -310,29 +312,59 @@ namespace Ninject
if (request.Service == typeof(IKernel))
return new[] { this };
- if (!CanResolve(request) && !HandleMissingBinding(request.Service))
+ if (!HasBindingsFor(request) && !HandleMissingBinding(request.Service))
{
if (request.IsOptional)
return Enumerable.Empty<object>();
- else
- throw new ActivationException(ExceptionFormatter.CouldNotResolveBinding(request));
+ throw new ActivationException(ExceptionFormatter.CouldNotResolveBinding(request));
}
var bindings = GetBindings(request.Service)
.OrderBy(binding => binding.IsConditional ? 0 : 1)
- .Where(binding => binding.Matches(request) && request.Matches(binding));
+ .Where(SatifiesRequest(request));
if (request.IsUnique && bindings.Count() > 1)
{
- throw new ActivationException(ExceptionFormatter.CouldNotUniquelyResolveBinding(request));
+ var conditionalBindings = bindings.Where(binding => binding.IsConditional);
+ if (conditionalBindings.Any())
+ {
+ if (conditionalBindings.Count() > 1)
+ {
+ throw new ActivationException(ExceptionFormatter.CouldNotUniquelyResolveBinding(request));
+ }
+ bindings = conditionalBindings;
+ }
+ else
+ {
+ var nonImplicitBindings = bindings.Where(binding => !binding.IsImplicit);
+ if (nonImplicitBindings.Count() != 1)
+ {
+ throw new ActivationException(ExceptionFormatter.CouldNotUniquelyResolveBinding(request));
+ }
+ bindings = nonImplicitBindings;
+ }
}
-
+
+ /*if (bindings.Any(binding => !binding.IsImplicit))
+ {
+ bindings = bindings.Where(binding => !binding.IsImplicit);
+ }*/
return bindings
.Select(binding => CreateContext(request, binding))
.Select(context => context.Resolve());
}
/// <summary>
+ /// Returns a predicate that can determine if a given IBinding matches the request.
+ /// </summary>
+ /// <param name="request">The request/</param>
+ /// <returns>A predicate that can determine if a given IBinding matches the request.</returns>
+ protected virtual Func<IBinding, bool> SatifiesRequest(IRequest request)
+ {
+ return binding => binding.Matches(request) && request.Matches(binding);
+ }
+
+ /// <summary>
/// Creates a request for the specified service.
/// </summary>
/// <param name="service">The service that is being requested.</param>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment