diff --git a/package.props b/package.props index cf3b888e1..d2fa5eeba 100644 --- a/package.props +++ b/package.props @@ -1,12 +1,12 @@ - 5.11.4 + 5.11.7 This package is compatible with .NET Standard 1.0 and 2.0, .NET Core 1.0 and 2.0, .NET 4.0, 4.5, 4.6, 4.7 - 5.11.2 + 5.11.* netstandard2.0;netstandard1.0;netcoreapp2.0;netcoreapp1.0;net47;net46;net45;net40 diff --git a/src/Extensions/Diagnostic.cs b/src/Extensions/Diagnostic.cs index ff0d0f824..38f2fa231 100644 --- a/src/Extensions/Diagnostic.cs +++ b/src/Extensions/Diagnostic.cs @@ -1,6 +1,10 @@ using System; +using System.Collections.Generic; using System.Diagnostics; +using System.Reflection; using Unity.Extension; +using Unity.Factories; +using Unity.Policy; namespace Unity { @@ -44,6 +48,12 @@ protected override void Initialize() { ((UnityContainer)Container).SetDefaultPolicies = UnityContainer.SetDiagnosticPolicies; ((UnityContainer)Container).SetDefaultPolicies((UnityContainer)Container); + + EnumerableResolver.EnumerableMethod = typeof(EnumerableResolver).GetTypeInfo() + .GetDeclaredMethod(nameof(EnumerableResolver.DiagnosticResolver)); + + EnumerableResolver.EnumerableFactory = typeof(EnumerableResolver).GetTypeInfo() + .GetDeclaredMethod(nameof(EnumerableResolver.DiagnosticResolverFactory)); } } diff --git a/src/Factories/EnumerableResolver.cs b/src/Factories/EnumerableResolver.cs index d56286f9f..8dc1a9ea6 100644 --- a/src/Factories/EnumerableResolver.cs +++ b/src/Factories/EnumerableResolver.cs @@ -11,11 +11,11 @@ public class EnumerableResolver { #region Fields - private static readonly MethodInfo EnumerableMethod = + internal static MethodInfo EnumerableMethod = typeof(EnumerableResolver).GetTypeInfo() .GetDeclaredMethod(nameof(EnumerableResolver.Resolver)); - private static readonly MethodInfo EnumerableFactory = + internal static MethodInfo EnumerableFactory = typeof(EnumerableResolver).GetTypeInfo() .GetDeclaredMethod(nameof(EnumerableResolver.ResolverFactory)); @@ -64,6 +64,19 @@ private static ResolveDelegate ResolverFactory() return (ref BuilderContext c) => ((UnityContainer)c.Container).ResolveEnumerable(c.Resolve, type, c.Name); } + + internal static object DiagnosticResolver(ref BuilderContext context) + { + return ((UnityContainer)context.Container).ResolveEnumerable(context.Resolve, + context.Name).ToArray(); + } + + internal static ResolveDelegate DiagnosticResolverFactory() + { + Type type = typeof(TElement).GetGenericTypeDefinition(); + return (ref BuilderContext c) => ((UnityContainer)c.Container).ResolveEnumerable(c.Resolve, type, c.Name).ToArray(); + } + #endregion diff --git a/src/Processors/Constructor/ConstructorResolution.cs b/src/Processors/Constructor/ConstructorResolution.cs index 81b07d5c1..bd82d1dce 100644 --- a/src/Processors/Constructor/ConstructorResolution.cs +++ b/src/Processors/Constructor/ConstructorResolution.cs @@ -75,7 +75,7 @@ protected override ResolveDelegate GetResolverDelegate(Construct var dependencies = new object[parameterResolvers.Length]; for (var i = 0; i < dependencies.Length; i++) dependencies[i] = parameterResolvers[i](ref c); - + c.Existing = info.Invoke(dependencies); } diff --git a/src/Strategies/LifetimeStrategy.cs b/src/Strategies/LifetimeStrategy.cs index 4fb71767a..5be80d2d6 100644 --- a/src/Strategies/LifetimeStrategy.cs +++ b/src/Strategies/LifetimeStrategy.cs @@ -55,7 +55,10 @@ public override void PreBuildUp(ref BuilderContext context) if (policy is IDisposable) { - context.Lifetime.Add(policy); + var scope = policy is ContainerControlledLifetimeManager container + ? ((UnityContainer)container.Scope)?.LifetimeContainer ?? context.Lifetime + : context.Lifetime; + scope.Add(policy); } } } diff --git a/src/UnityContainer.Diagnostic.cs b/src/UnityContainer.Diagnostic.cs index bd14e0828..e776da4b6 100644 --- a/src/UnityContainer.Diagnostic.cs +++ b/src/UnityContainer.Diagnostic.cs @@ -25,7 +25,7 @@ public partial class UnityContainer private static Func CreateMessage = (Exception ex) => { - return $"Resolution failed with error: {ex.Message}\n\nFor more detailed information run Unity in debug mode: new UnityContainer(ModeFlags.Diagnostic)"; + return $"Resolution failed with error: {ex.Message}\n\nFor more detailed information run Unity in debug mode: new UnityContainer().AddExtension(new Diagnostic())"; }; private static string CreateDiagnosticMessage(Exception ex) diff --git a/src/UnityContainer.IUnityContainer.cs b/src/UnityContainer.IUnityContainer.cs index adc7aa5cb..e41486348 100644 --- a/src/UnityContainer.IUnityContainer.cs +++ b/src/UnityContainer.IUnityContainer.cs @@ -233,8 +233,6 @@ bool IUnityContainer.IsRegistered(Type type, string name) => ReferenceEquals(All /// object IUnityContainer.Resolve(Type type, string name, params ResolverOverride[] overrides) { - var n = type.FullName; - // Verify arguments if (null == type) throw new ArgumentNullException(nameof(type)); diff --git a/src/UnityContainer.Implementation.cs b/src/UnityContainer.Implementation.cs index 92e7b24e8..edfde6094 100644 --- a/src/UnityContainer.Implementation.cs +++ b/src/UnityContainer.Implementation.cs @@ -112,7 +112,7 @@ private UnityContainer(UnityContainer parent) _isExplicitlyRegistered = _parent._isExplicitlyRegistered; IsTypeExplicitlyRegistered = _parent.IsTypeExplicitlyRegistered; - GetRegistration = _parent.GetRegistration; + GetRegistration = (t, n) => _parent.GetRegistration(t, n); Register = CreateAndSetOrUpdate; GetPolicy = parent.GetPolicy; SetPolicy = CreateAndSetPolicy; diff --git a/src/UnityContainer.Resolution.cs b/src/UnityContainer.Resolution.cs index 5558c5bbe..79af1be76 100644 --- a/src/UnityContainer.Resolution.cs +++ b/src/UnityContainer.Resolution.cs @@ -85,7 +85,6 @@ private IPolicySet CreateRegistration(Type type, Type policyInterface, object po #endregion - #region Resolving Enumerable internal IEnumerable ResolveEnumerable(Func resolve, string name) @@ -217,6 +216,7 @@ private static IList ResolveRegistrations(ref BuilderContext else list.Add((TElement)context.Resolve(type, entry.Name, entry.Registration)); } + catch (MakeGenericTypeFailedException) { /* Ignore */ } catch (ArgumentException ex) when (ex.InnerException is TypeLoadException) { // Ignore @@ -287,8 +287,11 @@ private static ResolveDelegate OptimizingFactory(ref BuilderCont // Check if optimization is required if (0 == Interlocked.Decrement(ref counter)) { +#if NET40 Task.Factory.StartNew(() => { - +#else + Task.Run(() => { +#endif // Compile build plan on worker thread var expressions = new List(); foreach (var processor in chain) @@ -374,7 +377,8 @@ internal ResolveDelegate ResolvingFactory(ref BuilderContext con !(ex is InvalidRegistrationException) && !(ex is ObjectDisposedException) && !(ex is MemberAccessException) && - !(ex is MakeGenericTypeFailedException)) + !(ex is MakeGenericTypeFailedException) && + !(ex is TargetInvocationException)) throw; throw new ResolutionFailedException(context.RegistrationType, context.Name, CreateMessage(ex), ex); diff --git a/tests/Unity.Diagnostic/Issues.cs b/tests/Unity.Diagnostic/Issues.cs index d00b999d6..4f25c8d1f 100644 --- a/tests/Unity.Diagnostic/Issues.cs +++ b/tests/Unity.Diagnostic/Issues.cs @@ -1,103 +1,23 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; using Unity; -using Unity.Builder; -using Unity.Extension; -using Unity.Specification.Diagnostic.Issues.GitHub; -using Unity.Strategies; -namespace GitHub +namespace Issues { [TestClass] - public class Container : Unity.Specification.Diagnostic.Issues.GitHub.SpecificationTests + public class GitHub : Unity.Specification.Diagnostic.Issues.GitHub.SpecificationTests { public override IUnityContainer GetContainer() { - return new UnityContainer().AddExtension(new ForceCompillation()) - .AddExtension(new Diagnostic()) - .AddExtension(new SpyExtension(new SpyStrategy(), UnityBuildStage.Initialization)); + return new UnityContainer().AddNewExtension(); } } - internal class SpyExtension : UnityContainerExtension - { - private BuilderStrategy strategy; - private UnityBuildStage stage; - private object policy; - private Type policyType; - - public SpyExtension(BuilderStrategy strategy, UnityBuildStage stage) - { - this.strategy = strategy; - this.stage = stage; - } - - public SpyExtension(BuilderStrategy strategy, UnityBuildStage stage, object policy, Type policyType) - { - this.strategy = strategy; - this.stage = stage; - this.policy = policy; - this.policyType = policyType; - } - - protected override void Initialize() - { - Context.Strategies.Add(this.strategy, this.stage); - - if (this.policy != null) - { - Context.Policies.Set(null, null, this.policyType, this.policy); - } - } - } - - internal class SpyStrategy : BuilderStrategy - { - private object existing = null; - private bool buildUpWasCalled = false; - - public override void PreBuildUp(ref BuilderContext context) - { - this.buildUpWasCalled = true; - this.existing = context.Existing; - - this.UpdateSpyPolicy(ref context); - } - - public override void PostBuildUp(ref BuilderContext context) - { - this.existing = context.Existing; - } - - public object Existing - { - get { return this.existing; } - } - - public bool BuildUpWasCalled - { - get { return this.buildUpWasCalled; } - } - - private void UpdateSpyPolicy(ref BuilderContext context) - { - SpyPolicy policy = (SpyPolicy)context.Get(null, null, typeof(SpyPolicy)); - - if (policy != null) - { - policy.WasSpiedOn = true; - } - } - } - - internal class SpyPolicy + [TestClass] + public class CodePlex : Unity.Specification.Issues.Codeplex.SpecificationTests { - private bool wasSpiedOn; - - public bool WasSpiedOn + public override IUnityContainer GetContainer() { - get { return wasSpiedOn; } - set { wasSpiedOn = value; } + return new UnityContainer().AddNewExtension(); } } } diff --git a/tests/Unity.Specification/Issues.cs b/tests/Unity.Specification/Issues.cs new file mode 100644 index 000000000..31aa7dd99 --- /dev/null +++ b/tests/Unity.Specification/Issues.cs @@ -0,0 +1,23 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Unity; + +namespace Issues +{ + [TestClass] + public class GitHub : Unity.Specification.Issues.GitHub.SpecificationTests + { + public override IUnityContainer GetContainer() + { + return new UnityContainer(); + } + } + + [TestClass] + public class CodePlex : Unity.Specification.Issues.Codeplex.SpecificationTests + { + public override IUnityContainer GetContainer() + { + return new UnityContainer(); + } + } +} diff --git a/tests/Unity.Specification/Issues/CodePlex.cs b/tests/Unity.Specification/Issues/CodePlex.cs deleted file mode 100644 index e22d1c725..000000000 --- a/tests/Unity.Specification/Issues/CodePlex.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Unity; -using Unity.Specification.Issues.Codeplex; - -namespace Issues -{ - [TestClass] - public class CodePlex : SpecificationTests - { - public override IUnityContainer GetContainer() - { - return new UnityContainer(); - } - } -} diff --git a/tests/Unity.Specification/Issues/GitHub.cs b/tests/Unity.Specification/Issues/GitHub.cs deleted file mode 100644 index d820adaab..000000000 --- a/tests/Unity.Specification/Issues/GitHub.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Unity; -using Unity.Specification.Issues.GitHub; - -namespace Issues -{ - [TestClass] - public class GitHub : SpecificationTests - { - public override IUnityContainer GetContainer() - { - return new UnityContainer(); - } - } -}