From 93539e4702b899de0933399df4e73e043335dd7e Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 1 Jul 2016 19:39:59 +0200 Subject: [PATCH] Bugfix - resolvers and ioc --- .../ContainerManyObjectsResolver.cs | 32 ++++---- .../ContainerSingleObjectResolver.cs | 5 +- .../ManyObjectsResolverBase.cs | 76 ++++++++----------- .../PropertyValueConvertersResolver.cs | 38 +++++----- 4 files changed, 66 insertions(+), 85 deletions(-) diff --git a/src/Umbraco.Core/ObjectResolution/ContainerManyObjectsResolver.cs b/src/Umbraco.Core/ObjectResolution/ContainerManyObjectsResolver.cs index 85bb754c2d..2454a8f2c9 100644 --- a/src/Umbraco.Core/ObjectResolution/ContainerManyObjectsResolver.cs +++ b/src/Umbraco.Core/ObjectResolution/ContainerManyObjectsResolver.cs @@ -40,7 +40,7 @@ namespace Umbraco.Core.ObjectResolution internal ContainerManyObjectsResolver(IServiceProvider serviceProvider, ILogger logger, IEnumerable value, ObjectLifetimeScope scope = ObjectLifetimeScope.Application) : base(serviceProvider, logger, value, scope) { - } + } #endregion /// @@ -57,7 +57,7 @@ namespace Umbraco.Core.ObjectResolution _container = container; Resolution.Frozen += Resolution_Frozen; } - + /// /// When resolution is frozen add all the types to the container /// @@ -69,7 +69,7 @@ namespace Umbraco.Core.ObjectResolution var i = 0; foreach (var type in InstanceTypes) { - var name = prefix + i++; + var name = $"{prefix}{i++:00000}"; _container.Register(typeof(TResolved), type, name, GetLifetime(LifetimeScope)); } } @@ -97,27 +97,25 @@ namespace Umbraco.Core.ObjectResolution /// Creates the instances from IoC /// /// A list of objects of type . - protected override IEnumerable CreateValues(ObjectLifetimeScope scope) + protected override IEnumerable CreateInstances() { //NOTE: we ignore scope because objects are registered under this scope and not build based on the scope. var prefix = GetType().FullName + "_"; - var services = _container.AvailableServices - .Where(x => x.ServiceName.StartsWith(prefix)) - .OrderBy(x => x.ServiceName); - var allInstances = _container.GetAllInstances() - .ToDictionary(x => x.GetType(), x => x); - - //foreach (var service in services) - // LogHelper.Debug("SERVICE " + service.ImplementingType.FullName + " " + service.ServiceName); - //foreach (var instance in allInstances) - // LogHelper.Debug("INSTANCE " + instance.Key.FullName); // GetAllInstances could return more than what *this* resolver has registered, // and there is no guarantee instances will be in the right order - have to do // it differently - //return _container.GetAllInstances(); - return services.Select(x => allInstances[x.ImplementingType]); - } + + var services = _container.AvailableServices + .Where(x => x.ServiceName.StartsWith(prefix)) + .OrderBy(x => x.ServiceName); + + var values = services + .Select(x => _container.GetInstance(x.ServiceName)) + .ToArray(); + + return values; + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/ObjectResolution/ContainerSingleObjectResolver.cs b/src/Umbraco.Core/ObjectResolution/ContainerSingleObjectResolver.cs index 78a0a58304..5f054c138a 100644 --- a/src/Umbraco.Core/ObjectResolution/ContainerSingleObjectResolver.cs +++ b/src/Umbraco.Core/ObjectResolution/ContainerSingleObjectResolver.cs @@ -100,8 +100,9 @@ namespace Umbraco.Core.ObjectResolution if (avail) { + // must override with the proper name! _container.Override( - sr => sr.ServiceType == typeof (TResolved), + sr => sr.ServiceType == typeof (TResolved) && sr.ServiceName == GetType().FullName, (factory, registration) => { registration.Value = value; @@ -116,7 +117,7 @@ namespace Umbraco.Core.ObjectResolution { ServiceType = typeof (TResolved), ImplementingType = value.GetType(), - ServiceName = "", + ServiceName = GetType().FullName, Lifetime = new PerContainerLifetime(), Value = value }); diff --git a/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs b/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs index 03c0146d9b..ca9243bc8a 100644 --- a/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs +++ b/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs @@ -1,7 +1,5 @@ using System; -using System.CodeDom; using System.Collections.Generic; -using System.ComponentModel; using System.Linq; using System.Threading; using System.Web; @@ -22,11 +20,9 @@ namespace Umbraco.Core.ObjectResolution private Lazy> _applicationInstances; private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); private readonly string _httpContextKey; - private readonly List _instanceTypes = new List(); + private readonly List _instanceTypes; private IEnumerable _sortedValues; - private int _defaultPluginWeight = 10; - #region Constructors /// @@ -38,12 +34,15 @@ namespace Umbraco.Core.ObjectResolution /// internal ManyObjectsResolverBase(ILogger logger, IEnumerable types, ObjectLifetimeScope scope = ObjectLifetimeScope.Application) { - if (logger == null) throw new ArgumentNullException("logger"); - if (types == null) throw new ArgumentNullException("types"); + if (logger == null) throw new ArgumentNullException(nameof(logger)); + if (types == null) throw new ArgumentNullException(nameof(types)); CanResolveBeforeFrozen = false; _instanceTypes = types.ToList(); LifetimeScope = scope; Logger = logger; + + if (scope == ObjectLifetimeScope.Application) + InitializeAppInstances(); } /// @@ -53,13 +52,8 @@ namespace Umbraco.Core.ObjectResolution /// /// internal ManyObjectsResolverBase(ILogger logger, ObjectLifetimeScope scope = ObjectLifetimeScope.Application) - { - if (logger == null) throw new ArgumentNullException("logger"); - CanResolveBeforeFrozen = false; - Logger = logger; - LifetimeScope = scope; - _instanceTypes = new List(); - } + : this(logger, new List(), scope) + { } /// @@ -73,25 +67,28 @@ namespace Umbraco.Core.ObjectResolution /// is per HttpRequest but the current HttpContext is null. protected ManyObjectsResolverBase(IServiceProvider serviceProvider, ILogger logger, ObjectLifetimeScope scope = ObjectLifetimeScope.Application) { - if (serviceProvider == null) throw new ArgumentNullException("serviceProvider"); - if (logger == null) throw new ArgumentNullException("logger"); + if (serviceProvider == null) throw new ArgumentNullException(nameof(serviceProvider)); + if (logger == null) throw new ArgumentNullException(nameof(logger)); + CanResolveBeforeFrozen = false; + if (scope == ObjectLifetimeScope.HttpRequest) { if (HttpContext.Current == null) throw new InvalidOperationException("Use alternative constructor accepting a HttpContextBase object in order to set the lifetime scope to HttpRequest when HttpContext.Current is null"); CurrentHttpContext = new HttpContextWrapper(HttpContext.Current); + _httpContextKey = GetType().FullName; } ServiceProvider = serviceProvider; Logger = logger; LifetimeScope = scope; - if (scope == ObjectLifetimeScope.HttpRequest) - _httpContextKey = GetType().FullName; + _instanceTypes = new List(); - InitializeAppInstances(); + if (scope == ObjectLifetimeScope.Application) + InitializeAppInstances(); } /// @@ -104,8 +101,8 @@ namespace Umbraco.Core.ObjectResolution /// is null. protected ManyObjectsResolverBase(IServiceProvider serviceProvider, ILogger logger, HttpContextBase httpContext) { - if (serviceProvider == null) throw new ArgumentNullException("serviceProvider"); - if (httpContext == null) throw new ArgumentNullException("httpContext"); + if (serviceProvider == null) throw new ArgumentNullException(nameof(serviceProvider)); + if (httpContext == null) throw new ArgumentNullException(nameof(httpContext)); CanResolveBeforeFrozen = false; Logger = logger; LifetimeScope = ObjectLifetimeScope.HttpRequest; @@ -147,28 +144,25 @@ namespace Umbraco.Core.ObjectResolution /// /// Gets the list of types to create instances from. /// - protected virtual IEnumerable InstanceTypes - { - get { return _instanceTypes; } - } + protected virtual IEnumerable InstanceTypes => _instanceTypes; /// /// Gets or sets the used to initialize this object, if any. /// /// If not null, then LifetimeScope will be ObjectLifetimeScope.HttpRequest. - protected HttpContextBase CurrentHttpContext { get; private set; } + protected HttpContextBase CurrentHttpContext { get; } /// /// Returns the service provider used to instantiate objects /// - public IServiceProvider ServiceProvider { get; private set; } + public IServiceProvider ServiceProvider { get; } - public ILogger Logger { get; private set; } + public ILogger Logger { get; } /// /// Gets or sets the lifetime scope of resolved objects. /// - protected ObjectLifetimeScope LifetimeScope { get; private set; } + protected ObjectLifetimeScope LifetimeScope { get; } /// /// Gets the resolved object instances, sorted by weight. @@ -180,12 +174,11 @@ namespace Umbraco.Core.ObjectResolution /// protected IEnumerable GetSortedValues() { - if (_sortedValues == null) - { - var values = Values.ToList(); - values.Sort((f1, f2) => GetObjectWeight(f1).CompareTo(GetObjectWeight(f2))); - _sortedValues = values; - } + if (_sortedValues != null) return _sortedValues; + + var values = Values.ToList(); + values.Sort((f1, f2) => GetObjectWeight(f1).CompareTo(GetObjectWeight(f2))); + _sortedValues = values; return _sortedValues; } @@ -194,11 +187,7 @@ namespace Umbraco.Core.ObjectResolution /// /// Determines the weight of types that do not have a WeightedPluginAttribute set on /// them, when calling GetSortedValues. - protected virtual int DefaultPluginWeight - { - get { return _defaultPluginWeight; } - set { _defaultPluginWeight = value; } - } + protected virtual int DefaultPluginWeight { get; set; } = 10; /// /// Returns the weight of an object for user with GetSortedValues @@ -209,17 +198,14 @@ namespace Umbraco.Core.ObjectResolution { var type = o.GetType(); var attr = type.GetCustomAttribute(true); - return attr == null ? DefaultPluginWeight : attr.Weight; + return attr?.Weight ?? DefaultPluginWeight; } /// /// Gets the resolved object instances. /// /// CanResolveBeforeFrozen is false, and resolution is not frozen. - protected IEnumerable Values - { - get { return CreateValues(LifetimeScope); } - } + protected IEnumerable Values => CreateValues(LifetimeScope); /// /// Creates the values collection based on the scope diff --git a/src/Umbraco.Core/PropertyEditors/PropertyValueConvertersResolver.cs b/src/Umbraco.Core/PropertyEditors/PropertyValueConvertersResolver.cs index fa4501a268..be29da8458 100644 --- a/src/Umbraco.Core/PropertyEditors/PropertyValueConvertersResolver.cs +++ b/src/Umbraco.Core/PropertyEditors/PropertyValueConvertersResolver.cs @@ -40,13 +40,10 @@ namespace Umbraco.Core.PropertyEditors /// /// Gets the converters. /// - public IEnumerable Converters - { - get { return Values; } - } + public IEnumerable Converters => Values; private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); - private Tuple[] _defaults = null; + private Tuple[] _defaults; /// /// Caches and gets the default converters with their metadata @@ -57,24 +54,23 @@ namespace Umbraco.Core.PropertyEditors { using (var locker = new UpgradeableReadLock(_lock)) { - if (_defaults == null) - { - locker.UpgradeToWriteLock(); + if (_defaults != null) return _defaults; - var defaultConvertersWithAttributes = Converters - .Select(x => new - { - attribute = x.GetType().GetCustomAttribute(false), - converter = x - }) - .Where(x => x.attribute != null) - .ToArray(); + locker.UpgradeToWriteLock(); - _defaults = defaultConvertersWithAttributes - .Select( - x => new Tuple(x.converter, x.attribute)) - .ToArray(); - } + var defaultConvertersWithAttributes = Converters + .Select(x => new + { + attribute = x.GetType().GetCustomAttribute(false), + converter = x + }) + .Where(x => x.attribute != null) + .ToArray(); + + _defaults = defaultConvertersWithAttributes + .Select( + x => new Tuple(x.converter, x.attribute)) + .ToArray(); return _defaults; }