Fixed #122
This commit is contained in:
Родитель
9facbe1a97
Коммит
a5de16804a
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security;
|
||||
using Unity.Policy;
|
||||
using Unity.Registration;
|
||||
|
@ -22,6 +23,8 @@ namespace Unity.Builder
|
|||
public ResolverOverride[] Overrides;
|
||||
public IPolicyList list;
|
||||
|
||||
public delegate object ExecutePlanDelegate(BuilderStrategy[] chain, ref BuilderContext context);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
@ -92,8 +95,13 @@ namespace Unity.Builder
|
|||
|
||||
public bool BuildComplete;
|
||||
|
||||
// TODO: Replace with Parent
|
||||
public Type DeclaringType { get; private set; }
|
||||
|
||||
public IntPtr Parent;
|
||||
|
||||
public ExecutePlanDelegate ExecutePlan;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
@ -101,20 +109,25 @@ namespace Unity.Builder
|
|||
|
||||
public object Resolve(Type type, string name, InternalRegistration registration)
|
||||
{
|
||||
var context = new BuilderContext
|
||||
unsafe
|
||||
{
|
||||
Lifetime = Lifetime,
|
||||
Registration = registration,
|
||||
RegistrationType = type,
|
||||
Name = name,
|
||||
Type = registration is ContainerRegistration containerRegistration ? containerRegistration.Type : type,
|
||||
var thisContext = this;
|
||||
var context = new BuilderContext
|
||||
{
|
||||
Lifetime = Lifetime,
|
||||
Registration = registration,
|
||||
RegistrationType = type,
|
||||
Name = name,
|
||||
Type = registration is ContainerRegistration containerRegistration ? containerRegistration.Type : type,
|
||||
ExecutePlan = ExecutePlan,
|
||||
list = list,
|
||||
Overrides = Overrides,
|
||||
Parent = new IntPtr(Unsafe.AsPointer(ref thisContext)),
|
||||
DeclaringType = RegistrationType
|
||||
};
|
||||
|
||||
list = list,
|
||||
Overrides = Overrides,
|
||||
DeclaringType = RegistrationType
|
||||
};
|
||||
|
||||
return ExecuteReThrowingPlan(registration.BuildChain, ref context);
|
||||
return ExecutePlan(registration.BuildChain, ref context);
|
||||
}
|
||||
}
|
||||
|
||||
public object Resolve(ParameterInfo parameter, string name, object value)
|
||||
|
@ -285,36 +298,5 @@ namespace Unity.Builder
|
|||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Implementation
|
||||
|
||||
|
||||
private static object ExecuteReThrowingPlan(BuilderStrategy[] chain, ref BuilderContext context)
|
||||
{
|
||||
var i = -1;
|
||||
|
||||
try
|
||||
{
|
||||
while (!context.BuildComplete && ++i < chain.Length)
|
||||
{
|
||||
chain[i].PreBuildUp(ref context);
|
||||
}
|
||||
|
||||
while (--i >= 0)
|
||||
{
|
||||
chain[i].PostBuildUp(ref context);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
context.RequiresRecovery?.Recover();
|
||||
throw;
|
||||
}
|
||||
|
||||
return context.Existing;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace Unity.Extension
|
|||
{
|
||||
protected override void Initialize()
|
||||
{
|
||||
((UnityContainer)Container).ExecutePlan = UnityContainer.ExecuteValidatingPlan;
|
||||
}
|
||||
|
||||
public void ForceCompile()
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace Unity.Processors
|
|||
|
||||
protected override Type MemberType(TMemberInfo info) => info.DeclaringType;
|
||||
|
||||
protected override IEnumerable<object> SelectMembers(Type type, TMemberInfo[] members, InjectionMember[] injectors)
|
||||
protected override IEnumerable<object> SelectMembers(Type type, IEnumerable<TMemberInfo> members, InjectionMember[] injectors)
|
||||
{
|
||||
// Select Injected Members
|
||||
if (null != injectors)
|
||||
|
@ -56,7 +56,7 @@ namespace Unity.Processors
|
|||
}
|
||||
}
|
||||
|
||||
if (null == members || 0 == members.Length) yield break;
|
||||
if (null == members) yield break;
|
||||
|
||||
// Select Attributed members
|
||||
foreach (var member in members)
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace Unity.Processors
|
|||
|
||||
#region Implementation
|
||||
|
||||
protected virtual IEnumerable<object> SelectMembers(Type type, TMemberInfo[] members, InjectionMember[] injectors)
|
||||
protected virtual IEnumerable<object> SelectMembers(Type type, IEnumerable<TMemberInfo> members, InjectionMember[] injectors)
|
||||
{
|
||||
// Select Injected Members
|
||||
if (null != injectors)
|
||||
|
@ -37,7 +37,7 @@ namespace Unity.Processors
|
|||
}
|
||||
}
|
||||
|
||||
if (null == members || 0 == members.Length) yield break;
|
||||
if (null == members) yield break;
|
||||
|
||||
// Select Attributed members
|
||||
foreach (var member in members)
|
||||
|
@ -52,7 +52,7 @@ namespace Unity.Processors
|
|||
}
|
||||
}
|
||||
|
||||
protected virtual TMemberInfo[] DeclaredMembers(Type type) => new TMemberInfo[0];
|
||||
protected virtual IEnumerable<TMemberInfo> DeclaredMembers(Type type) => new TMemberInfo[0];
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ using Unity.Storage;
|
|||
|
||||
namespace Unity.Processors
|
||||
{
|
||||
public partial class ConstructorProcessor : MethodBaseInfoProcessor<ConstructorInfo>
|
||||
public partial class ConstructorProcessor
|
||||
{
|
||||
#region Fields
|
||||
|
||||
|
@ -98,7 +98,7 @@ namespace Unity.Processors
|
|||
{
|
||||
// Validate if Type could be created
|
||||
var exceptionExpr = ValidateConstructedTypeExpression(type);
|
||||
if (null != exceptionExpr) return new Expression[] { exceptionExpr };
|
||||
if (null != exceptionExpr) return new[] { exceptionExpr };
|
||||
|
||||
// Select ConstructorInfo
|
||||
var selector = GetPolicy<ISelect<ConstructorInfo>>(registration);
|
||||
|
@ -106,7 +106,7 @@ namespace Unity.Processors
|
|||
.FirstOrDefault();
|
||||
|
||||
// Validate constructor info
|
||||
if (null == selection) return new Expression[] { NoConstructorExpr };
|
||||
if (null == selection) return new[] { NoConstructorExpr };
|
||||
|
||||
|
||||
// Select appropriate ctor for the Type
|
||||
|
@ -128,14 +128,14 @@ namespace Unity.Processors
|
|||
}
|
||||
|
||||
// Get lifetime manager
|
||||
var LifetimeManager = (LifetimeManager)registration.Get(typeof(LifetimeManager));
|
||||
var lifetimeManager = (LifetimeManager)registration.Get(typeof(LifetimeManager));
|
||||
|
||||
|
||||
// Validate parameters
|
||||
var parameters = info.GetParameters();
|
||||
if (parameters.Any(p => p.ParameterType == info.DeclaringType))
|
||||
{
|
||||
if (null == LifetimeManager?.GetValue())
|
||||
if (null == lifetimeManager?.GetValue())
|
||||
{
|
||||
return new Expression[]
|
||||
{
|
||||
|
@ -153,14 +153,14 @@ namespace Unity.Processors
|
|||
}
|
||||
|
||||
// Create 'new' expression
|
||||
var IfThenExpr = Expression.IfThen(
|
||||
var ifThenExpr = Expression.IfThen(
|
||||
Expression.Equal(Expression.Constant(null), BuilderContextExpression.Existing),
|
||||
BuildMemberExpression(info, resolvers));
|
||||
|
||||
// Check if PerResolveLifetimeManager is required
|
||||
return registration.Get(typeof(LifetimeManager)) is PerResolveLifetimeManager
|
||||
? new Expression[] { IfThenExpr, SetPerBuildSingletonExpr }
|
||||
: new Expression[] { IfThenExpr };
|
||||
? new[] { ifThenExpr, SetPerBuildSingletonExpr }
|
||||
: new Expression[] { ifThenExpr };
|
||||
}
|
||||
|
||||
protected override Expression BuildMemberExpression(ConstructorInfo info, object[] resolvers)
|
||||
|
|
|
@ -10,7 +10,7 @@ using Unity.Storage;
|
|||
|
||||
namespace Unity.Processors
|
||||
{
|
||||
public partial class ConstructorProcessor : MethodBaseInfoProcessor<ConstructorInfo>
|
||||
public partial class ConstructorProcessor
|
||||
{
|
||||
#region Overrides
|
||||
|
||||
|
@ -57,13 +57,13 @@ namespace Unity.Processors
|
|||
}
|
||||
|
||||
// Get lifetime manager
|
||||
var LifetimeManager = (LifetimeManager)registration.Get(typeof(LifetimeManager));
|
||||
var lifetimeManager = (LifetimeManager)registration.Get(typeof(LifetimeManager));
|
||||
|
||||
// Validate parameters
|
||||
var parameters = info.GetParameters();
|
||||
if (parameters.Any(p => p.ParameterType == info.DeclaringType))
|
||||
{
|
||||
if (null == LifetimeManager?.GetValue())
|
||||
if (null == lifetimeManager?.GetValue())
|
||||
return (ref BuilderContext c) =>
|
||||
{
|
||||
if (null == c.Existing)
|
||||
|
@ -76,7 +76,7 @@ namespace Unity.Processors
|
|||
|
||||
// Create dependency resolvers
|
||||
var parameterResolvers = CreateParameterResolvers(parameters, resolvers).ToArray();
|
||||
if (LifetimeManager is PerResolveLifetimeManager)
|
||||
if (lifetimeManager is PerResolveLifetimeManager)
|
||||
{
|
||||
// PerResolve lifetime
|
||||
return (ref BuilderContext c) =>
|
||||
|
|
|
@ -39,20 +39,18 @@ namespace Unity.Processors
|
|||
|
||||
#region Overrides
|
||||
|
||||
protected override ConstructorInfo[] DeclaredMembers(Type type)
|
||||
protected override IEnumerable<ConstructorInfo> DeclaredMembers(Type type)
|
||||
{
|
||||
#if NETSTANDARD1_0
|
||||
return type.GetTypeInfo()
|
||||
.DeclaredConstructors
|
||||
.Where(c => c.IsStatic == false && c.IsPublic)
|
||||
.ToArray();
|
||||
.Where(c => c.IsStatic == false && c.IsPublic);
|
||||
#else
|
||||
return type.GetConstructors(BindingFlags.Instance | BindingFlags.Public)
|
||||
.ToArray();
|
||||
return type.GetConstructors(BindingFlags.Instance | BindingFlags.Public);
|
||||
#endif
|
||||
}
|
||||
|
||||
protected override IEnumerable<object> SelectMembers(Type type, ConstructorInfo[] members, InjectionMember[] injectors)
|
||||
protected override IEnumerable<object> SelectMembers(Type type, IEnumerable<ConstructorInfo> members, InjectionMember[] injectors)
|
||||
{
|
||||
// Select Injected Members
|
||||
if (null != injectors)
|
||||
|
@ -67,27 +65,34 @@ namespace Unity.Processors
|
|||
}
|
||||
}
|
||||
|
||||
if (null == members || 0 == members.Length) yield break;
|
||||
if (1 == members.Length)
|
||||
if (null == members) yield break;
|
||||
|
||||
// Enumerate to array
|
||||
var constructors = members.ToArray();
|
||||
switch (constructors.Length)
|
||||
{
|
||||
yield return members[0];
|
||||
yield break;
|
||||
case 0:
|
||||
yield break;
|
||||
|
||||
case 1:
|
||||
yield return constructors[0];
|
||||
yield break;
|
||||
}
|
||||
|
||||
// Select Attributed members
|
||||
foreach (var member in members)
|
||||
foreach (var constructor in constructors)
|
||||
{
|
||||
foreach (var pair in ResolverFactories)
|
||||
{
|
||||
if (!member.IsDefined(pair.type)) continue;
|
||||
if (!constructor.IsDefined(pair.type)) continue;
|
||||
|
||||
yield return member;
|
||||
yield return constructor;
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
|
||||
// Select default
|
||||
yield return SelectMethod(type, members);
|
||||
yield return SelectMethod(type, constructors);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
@ -37,9 +38,14 @@ namespace Unity.Processors
|
|||
|
||||
#region Overrides
|
||||
|
||||
protected override FieldInfo[] DeclaredMembers(Type type)
|
||||
protected override IEnumerable<FieldInfo> DeclaredMembers(Type type)
|
||||
{
|
||||
return new FieldInfo[0];
|
||||
#if NETSTANDARD1_0
|
||||
return GetFieldsHierarchical(type).Where(f => !f.IsInitOnly && !f.IsStatic);
|
||||
#else
|
||||
return type.GetFields(BindingFlags.Instance | BindingFlags.Public)
|
||||
.Where(f => !f.IsInitOnly && !f.IsStatic);
|
||||
#endif
|
||||
}
|
||||
|
||||
protected override Type MemberType(FieldInfo info) => info.FieldType;
|
||||
|
@ -88,7 +94,7 @@ namespace Unity.Processors
|
|||
{
|
||||
try
|
||||
{
|
||||
((PropertyInfo)info).SetValue(context.Existing,
|
||||
((FieldInfo)info).SetValue(context.Existing,
|
||||
context.Resolve((FieldInfo)info, ((DependencyResolutionAttribute)attribute).Name, resolver));
|
||||
return context.Existing;
|
||||
}
|
||||
|
@ -101,5 +107,27 @@ namespace Unity.Processors
|
|||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Implementation
|
||||
|
||||
public static IEnumerable<FieldInfo> GetFieldsHierarchical(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
return Enumerable.Empty<FieldInfo>();
|
||||
}
|
||||
|
||||
if (type == typeof(object))
|
||||
{
|
||||
return type.GetTypeInfo().DeclaredFields;
|
||||
}
|
||||
|
||||
return type.GetTypeInfo()
|
||||
.DeclaredFields
|
||||
.Concat(GetFieldsHierarchical(type.GetTypeInfo().BaseType));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
@ -25,15 +26,13 @@ namespace Unity.Processors
|
|||
|
||||
#region Selection
|
||||
|
||||
protected override MethodInfo[] DeclaredMembers(Type type)
|
||||
protected override IEnumerable<MethodInfo> DeclaredMembers(Type type)
|
||||
{
|
||||
#if NETSTANDARD1_0
|
||||
return type.GetMethodsHierarchical()
|
||||
.Where(c => c.IsStatic == false && c.IsPublic)
|
||||
.ToArray();
|
||||
.Where(c => c.IsStatic == false && c.IsPublic);
|
||||
#else
|
||||
return type.GetMethods(BindingFlags.Instance | BindingFlags.Public)
|
||||
.ToArray();
|
||||
return type.GetMethods(BindingFlags.Instance | BindingFlags.Public);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
@ -38,28 +39,26 @@ namespace Unity.Processors
|
|||
|
||||
#region Overrides
|
||||
|
||||
protected override PropertyInfo[] DeclaredMembers(Type type)
|
||||
protected override IEnumerable<PropertyInfo> DeclaredMembers(Type type)
|
||||
{
|
||||
#if NETSTANDARD1_0
|
||||
return type.GetPropertiesHierarchical()
|
||||
.Where(p =>
|
||||
{
|
||||
if (!p.CanWrite) return false;
|
||||
return GetPropertiesHierarchical(type)
|
||||
.Where(p =>
|
||||
{
|
||||
if (!p.CanWrite) return false;
|
||||
|
||||
var propertyMethod = p.GetSetMethod(true) ??
|
||||
p.GetGetMethod(true);
|
||||
var propertyMethod = p.GetSetMethod(true) ??
|
||||
p.GetGetMethod(true);
|
||||
|
||||
// Skip static properties and indexers.
|
||||
if (propertyMethod.IsStatic || p.GetIndexParameters().Length != 0)
|
||||
return false;
|
||||
// Skip static properties and indexers.
|
||||
if (propertyMethod.IsStatic || p.GetIndexParameters().Length != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
})
|
||||
.ToArray();
|
||||
return true;
|
||||
});
|
||||
#else
|
||||
return type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
|
||||
.Where(p => p.CanWrite && p.GetIndexParameters().Length == 0)
|
||||
.ToArray();
|
||||
.Where(p => p.CanWrite && p.GetIndexParameters().Length == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -123,5 +122,27 @@ namespace Unity.Processors
|
|||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Implementation
|
||||
|
||||
public static IEnumerable<PropertyInfo> GetPropertiesHierarchical(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
return Enumerable.Empty<PropertyInfo>();
|
||||
}
|
||||
|
||||
if (type == typeof(object))
|
||||
{
|
||||
return type.GetTypeInfo().DeclaredProperties;
|
||||
}
|
||||
|
||||
return type.GetTypeInfo()
|
||||
.DeclaredProperties
|
||||
.Concat(GetPropertiesHierarchical(type.GetTypeInfo().BaseType));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -163,6 +163,7 @@ namespace Unity
|
|||
Registration = registration,
|
||||
RegistrationType = type,
|
||||
Name = name,
|
||||
ExecutePlan = ExecutePlan,
|
||||
Type = registration is ContainerRegistration containerRegistration
|
||||
? containerRegistration.Type : type,
|
||||
};
|
||||
|
@ -193,6 +194,7 @@ namespace Unity
|
|||
Registration = registration,
|
||||
RegistrationType = type,
|
||||
Name = name,
|
||||
ExecutePlan = ExecutePlan,
|
||||
Type = registration is ContainerRegistration containerRegistration
|
||||
? containerRegistration.Type : type
|
||||
};
|
||||
|
|
|
@ -3,6 +3,8 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -18,6 +20,7 @@ namespace Unity
|
|||
/// <summary>
|
||||
/// A simple, extensible dependency injection container.
|
||||
/// </summary>
|
||||
[SecuritySafeCritical]
|
||||
public partial class UnityContainer
|
||||
{
|
||||
#region Dynamic Registrations
|
||||
|
@ -318,5 +321,100 @@ namespace Unity
|
|||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Implementation
|
||||
|
||||
internal BuilderContext.ExecutePlanDelegate ExecutePlan { get; set; } =
|
||||
(BuilderStrategy[] chain, ref BuilderContext context) =>
|
||||
{
|
||||
var i = -1;
|
||||
|
||||
try
|
||||
{
|
||||
while (!context.BuildComplete && ++i < chain.Length)
|
||||
{
|
||||
chain[i].PreBuildUp(ref context);
|
||||
}
|
||||
|
||||
while (--i >= 0)
|
||||
{
|
||||
chain[i].PostBuildUp(ref context);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
context.RequiresRecovery?.Recover();
|
||||
throw;
|
||||
}
|
||||
|
||||
return context.Existing;
|
||||
|
||||
object GetPerResolveValue(IntPtr parent, Type registrationType, string name)
|
||||
{
|
||||
if (IntPtr.Zero == parent) return null;
|
||||
|
||||
unsafe
|
||||
{
|
||||
var c = Unsafe.AsRef<BuilderContext>(parent.ToPointer());
|
||||
if (registrationType != c.RegistrationType || name != c.Name)
|
||||
return GetPerResolveValue(c.Parent, registrationType, name);
|
||||
|
||||
var lifetimeManager = (LifetimeManager) c.Get(typeof(LifetimeManager));
|
||||
var result = lifetimeManager?.GetValue();
|
||||
if (null != result) return result;
|
||||
|
||||
throw new InvalidOperationException($"Circular reference for type: {c.Type}");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
internal static object ExecuteValidatingPlan(BuilderStrategy[] chain, ref BuilderContext context)
|
||||
{
|
||||
var i = -1;
|
||||
|
||||
var value = GetPerResolveValue(context.Parent, context.RegistrationType, context.Name);
|
||||
if (null != value) return value;
|
||||
|
||||
try
|
||||
{
|
||||
while (!context.BuildComplete && ++i < chain.Length)
|
||||
{
|
||||
chain[i].PreBuildUp(ref context);
|
||||
}
|
||||
|
||||
while (--i >= 0)
|
||||
{
|
||||
chain[i].PostBuildUp(ref context);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
context.RequiresRecovery?.Recover();
|
||||
throw;
|
||||
}
|
||||
|
||||
return context.Existing;
|
||||
|
||||
object GetPerResolveValue(IntPtr parent, Type registrationType, string name)
|
||||
{
|
||||
if (IntPtr.Zero == parent) return null;
|
||||
|
||||
unsafe
|
||||
{
|
||||
var c = Unsafe.AsRef<BuilderContext>(parent.ToPointer());
|
||||
if (registrationType != c.RegistrationType || name != c.Name)
|
||||
return GetPerResolveValue(c.Parent, registrationType, name);
|
||||
|
||||
var lifetimeManager = (LifetimeManager)c.Get(typeof(LifetimeManager));
|
||||
var result = lifetimeManager?.GetValue();
|
||||
if (null != result) return result;
|
||||
|
||||
throw new InvalidOperationException($"Circular reference for type: {c.Type}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,27 +33,6 @@ namespace Unity.Utility
|
|||
.Concat(GetMethodsHierarchical(type.GetTypeInfo().BaseType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the declared properties of a type or its base types.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to inspect</param>
|
||||
/// <returns>An enumerable of the <see cref="PropertyInfo"/> objects.</returns>
|
||||
public static IEnumerable<PropertyInfo> GetPropertiesHierarchical(this Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
return Enumerable.Empty<PropertyInfo>();
|
||||
}
|
||||
|
||||
if (type == typeof(object))
|
||||
{
|
||||
return type.GetTypeInfo().DeclaredProperties;
|
||||
}
|
||||
|
||||
return type.GetTypeInfo().DeclaredProperties
|
||||
.Concat(GetPropertiesHierarchical(type.GetTypeInfo().BaseType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the types in a parameter set ordinally matches the set of supplied types.
|
||||
/// </summary>
|
||||
|
|
|
@ -20,27 +20,32 @@ namespace Runner.Tests
|
|||
_container.AddExtension(new Diagnostic())
|
||||
.Configure<Diagnostic>()
|
||||
.ForceCompile();
|
||||
|
||||
_container.RegisterType<Poco>();
|
||||
_container.RegisterType<IFoo, Foo>();
|
||||
_container.RegisterType<IFoo, Foo>("1");
|
||||
_container.RegisterType<IFoo>("2", Invoke.Factory(c => new Foo()));
|
||||
}
|
||||
|
||||
[Benchmark(Description = "Resolve<IUnityContainer> ")]
|
||||
public object IUnityContainer() => _container.Resolve(typeof(IUnityContainer), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<object> (unregistered)")]
|
||||
[Benchmark(Description = "Compiled<object> (unregistered)")]
|
||||
public object Unregistered() => _container.Resolve(typeof(object), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<Poco> (registered)")]
|
||||
[Benchmark(Description = "Compiled<Poco> (registered)")]
|
||||
public object Transient() => _container.Resolve(typeof(Poco), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<IService> (registered)")]
|
||||
[Benchmark(Description = "Compiled<IService> (registered)")]
|
||||
public object Mapping() => _container.Resolve(typeof(IFoo), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<IService> (factory)")]
|
||||
[Benchmark(Description = "Compiled<IService> (factory)")]
|
||||
public object Factory() => _container.Resolve(typeof(IFoo), "2");
|
||||
|
||||
[Benchmark(Description = "Resolve<IService[]> (registered)")]
|
||||
[Benchmark(Description = "Compiled<IService[]> (registered)")]
|
||||
public object Array() => _container.Resolve(typeof(IFoo[]), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<IEnumerable<IService>> (registered)")]
|
||||
[Benchmark(Description = "Compiled<IEnumerable<IService>> (registered)")]
|
||||
public object Enumerable() => _container.Resolve(typeof(IEnumerable<IFoo>), null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using BenchmarkDotNet.Attributes;
|
||||
using Runner.Setup;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Unity;
|
||||
using Unity.Extension;
|
||||
|
||||
|
@ -8,7 +9,7 @@ namespace Runner.Tests
|
|||
{
|
||||
[BenchmarkCategory("Basic")]
|
||||
[Config(typeof(BenchmarkConfiguration))]
|
||||
public class Optimized
|
||||
public class PreCompiled
|
||||
{
|
||||
IUnityContainer _container;
|
||||
object _syncRoot = new object();
|
||||
|
@ -39,22 +40,22 @@ namespace Runner.Tests
|
|||
[Benchmark(Description = "Resolve<IUnityContainer> ")]
|
||||
public object IUnityContainer() => _container.Resolve(typeof(IUnityContainer), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<object> (optimized)")]
|
||||
[Benchmark(Description = "PreCompiled<object> (pre-built)")]
|
||||
public object Unregistered() => _container.Resolve(typeof(object), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<Poco> (optimized)")]
|
||||
[Benchmark(Description = "PreCompiled<Poco> (pre-built)")]
|
||||
public object Transient() => _container.Resolve(typeof(Poco), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<IService> (optimized)")]
|
||||
[Benchmark(Description = "PreCompiled<IService> (pre-built)")]
|
||||
public object Mapping() => _container.Resolve(typeof(IFoo), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<IService> (factory)")]
|
||||
[Benchmark(Description = "PreCompiled<IService> (factory)")]
|
||||
public object Factory() => _container.Resolve(typeof(IFoo), "2");
|
||||
|
||||
[Benchmark(Description = "Resolve<IService[]> (optimized)")]
|
||||
[Benchmark(Description = "PreCompiled<IService[]> (pre-built)")]
|
||||
public object Array() => _container.Resolve(typeof(IFoo[]), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<IEnumerable<IService>> (optimized)")]
|
||||
[Benchmark(Description = "PreCompiled<IEnumerable<IService>> (pre-built)")]
|
||||
public object Enumerable() => _container.Resolve(typeof(IEnumerable<IFoo>), null);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
using BenchmarkDotNet.Attributes;
|
||||
using Runner.Setup;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Unity;
|
||||
using Unity.Extension;
|
||||
|
||||
|
@ -9,7 +8,7 @@ namespace Runner.Tests
|
|||
{
|
||||
[BenchmarkCategory("Basic")]
|
||||
[Config(typeof(BenchmarkConfiguration))]
|
||||
public class PreBuilt
|
||||
public class PreResolved
|
||||
{
|
||||
IUnityContainer _container;
|
||||
object _syncRoot = new object();
|
||||
|
@ -40,22 +39,22 @@ namespace Runner.Tests
|
|||
[Benchmark(Description = "Resolve<IUnityContainer> ")]
|
||||
public object IUnityContainer() => _container.Resolve(typeof(IUnityContainer), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<object> (pre-built)")]
|
||||
[Benchmark(Description = "PreResolved<object> (optimized)")]
|
||||
public object Unregistered() => _container.Resolve(typeof(object), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<Poco> (pre-built)")]
|
||||
[Benchmark(Description = "PreResolved<Poco> (optimized)")]
|
||||
public object Transient() => _container.Resolve(typeof(Poco), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<IService> (pre-built)")]
|
||||
[Benchmark(Description = "PreResolved<IService> (optimized)")]
|
||||
public object Mapping() => _container.Resolve(typeof(IFoo), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<IService> (factory)")]
|
||||
[Benchmark(Description = "PreResolved<IService> (factory)")]
|
||||
public object Factory() => _container.Resolve(typeof(IFoo), "2");
|
||||
|
||||
[Benchmark(Description = "Resolve<IService[]> (pre-built)")]
|
||||
[Benchmark(Description = "PreResolved<IService[]> (optimized)")]
|
||||
public object Array() => _container.Resolve(typeof(IFoo[]), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<IEnumerable<IService>> (pre-built)")]
|
||||
[Benchmark(Description = "PreResolved<IEnumerable<IService>> (optimized)")]
|
||||
public object Enumerable() => _container.Resolve(typeof(IEnumerable<IFoo>), null);
|
||||
}
|
||||
}
|
|
@ -20,27 +20,32 @@ namespace Runner.Tests
|
|||
_container.AddExtension(new Diagnostic())
|
||||
.Configure<Diagnostic>()
|
||||
.DisableCompile();
|
||||
|
||||
_container.RegisterType<Poco>();
|
||||
_container.RegisterType<IFoo, Foo>();
|
||||
_container.RegisterType<IFoo, Foo>("1");
|
||||
_container.RegisterType<IFoo>("2", Invoke.Factory(c => new Foo()));
|
||||
}
|
||||
|
||||
[Benchmark(Description = "Resolve<IUnityContainer> ")]
|
||||
public object IUnityContainer() => _container.Resolve(typeof(IUnityContainer), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<object> (unregistered)")]
|
||||
[Benchmark(Description = "Resolved<object> (unregistered)")]
|
||||
public object Unregistered() => _container.Resolve(typeof(object), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<Poco> (registered)")]
|
||||
[Benchmark(Description = "Resolved<Poco> (registered)")]
|
||||
public object Transient() => _container.Resolve(typeof(Poco), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<IService> (registered)")]
|
||||
[Benchmark(Description = "Resolved<IService> (registered)")]
|
||||
public object Mapping() => _container.Resolve(typeof(IFoo), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<IService> (factory)")]
|
||||
[Benchmark(Description = "Resolved<IService> (factory)")]
|
||||
public object Factory() => _container.Resolve(typeof(IFoo), "2");
|
||||
|
||||
[Benchmark(Description = "Resolve<IService[]> (registered)")]
|
||||
[Benchmark(Description = "Resolved<IService[]> (registered)")]
|
||||
public object Array() => _container.Resolve(typeof(IFoo[]), null);
|
||||
|
||||
[Benchmark(Description = "Resolve<IEnumerable<IService>> (registered)")]
|
||||
[Benchmark(Description = "Resolved<IEnumerable<IService>> (registered)")]
|
||||
public object Enumerable() => _container.Resolve(typeof(IEnumerable<IFoo>), null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Injection.Constructor;
|
||||
using Unity.Specification.Constructor.Attribute;
|
||||
|
||||
namespace Injection
|
||||
namespace Constructor
|
||||
{
|
||||
[TestClass]
|
||||
public class Constructor : SpecificationTests
|
||||
public class Attribute : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
|
@ -0,0 +1,15 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Constructor.Injection;
|
||||
|
||||
namespace Constructor
|
||||
{
|
||||
[TestClass]
|
||||
public class Injection : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
||||
return new UnityContainer();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Container;
|
||||
using Unity.Specification.Container.Hierarchy;
|
||||
|
||||
namespace Specification.Tests
|
||||
namespace Container
|
||||
{
|
||||
[TestClass]
|
||||
public class Container : SpecificationTests
|
||||
public class Hierarchy : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
|
@ -1,8 +1,8 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Registrations.IsRegistered;
|
||||
using Unity.Specification.Container.IsRegistered;
|
||||
|
||||
namespace Registrations
|
||||
namespace Container
|
||||
{
|
||||
[TestClass]
|
||||
public class IsRegistered : SpecificationTests
|
|
@ -0,0 +1,15 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Container.Registrations;
|
||||
|
||||
namespace Container
|
||||
{
|
||||
[TestClass]
|
||||
public class Registrations : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
||||
return new UnityContainer();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Factory.Registration;
|
||||
|
||||
namespace Factory
|
||||
{
|
||||
[TestClass]
|
||||
public class Registration : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
||||
return new UnityContainer();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Injection.Factory;
|
||||
using Unity.Specification.Factory.Resolution;
|
||||
|
||||
namespace Injection
|
||||
namespace Factory
|
||||
{
|
||||
[TestClass]
|
||||
public class Factory : SpecificationTests
|
||||
public class Resolution : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
|
@ -1,11 +1,11 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Select.Property;
|
||||
using Unity.Specification.Field.Attribute;
|
||||
|
||||
namespace Select
|
||||
namespace Field
|
||||
{
|
||||
[TestClass]
|
||||
public class Property : SpecificationTests
|
||||
public class Attribute : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
|
@ -1,11 +1,11 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Select.Method;
|
||||
using Unity.Specification.Field.Injection;
|
||||
|
||||
namespace Select
|
||||
namespace Field
|
||||
{
|
||||
[TestClass]
|
||||
public class Method : SpecificationTests
|
||||
public class Injection : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
|
@ -1,11 +1,11 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Resolution.Field;
|
||||
using Unity.Specification.Issues.Codeplex;
|
||||
|
||||
namespace Resolution
|
||||
namespace Issues
|
||||
{
|
||||
[TestClass]
|
||||
public class Field : SpecificationTests
|
||||
public class CodePlex : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Issues;
|
||||
using Unity.Specification.Issues.GitHub;
|
||||
|
||||
namespace Issues
|
||||
{
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Injection.Methods;
|
||||
using Unity.Specification.Method.Attribute;
|
||||
|
||||
namespace Injection
|
||||
namespace Method
|
||||
{
|
||||
[TestClass]
|
||||
public class Methods : SpecificationTests
|
||||
public class Attribute : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
|
@ -0,0 +1,15 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Method.Injection;
|
||||
|
||||
namespace Method
|
||||
{
|
||||
[TestClass]
|
||||
public class Injection : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
||||
return new UnityContainer();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Method.Selection;
|
||||
|
||||
namespace Method
|
||||
{
|
||||
[TestClass]
|
||||
public class Selection : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
||||
return new UnityContainer();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Injection.Parameter;
|
||||
using Unity.Specification.Parameter.Attribute;
|
||||
|
||||
namespace Injection
|
||||
namespace Parameter
|
||||
{
|
||||
[TestClass]
|
||||
public class Parameter : SpecificationTests
|
||||
public class Attribute : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
|
@ -1,11 +1,11 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Injection.Property;
|
||||
using Unity.Specification.Property.Attribute;
|
||||
|
||||
namespace Injection
|
||||
namespace Property
|
||||
{
|
||||
[TestClass]
|
||||
public class Property : SpecificationTests
|
||||
public class Attribute : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
|
@ -0,0 +1,15 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Property.Injection;
|
||||
|
||||
namespace Property
|
||||
{
|
||||
[TestClass]
|
||||
public class Injection : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
||||
return new UnityContainer();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Property.Overrides;
|
||||
|
||||
namespace Property
|
||||
{
|
||||
[TestClass]
|
||||
public class Override : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
||||
return new UnityContainer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Registrations.Collection;
|
||||
|
||||
namespace Registrations
|
||||
{
|
||||
[TestClass]
|
||||
public class Collection : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
||||
return new UnityContainer();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Resolution.Parameters;
|
||||
|
||||
namespace Resolution
|
||||
{
|
||||
[TestClass]
|
||||
public class Parameters : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
||||
return new UnityContainer();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Unity;
|
||||
using Unity.Specification.Select.Constructor;
|
||||
|
||||
namespace Select
|
||||
{
|
||||
[TestClass]
|
||||
public class Constructor : SpecificationTests
|
||||
{
|
||||
public override IUnityContainer GetContainer()
|
||||
{
|
||||
return new UnityContainer();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,21 @@ namespace Unity.Tests.v5
|
|||
[TestClass]
|
||||
public class DiagnosticExtension
|
||||
{
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ResolutionFailedException))]
|
||||
// https://github.com/unitycontainer/container/issues/122
|
||||
public void Container_122()
|
||||
{
|
||||
var container = new UnityContainer();
|
||||
container.AddNewExtension<Diagnostic>();
|
||||
|
||||
container.RegisterType<I1, C1>();
|
||||
container.RegisterType<I2, C2>();
|
||||
|
||||
//next line returns StackOverflowException
|
||||
container.Resolve<I2>();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Register()
|
||||
{
|
||||
|
@ -61,5 +76,17 @@ namespace Unity.Tests.v5
|
|||
// Validate
|
||||
Assert.IsNotNull(container.Resolve<object>());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#region Test Data
|
||||
|
||||
public interface I1 { }
|
||||
public interface I2 { }
|
||||
|
||||
public class C1 : I1 { public C1(I2 i2) { } }
|
||||
|
||||
public class C2 : I2 { public C2(I1 i1) { } }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче