This commit is contained in:
Eugene Sadovoi 2018-12-30 13:00:53 -05:00
Родитель 9facbe1a97
Коммит a5de16804a
39 изменённых файлов: 433 добавлений и 220 удалений

Просмотреть файл

@ -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
}