|
using System;
using System.Collections.Generic;
using System.Globalization;
using Microsoft.Practices.ObjectBuilder;
using ObjectBuilder.Extension.Properties;
namespace ObjectBuilder.Extension
{
public class IADependencyResolver
{
IBuilderContext context;
/// <summary>
/// Constructor.
/// </summary>
/// <param name="context">The builder context in which the resolver will resolve
/// dependencies.</param>
public IADependencyResolver(IBuilderContext context)
{
if (context == null)
throw new ArgumentNullException("context");
this.context = context;
}
/// <summary>
/// Resolves a dependency.
/// </summary>
/// <param name="typeToResolve">The type to be resolved.</param>
/// <param name="typeToCreate">
/// The type to be created, if the type cannot be resolved (and notPresent is set to <see cref="NotPresentBehavior.CreateNew"/>).
/// </param>
/// <param name="id">The ID of the object to be resolved. Pass null for the unnamed object.</param>
/// <param name="notPresent">Flag to describe how to behave if the dependency is not found.</param>
/// <param name="searchMode">Flag to describe whether searches are local only, or local and up.</param>
/// <returns>
/// The dependent object. If the object is not found, and notPresent is set to <see cref="NotPresentBehavior.ReturnNull"/>, will return null.
/// </returns>
public object Resolve(Type typeToResolve, Type typeToCreate, string id, NotPresentBehavior notPresent, SearchMode searchMode)
{
if (typeToResolve == null)
throw new ArgumentNullException("typeToResolve");
if (!Enum.IsDefined(typeof(NotPresentBehavior), notPresent))
throw new ArgumentException(Resources.InvalidEnumerationValue, "notPresent");
if (typeToCreate == null)
typeToCreate = typeToResolve;
DependencyResolutionLocatorKey key = new DependencyResolutionLocatorKey(typeToResolve, id);
// See if the item can be located using the DRLK...
if (context.Locator.Contains(key, searchMode))
return context.Locator.Get(key, searchMode);
// When injecting items with the DependencyAttribute it doesn't take into account implemented interfaces.
// This code fixes that behaviour.
else if (!string.IsNullOrEmpty(id))
{
// See if we can find the item requested
object retVal = ResolveBasedOnId(typeToResolve, id, searchMode);
// If we've found the item requested, return it
if (retVal != null) return retVal;
}
switch (notPresent)
{
case NotPresentBehavior.CreateNew:
return context.HeadOfChain.BuildUp(context, typeToCreate, null, key.ID);
case NotPresentBehavior.ReturnNull:
return null;
default:
throw new DependencyMissingException(string.Format(CultureInfo.CurrentCulture, Resources.DependencyMissing, typeToResolve.ToString()));
}
}
/// <summary>
/// Resolves the item based on id.
/// </summary>
/// <param name="typeToResolve">The type to resolve.</param>
/// <param name="id">The id.</param>
/// <param name="searchMode">The search mode.</param>
/// <returns></returns>
private object ResolveBasedOnId(Type typeToResolve, string id, SearchMode searchMode)
{
IReadableLocator locator = context.Locator;
object retVal = null;
// This loop is for if we're going up the parents of the list
while ((retVal == null) && (locator != null))
{
// Go through all the items in the locator
foreach (KeyValuePair<object, object> pair in locator)
{
// We're only interested in things that have a DependencyResolutionLocatorKey key
if (pair.Key is DependencyResolutionLocatorKey)
{
DependencyResolutionLocatorKey depKey = (DependencyResolutionLocatorKey)pair.Key;
// See if the key's id and the id we're looking for match
if (object.Equals(depKey.ID, id))
retVal = IsResolvable(pair.Value, typeToResolve);
}
// Do a check to see if we've found our object (no point carrying on if we have!)
if (retVal != null) return retVal;
}
// See if we need to go up to the parent. This is done under the following conditions:
// - searchMode has been set to up
if (searchMode == SearchMode.Up)
locator = locator.ParentLocator;
else
locator = null;
}
// Return whatever we have (or haven't) found
return retVal;
}
/// <summary>
/// Determines whether the specified object is resolvable to the specified type.
/// </summary>
/// <param name="Test">The object to test.</param>
/// <param name="typeToResolve">The type to resolve.</param>
/// <returns><c>Test</c> if the object is resolvable; otherwise <c>null</c>.</returns>
private object IsResolvable(object Test, Type typeToResolve)
{
if (typeToResolve.IsAssignableFrom(Test.GetType()))
return Test;
else
return null;
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.