private object TryCreateToConstruct(Type typeToConstruct, ConstructorInfo constructor, object tag, object[] parameters,
bool checkConstructor, bool hasMoreConstructorsLeft)
{
// Check if this constructor is even possible
if (checkConstructor)
{
if (!CanConstructorBeUsed(constructor, tag, true, parameters))
{
return null;
}
}
try
{
var finalParameters = new List<object>(parameters);
var ctorParameters = constructor.GetParameters();
for (int i = parameters.Length; i < ctorParameters.Length; i++)
{
object ctorParameterValue = null;
if (tag != null && _serviceLocator.IsTypeRegistered(ctorParameters[i].ParameterType, tag))
{
// Use preferred tag
ctorParameterValue = _serviceLocator.ResolveType(ctorParameters[i].ParameterType, tag);
}
else
{
// No tag or fallback to default without tag
ctorParameterValue = _serviceLocator.ResolveType(ctorParameters[i].ParameterType);
}
finalParameters.Add(ctorParameterValue);
}
var finalParametersArray = finalParameters.ToArray();
Log.Debug("Calling constructor.Invoke with the right parameters");
var instance = constructor.Invoke(finalParametersArray);
InitializeAfterConstruction(instance);
return instance;
}
#if NET
catch (MissingMethodException)
{
// Ignore, we accept this
}
#endif
catch (TargetParameterCountException)
{
// Ignore, we accept this
}
catch (CircularDependencyException)
{
// Only handle CircularDependencyExceptions we throw ourselves because we support generic types such as
// Dictionary<TKey, TValue> which has a constructor with IDictionary<TKey, TValue>
if (!hasMoreConstructorsLeft)
//if (string.Equals(TypeRequestPathName, ex.TypePath.Name, StringComparison.Ordinal))
{
throw;
}
}
catch (Exception ex)
{
// Real exceptions bubble up, otherwise return null
Log.Error(ex, "Failed to instantiate type '{0}', but this was an unexpected error", typeToConstruct.FullName);
throw;
}
Log.Debug("Failed to create instance using dependency injection for type '{0}' using constructor '{1}'",
typeToConstruct.FullName, constructor.GetSignature());
return null;
}