New Array resolution
This commit is contained in:
Родитель
95b80366a3
Коммит
b59c034309
|
@ -3,7 +3,6 @@ using System.Linq;
|
|||
using System.Reflection;
|
||||
using Unity.Builder;
|
||||
using Unity.Policy;
|
||||
using Unity.Registration;
|
||||
using Unity.Resolution;
|
||||
|
||||
namespace Unity.Factories
|
||||
|
@ -12,10 +11,13 @@ namespace Unity.Factories
|
|||
{
|
||||
#region Fields
|
||||
|
||||
private static readonly MethodInfo ResolveMethod =
|
||||
typeof(UnityContainer).GetTypeInfo()
|
||||
.GetDeclaredMethod(nameof(UnityContainer.GetArray));
|
||||
private static readonly MethodInfo ResolverMethod =
|
||||
typeof(ArrayResolver).GetTypeInfo()
|
||||
.GetDeclaredMethod(nameof(ArrayResolver.ResolverFactory));
|
||||
|
||||
private static readonly MethodInfo BuiltInMethod =
|
||||
typeof(ArrayResolver).GetTypeInfo()
|
||||
.GetDeclaredMethod(nameof(ArrayResolver.BuiltInFactory));
|
||||
#endregion
|
||||
|
||||
|
||||
|
@ -27,12 +29,16 @@ namespace Unity.Factories
|
|||
var typeArgument = context.RegistrationType.GetElementType();
|
||||
var targetType = ((UnityContainer)context.Container).GetTargetType(typeArgument);
|
||||
|
||||
// Simple types
|
||||
var method = (ResolveArray)
|
||||
ResolveMethod.MakeGenericMethod(typeArgument)
|
||||
.CreateDelegate(typeof(ResolveArray));
|
||||
if (typeArgument != targetType)
|
||||
{
|
||||
return ((BuiltInFactoryDelegate)BuiltInMethod
|
||||
.MakeGenericMethod(typeArgument)
|
||||
.CreateDelegate(typeof(BuiltInFactoryDelegate)))(targetType);
|
||||
}
|
||||
|
||||
return (ref BuilderContext c) => method(c.Resolve, c.Resolve);
|
||||
return ((ArrayFactoryDelegate)ResolverMethod
|
||||
.MakeGenericMethod(typeArgument)
|
||||
.CreateDelegate(typeof(ArrayFactoryDelegate)))();
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
@ -40,14 +46,48 @@ namespace Unity.Factories
|
|||
|
||||
#region Implementation
|
||||
|
||||
|
||||
private static ResolveDelegate<BuilderContext> ResolverFactory<TElement>()
|
||||
{
|
||||
#if NETSTANDARD1_0 || NETCOREAPP1_0
|
||||
if (typeof(TElement).GetTypeInfo().IsGenericType)
|
||||
#else
|
||||
if (typeof(TElement).IsGenericType)
|
||||
#endif
|
||||
{
|
||||
var definition = typeof(TElement).GetGenericTypeDefinition();
|
||||
return (ref BuilderContext c) => ((UnityContainer)c.Container).ResolveArray<TElement>(c.Resolve, typeof(TElement), definition)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return (ref BuilderContext c) => ((UnityContainer)c.Container).ResolveArray<TElement>(c.Resolve, typeof(TElement))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private static ResolveDelegate<BuilderContext> BuiltInFactory<TElement>(Type type)
|
||||
{
|
||||
#if NETSTANDARD1_0 || NETCOREAPP1_0
|
||||
var info = type.GetTypeInfo();
|
||||
if (info.IsGenericType && !info.IsGenericTypeDefinition)
|
||||
#else
|
||||
if (type.IsGenericType && !type.IsGenericTypeDefinition)
|
||||
#endif
|
||||
{
|
||||
var definition = type.GetGenericTypeDefinition();
|
||||
return (ref BuilderContext c) => ((UnityContainer)c.Container).ComplexArray<TElement>(c.Resolve, type, definition)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return (ref BuilderContext c) => ((UnityContainer)c.Container).ComplexArray<TElement>(c.Resolve, type)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Nested Types
|
||||
|
||||
|
||||
internal delegate object ResolveArray(Func<Type, string, object> resolve, Func<Type, string, InternalRegistration, object> resolveRegistration);
|
||||
private delegate ResolveDelegate<BuilderContext> ArrayFactoryDelegate();
|
||||
private delegate ResolveDelegate<BuilderContext> BuiltInFactoryDelegate(Type type);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@ namespace Unity.Factories
|
|||
|
||||
private static readonly MethodInfo EnumerableMethod =
|
||||
typeof(EnumerableResolver).GetTypeInfo()
|
||||
.GetDeclaredMethod(nameof(EnumerableResolver.ResolveEnumerable));
|
||||
.GetDeclaredMethod(nameof(EnumerableResolver.Resolver));
|
||||
|
||||
private static readonly MethodInfo GenericEnumerable =
|
||||
private static readonly MethodInfo EnumerableFactory =
|
||||
typeof(EnumerableResolver).GetTypeInfo()
|
||||
.GetDeclaredMethod(nameof(EnumerableResolver.ResolveGeneric));
|
||||
.GetDeclaredMethod(nameof(EnumerableResolver.ResolverFactory));
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -35,18 +35,15 @@ namespace Unity.Factories
|
|||
if (typeArgument.IsGenericType)
|
||||
#endif
|
||||
{
|
||||
var method = (ResolveEnumerableDelegate)
|
||||
GenericEnumerable.MakeGenericMethod(typeArgument)
|
||||
.CreateDelegate(typeof(ResolveEnumerableDelegate));
|
||||
|
||||
Type type = typeArgument.GetGenericTypeDefinition();
|
||||
|
||||
return (ref BuilderContext c) => method(ref c, type);
|
||||
return ((EnumerableFactoryDelegate)
|
||||
EnumerableFactory.MakeGenericMethod(typeArgument)
|
||||
.CreateDelegate(typeof(EnumerableFactoryDelegate)))();
|
||||
}
|
||||
else
|
||||
{
|
||||
return (ResolveDelegate<BuilderContext>)EnumerableMethod.MakeGenericMethod(typeArgument)
|
||||
.CreateDelegate(typeof(ResolveDelegate<BuilderContext>));
|
||||
return (ResolveDelegate<BuilderContext>)
|
||||
EnumerableMethod.MakeGenericMethod(typeArgument)
|
||||
.CreateDelegate(typeof(ResolveDelegate<BuilderContext>));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -55,18 +52,16 @@ namespace Unity.Factories
|
|||
|
||||
#region Implementation
|
||||
|
||||
private static object ResolveEnumerable<TElement>(ref BuilderContext context)
|
||||
private static object Resolver<TElement>(ref BuilderContext context)
|
||||
{
|
||||
return ((UnityContainer)context.Container).ResolveEnumerable<TElement>(context.Resolve,
|
||||
context.Resolve,
|
||||
context.Name);
|
||||
}
|
||||
|
||||
private static object ResolveGeneric<TElement>(ref BuilderContext context, Type type)
|
||||
private static ResolveDelegate<BuilderContext> ResolverFactory<TElement>()
|
||||
{
|
||||
return ((UnityContainer)context.Container).ResolveEnumerable<TElement>(context.Resolve,
|
||||
context.Resolve,
|
||||
type, context.Name);
|
||||
Type type = typeof(TElement).GetGenericTypeDefinition();
|
||||
return (ref BuilderContext c) => ((UnityContainer)c.Container).ResolveEnumerable<TElement>(c.Resolve, type, c.Name);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -74,7 +69,7 @@ namespace Unity.Factories
|
|||
|
||||
#region Nested Types
|
||||
|
||||
private delegate object ResolveEnumerableDelegate(ref BuilderContext context, Type type);
|
||||
private delegate ResolveDelegate<BuilderContext> EnumerableFactoryDelegate();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace Unity
|
|||
|
||||
private readonly object _syncRoot = new object();
|
||||
private LinkedNode<Type, object> _validators;
|
||||
|
||||
private Registrations _registrations;
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -88,13 +88,12 @@ namespace Unity
|
|||
|
||||
#region Resolving Enumerable
|
||||
|
||||
internal IEnumerable<TElement> ResolveEnumerable<TElement>(Func<Type, string, object> resolve,
|
||||
Func<Type, string, InternalRegistration, object> resolveRegistration,
|
||||
internal IEnumerable<TElement> ResolveEnumerable<TElement>(Func<Type, string, InternalRegistration, object> resolve,
|
||||
string name)
|
||||
{
|
||||
TElement value;
|
||||
var set = new QuickSet();
|
||||
int hashCode = typeof(TElement).GetHashCode() & HashMask;
|
||||
var set = new HashSet<string>();
|
||||
int hash = typeof(TElement).GetHashCode() & HashMask;
|
||||
|
||||
// Iterate over hierarchy
|
||||
for (var container = this; null != container; container = container._parent)
|
||||
|
@ -104,20 +103,19 @@ namespace Unity
|
|||
|
||||
// Hold on to registries
|
||||
var registry = container._registry;
|
||||
var metadata = container._metadata;
|
||||
|
||||
// Get indexes and iterate over them
|
||||
var length = metadata.GetEntries<TElement>(hashCode, out int[] data);
|
||||
var length = container._metadata.GetEntries<TElement>(hash, out int[] data);
|
||||
for (var i = 1; i < length; i++)
|
||||
{
|
||||
var index = data[i];
|
||||
var key = registry.Entries[index].Key.Name;
|
||||
|
||||
if (set.RequireToGrow) set = new QuickSet(set);
|
||||
if (set.Add(registry.Entries[index].HashCode, registry.Entries[index].Key.Type))
|
||||
if (set.Add(key))
|
||||
{
|
||||
try
|
||||
{
|
||||
value = (TElement)resolveRegistration(typeof(TElement), registry.Entries[index].Key.Name, registry.Entries[index].Value);
|
||||
value = (TElement)resolve(typeof(TElement), key, registry.Entries[index].Value);
|
||||
}
|
||||
catch (ArgumentException ex) when (ex.InnerException is TypeLoadException)
|
||||
{
|
||||
|
@ -134,7 +132,8 @@ namespace Unity
|
|||
{
|
||||
try
|
||||
{
|
||||
value = (TElement)resolve(typeof(TElement), name);
|
||||
var registration = GetRegistration(typeof(TElement), name);
|
||||
value = (TElement)resolve(typeof(TElement), name, registration);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -145,12 +144,11 @@ namespace Unity
|
|||
}
|
||||
}
|
||||
|
||||
internal IEnumerable<TElement> ResolveEnumerable<TElement>(Func<Type, string, object> resolve,
|
||||
Func<Type, string, InternalRegistration, object> resolveRegistration,
|
||||
internal IEnumerable<TElement> ResolveEnumerable<TElement>(Func<Type, string, InternalRegistration, object> resolve,
|
||||
Type typeDefinition, string name)
|
||||
{
|
||||
TElement value;
|
||||
var set = new QuickSet();
|
||||
var set = new HashSet<string>();
|
||||
int hashCode = typeof(TElement).GetHashCode() & HashMask;
|
||||
int hashGeneric = typeDefinition.GetHashCode() & HashMask;
|
||||
|
||||
|
@ -162,21 +160,19 @@ namespace Unity
|
|||
|
||||
// Hold on to registries
|
||||
var registry = container._registry;
|
||||
var metadata = container._metadata;
|
||||
|
||||
// Get indexes for bound types and iterate over them
|
||||
var length = metadata.GetEntries<TElement>(hashCode, out int[] data);
|
||||
var length = container._metadata.GetEntries<TElement>(hashCode, out int[] data);
|
||||
for (var i = 1; i < length; i++)
|
||||
{
|
||||
var index = data[i];
|
||||
var key = registry.Entries[index].Key.Name;
|
||||
|
||||
if (set.RequireToGrow) set = new QuickSet(set);
|
||||
if (set.Add(registry.Entries[index].HashCode, registry.Entries[index].Key.Type))
|
||||
if (set.Add(key))
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
value = (TElement)resolveRegistration(typeof(TElement), registry.Entries[index].Key.Name, registry.Entries[index].Value);
|
||||
value = (TElement)resolve(typeof(TElement), key, registry.Entries[index].Value);
|
||||
}
|
||||
catch (ArgumentException ex) when (ex.InnerException is TypeLoadException)
|
||||
{
|
||||
|
@ -188,17 +184,19 @@ namespace Unity
|
|||
}
|
||||
|
||||
// Get indexes for unbound types and iterate over them
|
||||
length = metadata.GetEntries(hashGeneric, typeDefinition, out data);
|
||||
length = container._metadata.GetEntries(hashGeneric, typeDefinition, out data);
|
||||
for (var i = 1; i < length; i++)
|
||||
{
|
||||
var index = data[i];
|
||||
var key = registry.Entries[index].Key.Name;
|
||||
|
||||
if (set.RequireToGrow) set = new QuickSet(set);
|
||||
if (set.Add(registry.Entries[index].HashCode, registry.Entries[index].Key.Type))
|
||||
if (set.Add(key))
|
||||
{
|
||||
try
|
||||
{
|
||||
value = (TElement)resolve(typeof(TElement), registry.Entries[index].Key.Name);
|
||||
int hash = NamedType.GetHashCode(typeof(TElement), key) & 0x7FFFFFFF;
|
||||
var registration = container.GetOrAdd(hash, typeof(TElement), key, registry.Entries[index].Value);
|
||||
value = (TElement)resolve(typeof(TElement), key, registration);
|
||||
}
|
||||
catch (MakeGenericTypeFailedException) { continue; }
|
||||
catch (InvalidOperationException ex) when (ex.InnerException is InvalidRegistrationException)
|
||||
|
@ -221,7 +219,8 @@ namespace Unity
|
|||
{
|
||||
try
|
||||
{
|
||||
value = (TElement)resolve(typeof(TElement), name);
|
||||
var registration = GetRegistration(typeof(TElement), name);
|
||||
value = (TElement)resolve(typeof(TElement), name, registration);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -267,12 +266,11 @@ namespace Unity
|
|||
return argType;
|
||||
}
|
||||
|
||||
internal IEnumerable<TElement> ResolveArray<TElement>(Func<Type, string, object> resolve,
|
||||
Func<Type, string, InternalRegistration, object> resolveRegistration)
|
||||
internal IEnumerable<TElement> ResolveArray<TElement>(Func<Type, string, InternalRegistration, object> resolve, Type type)
|
||||
{
|
||||
TElement value;
|
||||
var set = new QuickSet();
|
||||
int hashCode = typeof(TElement).GetHashCode() & HashMask;
|
||||
var set = new HashSet<string>();
|
||||
int hash = type.GetHashCode() & HashMask;
|
||||
|
||||
// Iterate over hierarchy
|
||||
for (var container = this; null != container; container = container._parent)
|
||||
|
@ -282,20 +280,19 @@ namespace Unity
|
|||
|
||||
// Hold on to registries
|
||||
var registry = container._registry;
|
||||
var metadata = container._metadata;
|
||||
|
||||
// Get indexes and iterate over them
|
||||
var length = metadata.GetEntries<TElement>(hashCode, out int[] data);
|
||||
var length = container._metadata.GetEntries(hash, type, out int[] data);
|
||||
for (var i = 1; i < length; i++)
|
||||
{
|
||||
var index = data[i];
|
||||
|
||||
if (set.RequireToGrow) set = new QuickSet(set);
|
||||
if (set.Add(registry.Entries[index].HashCode, registry.Entries[index].Key.Type))
|
||||
var key = registry.Entries[index].Key.Name;
|
||||
if (null == key) continue;
|
||||
if (set.Add(key))
|
||||
{
|
||||
try
|
||||
{
|
||||
value = (TElement)resolveRegistration(typeof(TElement), registry.Entries[index].Key.Name, registry.Entries[index].Value);
|
||||
value = (TElement)resolve(typeof(TElement), key, registry.Entries[index].Value);
|
||||
}
|
||||
catch (ArgumentException ex) when (ex.InnerException is TypeLoadException)
|
||||
{
|
||||
|
@ -308,11 +305,13 @@ namespace Unity
|
|||
}
|
||||
}
|
||||
|
||||
internal IEnumerable<TElement> GetArray<TElement>(Func<Type, string, InternalRegistration, object> resolve)
|
||||
internal IEnumerable<TElement> ResolveArray<TElement>(Func<Type, string, InternalRegistration, object> resolve,
|
||||
Type type, Type typeDefinition)
|
||||
{
|
||||
TElement value;
|
||||
var set = new HashSet<string>();
|
||||
int hashCode = typeof(TElement).GetHashCode() & HashMask;
|
||||
int hashCode = type.GetHashCode() & HashMask;
|
||||
int hashGeneric = typeDefinition.GetHashCode() & HashMask;
|
||||
|
||||
// Iterate over hierarchy
|
||||
for (var container = this; null != container; container = container._parent)
|
||||
|
@ -322,21 +321,92 @@ namespace Unity
|
|||
|
||||
// Hold on to registries
|
||||
var registry = container._registry;
|
||||
var metadata = container._metadata;
|
||||
|
||||
// Get indexes and iterate over them
|
||||
var length = metadata.GetEntries<TElement>(hashCode, out int[] data);
|
||||
// Get indexes for bound types and iterate over them
|
||||
var length = container._metadata.GetEntries(hashCode, type, out int[] data);
|
||||
for (var i = 1; i < length; i++)
|
||||
{
|
||||
var index = data[i];
|
||||
var name = registry.Entries[index].Key.Name;
|
||||
var key = registry.Entries[index].Key.Name;
|
||||
|
||||
if (null == name) continue;
|
||||
if (set.Add(name))
|
||||
if (null == key) continue;
|
||||
if (set.Add(key))
|
||||
{
|
||||
try
|
||||
{
|
||||
value = (TElement)resolve(typeof(TElement), name, registry.Entries[index].Value);
|
||||
value = (TElement)resolve(typeof(TElement), key, registry.Entries[index].Value);
|
||||
}
|
||||
catch (ArgumentException ex) when (ex.InnerException is TypeLoadException)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return value;
|
||||
}
|
||||
}
|
||||
|
||||
// Get indexes for unbound types and iterate over them
|
||||
length = container._metadata.GetEntries(hashGeneric, typeDefinition, out data);
|
||||
for (var i = 1; i < length; i++)
|
||||
{
|
||||
var index = data[i];
|
||||
var key = registry.Entries[index].Key.Name;
|
||||
|
||||
if (null == key) continue;
|
||||
if (set.Add(key))
|
||||
{
|
||||
try
|
||||
{
|
||||
int hash = NamedType.GetHashCode(typeof(TElement), key) & 0x7FFFFFFF;
|
||||
var registration = container.GetOrAdd(hash, typeof(TElement), key, registry.Entries[index].Value);
|
||||
value = (TElement)resolve(typeof(TElement), key, registration);
|
||||
}
|
||||
catch (MakeGenericTypeFailedException) { continue; }
|
||||
catch (InvalidOperationException ex) when (ex.InnerException is InvalidRegistrationException)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// TODO: Verify if required
|
||||
//catch (ArgumentException ex) when (ex.InnerException is TypeLoadException)
|
||||
//{
|
||||
// continue;
|
||||
//}
|
||||
|
||||
yield return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal IEnumerable<TElement> ComplexArray<TElement>(Func<Type, string, InternalRegistration, object> resolve, Type type)
|
||||
{
|
||||
TElement value;
|
||||
var set = new HashSet<string>();
|
||||
int hashCode = type.GetHashCode() & HashMask;
|
||||
|
||||
// Iterate over hierarchy
|
||||
for (var container = this; null != container; container = container._parent)
|
||||
{
|
||||
// Skip to parent if no data
|
||||
if (null == container._metadata) continue;
|
||||
|
||||
// Hold on to registries
|
||||
var registry = container._registry;
|
||||
|
||||
// Get indexes and iterate over them
|
||||
var length = container._metadata.GetEntries(hashCode, type, out int[] data);
|
||||
for (var i = 1; i < length; i++)
|
||||
{
|
||||
var index = data[i];
|
||||
var key = registry.Entries[index].Key.Name;
|
||||
if (null == key) continue;
|
||||
if (set.Add(key))
|
||||
{
|
||||
try
|
||||
{
|
||||
int hash = NamedType.GetHashCode(typeof(TElement), key) & 0x7FFFFFFF;
|
||||
var registration = container.GetOrAdd(hash, typeof(TElement), key, registry.Entries[index].Value);
|
||||
value = (TElement)resolve(typeof(TElement), key, registration);
|
||||
}
|
||||
catch (ArgumentException ex) when (ex.InnerException is TypeLoadException)
|
||||
{
|
||||
|
@ -349,11 +419,13 @@ namespace Unity
|
|||
}
|
||||
}
|
||||
|
||||
internal IEnumerable<TElement> ResolveArrayTarget<TElement, TTarget>(Func<Type, string, object> resolve)
|
||||
internal IEnumerable<TElement> ComplexArray<TElement>(Func<Type, string, InternalRegistration, object> resolve,
|
||||
Type type, Type typeDefinition)
|
||||
{
|
||||
TElement value;
|
||||
var set = new HashSet<string>();
|
||||
int hashCode = typeof(TTarget).GetHashCode() & HashMask;
|
||||
int hashCode = type.GetHashCode() & HashMask;
|
||||
int hashGeneric = typeDefinition.GetHashCode() & HashMask;
|
||||
|
||||
// Iterate over hierarchy
|
||||
for (var container = this; null != container; container = container._parent)
|
||||
|
@ -363,21 +435,22 @@ namespace Unity
|
|||
|
||||
// Hold on to registries
|
||||
var registry = container._registry;
|
||||
var metadata = container._metadata;
|
||||
|
||||
// Get indexes and iterate over them
|
||||
var length = metadata.GetEntries<TTarget>(hashCode, out int[] data);
|
||||
// Get indexes for bound types and iterate over them
|
||||
var length = container._metadata.GetEntries(hashCode, type, out int[] data);
|
||||
for (var i = 1; i < length; i++)
|
||||
{
|
||||
var index = data[i];
|
||||
var name = registry.Entries[index].Key.Name;
|
||||
var key = registry.Entries[index].Key.Name;
|
||||
|
||||
if (null == name) continue;
|
||||
if (set.Add(name))
|
||||
if (null == key) continue;
|
||||
if (set.Add(key))
|
||||
{
|
||||
try
|
||||
{
|
||||
value = (TElement)resolve(typeof(TElement), name);
|
||||
int hash = NamedType.GetHashCode(typeof(TElement), key) & 0x7FFFFFFF;
|
||||
var registration = container.GetOrAdd(hash, typeof(TElement), key, registry.Entries[index].Value);
|
||||
value = (TElement)resolve(typeof(TElement), key, registration);
|
||||
}
|
||||
catch (ArgumentException ex) when (ex.InnerException is TypeLoadException)
|
||||
{
|
||||
|
@ -387,43 +460,33 @@ namespace Unity
|
|||
yield return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal IEnumerable<TElement> DefinitionArray<TElement>(Func<Type, string, InternalRegistration, object> resolve, Type type)
|
||||
{
|
||||
TElement value;
|
||||
var set = new HashSet<string>();
|
||||
int hashCode = typeof(TElement).GetHashCode() & HashMask;
|
||||
|
||||
// Iterate over hierarchy
|
||||
for (var container = this; null != container; container = container._parent)
|
||||
{
|
||||
// Skip to parent if no data
|
||||
if (null == container._metadata) continue;
|
||||
|
||||
// Hold on to registries
|
||||
var registry = container._registry;
|
||||
var metadata = container._metadata;
|
||||
|
||||
// Get indexes and iterate over them
|
||||
var length = metadata.GetEntries<TElement>(hashCode, out int[] data);
|
||||
// Get indexes for unbound types and iterate over them
|
||||
length = container._metadata.GetEntries(hashGeneric, typeDefinition, out data);
|
||||
for (var i = 1; i < length; i++)
|
||||
{
|
||||
var index = data[i];
|
||||
var name = registry.Entries[index].Key.Name;
|
||||
var key = registry.Entries[index].Key.Name;
|
||||
|
||||
if (null == name) continue;
|
||||
if (set.Add(name))
|
||||
if (null == key) continue;
|
||||
if (set.Add(key))
|
||||
{
|
||||
try
|
||||
{
|
||||
value = (TElement)resolve(typeof(TElement), name, registry.Entries[index].Value);
|
||||
int hash = NamedType.GetHashCode(typeof(TElement), key) & 0x7FFFFFFF;
|
||||
var registration = container.GetOrAdd(hash, typeof(TElement), key, registry.Entries[index].Value);
|
||||
value = (TElement)resolve(typeof(TElement), key, registration);
|
||||
}
|
||||
catch (ArgumentException ex) when (ex.InnerException is TypeLoadException)
|
||||
catch (MakeGenericTypeFailedException) { continue; }
|
||||
catch (InvalidOperationException ex) when (ex.InnerException is InvalidRegistrationException)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// TODO: Verify if required
|
||||
//catch (ArgumentException ex) when (ex.InnerException is TypeLoadException)
|
||||
//{
|
||||
// continue;
|
||||
//}
|
||||
|
||||
yield return value;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче