/// <summary>
/// Try to resolve the dependency by checking the parameters in
/// the model or checking the Kernel for the requested service.
/// </summary>
/// <remarks>
/// The dependency resolver has the following precedence order:
/// <list type = "bullet">
/// <item>
/// <description>The dependency is checked within the
/// <see cref = "CreationContext" />
/// </description>
/// </item>
/// <item>
/// <description>The dependency is checked within the
/// <see cref = "IHandler" />
/// instance for the component</description>
/// </item>
/// <item>
/// <description>The dependency is checked within the registered
/// <see cref = "ISubDependencyResolver" />
/// s</description>
/// </item>
/// <item>
/// <description>Finally the resolver tries the normal flow
/// which is using the configuration
/// or other component to satisfy the dependency</description>
/// </item>
/// </list>
/// </remarks>
/// <param name = "context">Creation context, which is a resolver itself</param>
/// <param name = "contextHandlerResolver">Parent resolver</param>
/// <param name = "model">Model of the component that is requesting the dependency</param>
/// <param name = "dependency">The dependency model</param>
/// <returns>The dependency resolved value or null</returns>
public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
{
object value = null;
bool resolved = false;
// 1 - check for the dependency on CreationContext, if present
if (context != null && context.CanResolve(context, contextHandlerResolver, model, dependency))
{
value = context.Resolve(context, contextHandlerResolver, model, dependency);
resolved = true;
}
// 2 - check with the model's handler, if not the same as the parent resolver
IHandler handler = kernel.GetHandler(model.Name);
if (!resolved && handler != contextHandlerResolver && handler.CanResolve(context, contextHandlerResolver, model, dependency))
{
value = handler.Resolve(context, contextHandlerResolver, model, dependency);
resolved = true;
}
// 3 - check within parent resolver, if present
if (!resolved && contextHandlerResolver != null && contextHandlerResolver.CanResolve(context, contextHandlerResolver, model, dependency))
{
value = contextHandlerResolver.Resolve(context, contextHandlerResolver, model, dependency);
resolved = true;
}
// 4 - check within subresolvers
if (!resolved && subResolvers.Count > 0)
{
for (int index = 0; index < subResolvers.Count; index++)
{
ISubDependencyResolver subResolver = subResolvers[index];
if (subResolver.CanResolve(context, contextHandlerResolver, model, dependency))
{
value = subResolver.Resolve(context, contextHandlerResolver, model, dependency);
resolved = true;
break;
}
}
}
// 5 - normal flow, checking against the kernel
if (!resolved)
{
if (dependency.DependencyType == DependencyType.Service ||
dependency.DependencyType == DependencyType.ServiceOverride)
{
value = ResolveServiceDependency(context, model, dependency);
}
else
{
value = ResolveParameterDependency(context, model, dependency);
}
}
if (value == null)
{
if (dependency.HasDefaultValue)
{
value = dependency.DefaultValue;
}
else if (dependency.IsOptional == false)
{
var implementation = String.Empty;
if (model.Implementation != null)
{
implementation = model.Implementation.FullName;
}
var message = String.Format(
"Could not resolve non-optional dependency for '{0}' ({1}). Parameter '{2}' type '{3}'",
model.Name, implementation, dependency.DependencyKey, dependency.TargetType.FullName);
throw new DependencyResolverException(message);
}
}
RaiseDependencyResolving(model, dependency, value);
return value;
}