Bugfix - resolvers and ioc
This commit is contained in:
@@ -40,7 +40,7 @@ namespace Umbraco.Core.ObjectResolution
|
||||
internal ContainerManyObjectsResolver(IServiceProvider serviceProvider, ILogger logger, IEnumerable<Type> value, ObjectLifetimeScope scope = ObjectLifetimeScope.Application)
|
||||
: base(serviceProvider, logger, value, scope)
|
||||
{
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
@@ -57,7 +57,7 @@ namespace Umbraco.Core.ObjectResolution
|
||||
_container = container;
|
||||
Resolution.Frozen += Resolution_Frozen;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// When resolution is frozen add all the types to the container
|
||||
/// </summary>
|
||||
@@ -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
|
||||
/// </summary>
|
||||
/// <returns>A list of objects of type <typeparamref name="TResolved"/>.</returns>
|
||||
protected override IEnumerable<TResolved> CreateValues(ObjectLifetimeScope scope)
|
||||
protected override IEnumerable<TResolved> 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<TResolved>()
|
||||
.ToDictionary(x => x.GetType(), x => x);
|
||||
|
||||
//foreach (var service in services)
|
||||
// LogHelper.Debug<object>("SERVICE " + service.ImplementingType.FullName + " " + service.ServiceName);
|
||||
//foreach (var instance in allInstances)
|
||||
// LogHelper.Debug<object>("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<TResolved>();
|
||||
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<TResolved>(x.ServiceName))
|
||||
.ToArray();
|
||||
|
||||
return values;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -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<IEnumerable<TResolved>> _applicationInstances;
|
||||
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
|
||||
private readonly string _httpContextKey;
|
||||
private readonly List<Type> _instanceTypes = new List<Type>();
|
||||
private readonly List<Type> _instanceTypes;
|
||||
private IEnumerable<TResolved> _sortedValues;
|
||||
|
||||
private int _defaultPluginWeight = 10;
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
@@ -38,12 +34,15 @@ namespace Umbraco.Core.ObjectResolution
|
||||
/// <param name="scope"></param>
|
||||
internal ManyObjectsResolverBase(ILogger logger, IEnumerable<Type> 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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -53,13 +52,8 @@ namespace Umbraco.Core.ObjectResolution
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="scope"></param>
|
||||
internal ManyObjectsResolverBase(ILogger logger, ObjectLifetimeScope scope = ObjectLifetimeScope.Application)
|
||||
{
|
||||
if (logger == null) throw new ArgumentNullException("logger");
|
||||
CanResolveBeforeFrozen = false;
|
||||
Logger = logger;
|
||||
LifetimeScope = scope;
|
||||
_instanceTypes = new List<Type>();
|
||||
}
|
||||
: this(logger, new List<Type>(), scope)
|
||||
{ }
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -73,25 +67,28 @@ namespace Umbraco.Core.ObjectResolution
|
||||
/// <exception cref="InvalidOperationException"><paramref name="scope"/> is per HttpRequest but the current HttpContext is null.</exception>
|
||||
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<Type>();
|
||||
|
||||
InitializeAppInstances();
|
||||
if (scope == ObjectLifetimeScope.Application)
|
||||
InitializeAppInstances();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -104,8 +101,8 @@ namespace Umbraco.Core.ObjectResolution
|
||||
/// <exception cref="ArgumentNullException"><paramref name="httpContext"/> is <c>null</c>.</exception>
|
||||
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
|
||||
/// <summary>
|
||||
/// Gets the list of types to create instances from.
|
||||
/// </summary>
|
||||
protected virtual IEnumerable<Type> InstanceTypes
|
||||
{
|
||||
get { return _instanceTypes; }
|
||||
}
|
||||
protected virtual IEnumerable<Type> InstanceTypes => _instanceTypes;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="HttpContextBase"/> used to initialize this object, if any.
|
||||
/// </summary>
|
||||
/// <remarks>If not null, then <c>LifetimeScope</c> will be <c>ObjectLifetimeScope.HttpRequest</c>.</remarks>
|
||||
protected HttpContextBase CurrentHttpContext { get; private set; }
|
||||
protected HttpContextBase CurrentHttpContext { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the service provider used to instantiate objects
|
||||
/// </summary>
|
||||
public IServiceProvider ServiceProvider { get; private set; }
|
||||
public IServiceProvider ServiceProvider { get; }
|
||||
|
||||
public ILogger Logger { get; private set; }
|
||||
public ILogger Logger { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the lifetime scope of resolved objects.
|
||||
/// </summary>
|
||||
protected ObjectLifetimeScope LifetimeScope { get; private set; }
|
||||
protected ObjectLifetimeScope LifetimeScope { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resolved object instances, sorted by weight.
|
||||
@@ -180,12 +174,11 @@ namespace Umbraco.Core.ObjectResolution
|
||||
/// </remarks>
|
||||
protected IEnumerable<TResolved> 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
|
||||
/// </summary>
|
||||
/// <remarks>Determines the weight of types that do not have a <c>WeightedPluginAttribute</c> set on
|
||||
/// them, when calling <c>GetSortedValues</c>.</remarks>
|
||||
protected virtual int DefaultPluginWeight
|
||||
{
|
||||
get { return _defaultPluginWeight; }
|
||||
set { _defaultPluginWeight = value; }
|
||||
}
|
||||
protected virtual int DefaultPluginWeight { get; set; } = 10;
|
||||
|
||||
/// <summary>
|
||||
/// 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<WeightedPluginAttribute>(true);
|
||||
return attr == null ? DefaultPluginWeight : attr.Weight;
|
||||
return attr?.Weight ?? DefaultPluginWeight;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resolved object instances.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException"><c>CanResolveBeforeFrozen</c> is false, and resolution is not frozen.</exception>
|
||||
protected IEnumerable<TResolved> Values
|
||||
{
|
||||
get { return CreateValues(LifetimeScope); }
|
||||
}
|
||||
protected IEnumerable<TResolved> Values => CreateValues(LifetimeScope);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the values collection based on the scope
|
||||
|
||||
@@ -40,13 +40,10 @@ namespace Umbraco.Core.PropertyEditors
|
||||
/// <summary>
|
||||
/// Gets the converters.
|
||||
/// </summary>
|
||||
public IEnumerable<IPropertyValueConverter> Converters
|
||||
{
|
||||
get { return Values; }
|
||||
}
|
||||
public IEnumerable<IPropertyValueConverter> Converters => Values;
|
||||
|
||||
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
|
||||
private Tuple<IPropertyValueConverter, DefaultPropertyValueConverterAttribute>[] _defaults = null;
|
||||
private Tuple<IPropertyValueConverter, DefaultPropertyValueConverterAttribute>[] _defaults;
|
||||
|
||||
/// <summary>
|
||||
/// 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<DefaultPropertyValueConverterAttribute>(false),
|
||||
converter = x
|
||||
})
|
||||
.Where(x => x.attribute != null)
|
||||
.ToArray();
|
||||
locker.UpgradeToWriteLock();
|
||||
|
||||
_defaults = defaultConvertersWithAttributes
|
||||
.Select(
|
||||
x => new Tuple<IPropertyValueConverter, DefaultPropertyValueConverterAttribute>(x.converter, x.attribute))
|
||||
.ToArray();
|
||||
}
|
||||
var defaultConvertersWithAttributes = Converters
|
||||
.Select(x => new
|
||||
{
|
||||
attribute = x.GetType().GetCustomAttribute<DefaultPropertyValueConverterAttribute>(false),
|
||||
converter = x
|
||||
})
|
||||
.Where(x => x.attribute != null)
|
||||
.ToArray();
|
||||
|
||||
_defaults = defaultConvertersWithAttributes
|
||||
.Select(
|
||||
x => new Tuple<IPropertyValueConverter, DefaultPropertyValueConverterAttribute>(x.converter, x.attribute))
|
||||
.ToArray();
|
||||
|
||||
return _defaults;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user