diff --git a/src/Umbraco.Core/Macros/MacroFieldEditorsResolver.cs b/src/Umbraco.Core/Macros/MacroFieldEditorsResolver.cs
index df7dc4fbf4..eb0366eb93 100644
--- a/src/Umbraco.Core/Macros/MacroFieldEditorsResolver.cs
+++ b/src/Umbraco.Core/Macros/MacroFieldEditorsResolver.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Web;
using System.Web.UI;
using System.Linq;
@@ -24,9 +25,7 @@ namespace Umbraco.Core.Macros
///
internal MacroFieldEditorsResolver(Func> macroEditors)
: base(macroEditors, ObjectLifetimeScope.Transient)
- {
-
- }
+ { }
///
/// Gets the implementations.
diff --git a/src/Umbraco.Core/ObjectResolution/LazyManyObjectsResolverbase.cs b/src/Umbraco.Core/ObjectResolution/LazyManyObjectsResolverbase.cs
index 7731916a7f..eae56a9604 100644
--- a/src/Umbraco.Core/ObjectResolution/LazyManyObjectsResolverbase.cs
+++ b/src/Umbraco.Core/ObjectResolution/LazyManyObjectsResolverbase.cs
@@ -6,18 +6,17 @@ using System.Web;
namespace Umbraco.Core.ObjectResolution
{
- ///
- /// A base class for lazily resolving types for a resolver
- ///
- ///
- ///
- ///
- /// This is a special case resolver for when types get lazily resolved in order to resolve the actual types. This is useful
- /// for when there is some processing overhead (i.e. Type finding in assemblies) to return the Types used to instantiate the instances.
- /// In some these cases we don't want to have to type find during application startup, only when we need to resolve the instances.
- ///
- /// Important notes about this resolver: This does not support Insert or Remove and therefore does not support any ordering unless
- /// the types are marked with the WeightedPluginAttribute.
+ ///
+ /// The base class for all lazy many-objects resolvers.
+ ///
+ /// The type of the concrete resolver class.
+ /// The type of the resolved objects.
+ ///
+ /// This is a special case resolver for when types get lazily resolved in order to resolve the actual types. This is useful
+ /// for when there is some processing overhead (i.e. Type finding in assemblies) to return the Types used to instantiate the instances.
+ /// In some these cases we don't want to have to type-find during application startup, only when we need to resolve the instances.
+ /// Important notes about this resolver: it does not support Insert or Remove and therefore does not support any ordering unless
+ /// the types are marked with the WeightedPluginAttribute.
///
internal abstract class LazyManyObjectsResolverBase : ManyObjectsResolverBase
where TResolved : class
@@ -25,105 +24,125 @@ namespace Umbraco.Core.ObjectResolution
{
#region Constructors
+ ///
+ /// Initializes a new instance of the class with an empty list of objects,
+ /// with creation of objects based on an HttpRequest lifetime scope.
+ ///
+ /// The lifetime scope of instantiated objects, default is per Application.
+ /// If is per HttpRequest then there must be a current HttpContext.
+ /// is per HttpRequest but the current HttpContext is null.
protected LazyManyObjectsResolverBase(ObjectLifetimeScope scope = ObjectLifetimeScope.Application)
: base(scope)
- {
- }
-
+ { }
+
+ ///
+ /// Initializes a new instance of the class with an empty list of objects,
+ /// with creation of objects based on an HttpRequest lifetime scope.
+ ///
+ /// The HttpContextBase corresponding to the HttpRequest.
+ /// is null.
protected LazyManyObjectsResolverBase(HttpContextBase httpContext)
: base(httpContext)
- {
- }
+ { }
- ///
- /// Constructor accepting a list of lazy types
- ///
- ///
- ///
- protected LazyManyObjectsResolverBase(IEnumerable> listOfLazyTypes, ObjectLifetimeScope scope = ObjectLifetimeScope.Application)
+ ///
+ /// Initializes a new instance of the class with an initial list
+ /// If is per HttpRequest then there must be a current HttpContext.
+ /// is per HttpRequest but the current HttpContext is null.
+ protected LazyManyObjectsResolverBase(IEnumerable> lazyTypeList, ObjectLifetimeScope scope = ObjectLifetimeScope.Application)
: this(scope)
{
- AddTypes(listOfLazyTypes);
+ AddTypes(lazyTypeList);
}
- ///
- /// Constructor accepting a delegate to return a list of types
- ///
- ///
- ///
- protected LazyManyObjectsResolverBase(Func> typeListDelegate, ObjectLifetimeScope scope = ObjectLifetimeScope.Application)
+ ///
+ /// Initializes a new instance of the class with an initial list
+ /// of functions producing types, and an optional lifetime scope.
+ ///
+ /// The list of functions producing types.
+ /// The lifetime scope of instantiated objects, default is per Application.
+ /// If is per HttpRequest then there must be a current HttpContext.
+ /// is per HttpRequest but the current HttpContext is null.
+ protected LazyManyObjectsResolverBase(Func> typeListProducerList, ObjectLifetimeScope scope = ObjectLifetimeScope.Application)
: this(scope)
{
- _listOfTypeListDelegates.Add(typeListDelegate);
+ _typeListProducerList.Add(typeListProducerList);
}
- ///
- /// Constructor accepting a list of lazy types
- ///
- ///
- ///
- protected LazyManyObjectsResolverBase(HttpContextBase httpContext, IEnumerable> listOfLazyTypes)
+ ///
+ /// Initializes a new instance of the class with an initial list of
+ /// lazy object types, with creation of objects based on an HttpRequest lifetime scope.
+ ///
+ /// The HttpContextBase corresponding to the HttpRequest.
+ /// The list of lazy object types.
+ /// is null.
+ protected LazyManyObjectsResolverBase(HttpContextBase httpContext, IEnumerable> lazyTypeList)
: this(httpContext)
{
- AddTypes(listOfLazyTypes);
+ AddTypes(lazyTypeList);
}
- ///
- /// Constructor accepting a delegate to return a list of types
- ///
- ///
- ///
- protected LazyManyObjectsResolverBase(HttpContextBase httpContext, Func> typeListDelegate)
+ ///
+ /// Initializes a new instance of the class with an initial list of
+ /// functions producing types, with creation of objects based on an HttpRequest lifetime scope.
+ ///
+ /// The HttpContextBase corresponding to the HttpRequest.
+ /// The list of functions producing types.
+ /// is null.
+ protected LazyManyObjectsResolverBase(HttpContextBase httpContext, Func> typeListProducerList)
: this(httpContext)
{
- _listOfTypeListDelegates.Add(typeListDelegate);
+ _typeListProducerList.Add(typeListProducerList);
}
#endregion
private readonly List> _lazyTypeList = new List>();
- private readonly List>> _listOfTypeListDelegates = new List>>();
+ private readonly List>> _typeListProducerList = new List>>();
+
private List _resolvedTypes = null;
- private readonly ReaderWriterLockSlim _typeResolutionLock = new ReaderWriterLockSlim();
+ private readonly ReaderWriterLockSlim _resolvedTypesLock = new ReaderWriterLockSlim();
///
- /// Used for unit tests
+ /// Gets a value indicating whether the resolver has resolved types to create instances from.
///
+ /// To be used in unit tests.
internal bool HasResolvedTypes
{
- get { return _resolvedTypes != null; }
+ get
+ {
+ using (new ReadLock(_resolvedTypesLock))
+ {
+ return _resolvedTypes != null;
+ }
+ }
}
- ///
- /// Once this is called this will resolve all types registered in the lazy list
- ///
- protected override IEnumerable InstanceTypes
+ ///
+ /// Gets the list of types to create instances from.
+ ///
+ /// When called, will get the types from the lazy list.
+ protected override IEnumerable InstanceTypes
{
get
{
- using (var lck = new UpgradeableReadLock(_typeResolutionLock))
+ using (var lck = new UpgradeableReadLock(_resolvedTypesLock))
{
- var lazyTypeList = _lazyTypeList.Select(x => x.Value).ToArray();
- var listofTypeListDelegates = _listOfTypeListDelegates.SelectMany(x => x()).ToArray();
-
- //we need to validate each resolved type now since we could not do it before when inserting the lazy delegates
- if (!HasResolvedTypes)
+ if (_resolvedTypes == null)
{
- lck.UpgradeToWriteLock();
+ // get the types by evaluating the lazy & producers
+ var types = new List();
+ types.AddRange(_lazyTypeList.Select(x => x.Value));
+ types.AddRange(_typeListProducerList.SelectMany(x => x()));
+
+ lck.UpgradeToWriteLock();
_resolvedTypes = new List();
- //first iterate the lazy type list
- foreach (var l in lazyTypeList)
- {
- UpdateUniqueList(_resolvedTypes, l);
- }
-
- //next iterate the list of list type delegates
- foreach (var l in listofTypeListDelegates)
- {
- UpdateUniqueList(_resolvedTypes, l);
- }
+ // we need to validate each resolved type now since we could
+ // not do it before evaluating the lazy & producers
+ foreach (var type in types)
+ AddValidAndNoDuplicate(_resolvedTypes, type);
}
return _resolvedTypes;
@@ -131,23 +150,28 @@ namespace Umbraco.Core.ObjectResolution
}
}
- private void UpdateUniqueList(List uniqueList, Type toAdd)
+ // ensures that type is valid and not a duplicate
+ // then appends the type to the end of the list
+ private void AddValidAndNoDuplicate(List list, Type type)
{
- EnsureCorrectType(toAdd);
- if (uniqueList.Contains(toAdd))
+ EnsureCorrectType(type);
+ if (list.Contains(type))
{
- throw new InvalidOperationException("The Type " + toAdd + " already exists in the collection");
- }
- uniqueList.Add(toAdd);
+ throw new InvalidOperationException(string.Format(
+ "Type {0} is already in the collection of types.", type.FullName));
+ }
+ list.Add(type);
}
- ///
- /// Allows adding of multiple lazy types at once
+ #region Types collection manipulation
+
+ ///
+ /// Lazily adds types from lazy types.
///
- ///
+ /// The lazy types, to add.
protected void AddTypes(IEnumerable> types)
{
- EnsureAddSupport();
+ EnsureSupportsAdd();
using (Resolution.Configuration)
using (GetWriteLock())
@@ -160,27 +184,27 @@ namespace Umbraco.Core.ObjectResolution
}
///
- /// Adds a type list delegate to the collection
+ /// Lazily adds types from a function producing types.
///
- ///
- public void AddTypeListDelegate(Func> typeListDelegate)
+ /// The functions producing types, to add.
+ public void AddTypeListDelegate(Func> typeListProducer)
{
- EnsureAddSupport();
+ EnsureSupportsAdd();
using (Resolution.Configuration)
using (GetWriteLock())
{
- _listOfTypeListDelegates.Add(typeListDelegate);
+ _typeListProducerList.Add(typeListProducer);
}
}
///
- /// Adds a lazy type to the list
+ /// Lazily adds a type from a lazy type.
///
- ///
+ /// The lazy type, to add.
public void AddType(Lazy value)
{
- EnsureAddSupport();
+ EnsureSupportsAdd();
using (Resolution.Configuration)
using (GetWriteLock())
@@ -190,9 +214,10 @@ namespace Umbraco.Core.ObjectResolution
}
///
- /// Converts the static type added to a lazy type and adds it to the internal list
+ /// Lazily adds a type from an actual type.
///
- ///
+ /// The actual type, to add.
+ /// The type is converted to a lazy type.
public override void AddType(Type value)
{
AddType(new Lazy(() => value));
@@ -203,7 +228,7 @@ namespace Umbraco.Core.ObjectResolution
///
public override void Clear()
{
- EnsureClearSupport();
+ EnsureSupportsClear();
using (Resolution.Configuration)
using (GetWriteLock())
@@ -212,8 +237,12 @@ namespace Umbraco.Core.ObjectResolution
}
}
- ///
- /// Does not support removal
+ #endregion
+
+ #region Types collection manipulation support
+
+ ///
+ /// Gets a false value indicating that the resolver does NOT support removing types.
///
protected override bool SupportsRemove
{
@@ -221,11 +250,13 @@ namespace Umbraco.Core.ObjectResolution
}
///
- /// Does not support insert
+ /// Gets a false value indicating that the resolver does NOT support inserting types.
///
protected override bool SupportsInsert
{
get { return false; }
- }
- }
+ }
+
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/ObjectResolution/LegacyTransientObjectsResolver.cs b/src/Umbraco.Core/ObjectResolution/LegacyTransientObjectsResolver.cs
index 23eb1f7565..eb871d4b73 100644
--- a/src/Umbraco.Core/ObjectResolution/LegacyTransientObjectsResolver.cs
+++ b/src/Umbraco.Core/ObjectResolution/LegacyTransientObjectsResolver.cs
@@ -27,18 +27,17 @@ namespace Umbraco.Core.ObjectResolution
#region Constructors
///
- /// Constructor
+ /// Initializes a new instance of the class with an initial list of object types.
///
- ///
+ /// A function returning the list of object types.
///
/// We are creating Transient instances (new instances each time) because this is how the legacy code worked and
/// I don't want to muck anything up by changing them to application based instances.
/// TODO: However, it would make much more sense to do this and would speed up the application plus this would make the GetById method much easier.
///
- protected LegacyTransientObjectsResolver(Func> types)
- : base(types, ObjectLifetimeScope.Transient) // new objects every time
- {
- }
+ protected LegacyTransientObjectsResolver(Func> value)
+ : base(value, ObjectLifetimeScope.Transient) // new objects every time
+ { }
#endregion
///
diff --git a/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs b/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs
index f4562c60fb..e4727d0489 100644
--- a/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs
+++ b/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs
@@ -25,7 +25,8 @@ namespace Umbraco.Core.ObjectResolution
#region Constructors
///
- /// Initializes a new instance of the class with an empty list of objects.
+ /// Initializes a new instance of the class with an empty list of objects,
+ /// and an optional lifetime scope.
///
/// The lifetime scope of instantiated objects, default is per Application.
/// If is per HttpRequest then there must be a current HttpContext.
@@ -65,7 +66,8 @@ namespace Umbraco.Core.ObjectResolution
}
///
- /// Initializes a new instance of the class with an initial list of object types.
+ /// Initializes a new instance of the class with an initial list of object types,
+ /// and an optional lifetime scope.
///
/// The list of object types.
/// The lifetime scope of instantiated objects, default is per Application.
@@ -215,18 +217,6 @@ namespace Umbraco.Core.ObjectResolution
#region Types collection manipulation
- ///
- /// Ensures that a type is a valid type for the resolver.
- ///
- /// The type to test.
- /// the type is not a valid type for the resolver.
- protected void EnsureCorrectType(Type value)
- {
- if (!TypeHelper.IsTypeAssignableFrom(value))
- throw new InvalidOperationException(string.Format(
- "Type {0} is not an acceptable type for resolver {1}.", value.FullName, this.GetType().FullName));
- }
-
///
/// Removes a type.
///
@@ -235,7 +225,7 @@ namespace Umbraco.Core.ObjectResolution
/// the type is not a valid type for the resolver.
public virtual void RemoveType(Type value)
{
- EnsureRemoveSupport();
+ EnsureSupportsRemove();
using (Resolution.Configuration)
using (var l = new UpgradeableReadLock(_lock))
@@ -268,7 +258,7 @@ namespace Umbraco.Core.ObjectResolution
/// a type is not a valid type for the resolver, or a type is already in the collection of types.
protected void AddTypes(IEnumerable types)
{
- EnsureAddSupport();
+ EnsureSupportsAdd();
using (Resolution.Configuration)
using (new WriteLock(_lock))
@@ -276,7 +266,7 @@ namespace Umbraco.Core.ObjectResolution
foreach(var t in types)
{
EnsureCorrectType(t);
- if (InstanceTypes.Contains(t))
+ if (_instanceTypes.Contains(t))
{
throw new InvalidOperationException(string.Format(
"Type {0} is already in the collection of types.", t.FullName));
@@ -295,13 +285,13 @@ namespace Umbraco.Core.ObjectResolution
/// the type is not a valid type for the resolver, or the type is already in the collection of types.
public virtual void AddType(Type value)
{
- EnsureAddSupport();
+ EnsureSupportsAdd();
using (Resolution.Configuration)
using (var l = new UpgradeableReadLock(_lock))
{
EnsureCorrectType(value);
- if (InstanceTypes.Contains(value))
+ if (_instanceTypes.Contains(value))
{
throw new InvalidOperationException(string.Format(
"Type {0} is already in the collection of types.", value.FullName));
@@ -331,7 +321,7 @@ namespace Umbraco.Core.ObjectResolution
/// the resolver does not support clearing types.
public virtual void Clear()
{
- EnsureClearSupport();
+ EnsureSupportsClear();
using (Resolution.Configuration)
using (new WriteLock(_lock))
@@ -350,13 +340,13 @@ namespace Umbraco.Core.ObjectResolution
/// is out of range.
public virtual void InsertType(int index, Type value)
{
- EnsureInsertSupport();
+ EnsureSupportsInsert();
using (Resolution.Configuration)
using (var l = new UpgradeableReadLock(_lock))
{
EnsureCorrectType(value);
- if (InstanceTypes.Contains(value))
+ if (_instanceTypes.Contains(value))
{
throw new InvalidOperationException(string.Format(
"Type {0} is already in the collection of types.", value.FullName));
@@ -389,24 +379,24 @@ namespace Umbraco.Core.ObjectResolution
/// or the new type is already in the collection of types.
public virtual void InsertTypeBefore(Type existingType, Type value)
{
- EnsureInsertSupport();
+ EnsureSupportsInsert();
using (Resolution.Configuration)
using (var l = new UpgradeableReadLock(_lock))
{
EnsureCorrectType(existingType);
EnsureCorrectType(value);
- if (!InstanceTypes.Contains(existingType))
+ if (!_instanceTypes.Contains(existingType))
{
throw new InvalidOperationException(string.Format(
"Type {0} is not in the collection of types.", existingType.FullName));
}
- if (InstanceTypes.Contains(value))
+ if (_instanceTypes.Contains(value))
{
throw new InvalidOperationException(string.Format(
"Type {0} is already in the collection of types.", value.FullName));
}
- int index = InstanceTypes.IndexOf(existingType);
+ int index = _instanceTypes.IndexOf(existingType);
l.UpgradeToWriteLock();
_instanceTypes.Insert(index, value);
@@ -463,60 +453,95 @@ namespace Umbraco.Core.ObjectResolution
return new WriteLock(_lock);
}
- ///
- /// Throws an exception if this does not support Remove
- ///
- protected void EnsureRemoveSupport()
+ #region Type utilities
+
+ ///
+ /// Ensures that a type is a valid type for the resolver.
+ ///
+ /// The type to test.
+ /// the type is not a valid type for the resolver.
+ protected void EnsureCorrectType(Type value)
+ {
+ if (!TypeHelper.IsTypeAssignableFrom(value))
+ throw new InvalidOperationException(string.Format(
+ "Type {0} is not an acceptable type for resolver {1}.", value.FullName, this.GetType().FullName));
+ }
+
+ #endregion
+
+ #region Types collection manipulation support
+
+ ///
+ /// Ensures that the resolver supports removing types.
+ ///
+ /// The resolver does not support removing types.
+ protected void EnsureSupportsRemove()
{
if (!SupportsRemove)
- throw new InvalidOperationException("This resolver does not support Removing types");
+ throw new InvalidOperationException("This resolver does not support removing types");
}
- ///
- /// Throws an exception if this does not support Clear
- ///
- protected void EnsureClearSupport()
- {
+ ///
+ /// Ensures that the resolver supports clearing types.
+ ///
+ /// The resolver does not support clearing types.
+ protected void EnsureSupportsClear() {
if (!SupportsClear)
- throw new InvalidOperationException("This resolver does not support Clearing types");
+ throw new InvalidOperationException("This resolver does not support clearing types");
}
- ///
- /// Throws an exception if this does not support Add
- ///
- protected void EnsureAddSupport()
+ ///
+ /// Ensures that the resolver supports adding types.
+ ///
+ /// The resolver does not support adding types.
+ protected void EnsureSupportsAdd()
{
if (!SupportsAdd)
- throw new InvalidOperationException("This resolver does not support Adding new types");
+ throw new InvalidOperationException("This resolver does not support adding new types");
}
- ///
- /// Throws an exception if this does not support insert
- ///
- protected void EnsureInsertSupport()
+ ///
+ /// Ensures that the resolver supports inserting types.
+ ///
+ /// The resolver does not support inserting types.
+ protected void EnsureSupportsInsert()
{
if (!SupportsInsert)
- throw new InvalidOperationException("This resolver does not support Inserting new types");
+ throw new InvalidOperationException("This resolver does not support inserting new types");
}
+ ///
+ /// Gets a value indicating whether the resolver supports adding types.
+ ///
protected virtual bool SupportsAdd
{
get { return true; }
}
- protected virtual bool SupportsInsert
+ ///
+ /// Gets a value indicating whether the resolver supports inserting types.
+ ///
+ protected virtual bool SupportsInsert
{
get { return true; }
}
- protected virtual bool SupportsClear
+ ///
+ /// Gets a value indicating whether the resolver supports clearing types.
+ ///
+ protected virtual bool SupportsClear
{
get { return true; }
}
- protected virtual bool SupportsRemove
+ ///
+ /// Gets a value indicating whether the resolver supports removing types.
+ ///
+ protected virtual bool SupportsRemove
{
get { return true; }
- }
- }
+ }
+
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/Resolvers/LazyManyObjectResolverTests.cs b/src/Umbraco.Tests/Resolvers/LazyManyObjectResolverTests.cs
index d7040057f6..666a7abebf 100644
--- a/src/Umbraco.Tests/Resolvers/LazyManyObjectResolverTests.cs
+++ b/src/Umbraco.Tests/Resolvers/LazyManyObjectResolverTests.cs
@@ -5,6 +5,7 @@ using System.Linq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.ObjectResolution;
+using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.Resolvers
{
@@ -15,19 +16,24 @@ namespace Umbraco.Tests.Resolvers
[SetUp]
public void Initialize()
{
-
- }
+ TestHelper.SetupLog4NetForTests();
+
+ Resolution.Reset();
+ LazyResolver.Reset();
+ }
[TearDown]
public void TearDown()
{
Resolution.Reset();
+ LazyResolver.Reset();
}
[Test]
- public void Ensure_Lazy_Type_Resolution()
+ public void LazyResolverResolvesLazyTypes()
{
- var resolver = new LazyResolver(new[] {new Lazy(() => typeof (TransientObject3))});
+ var resolver = new LazyResolver(new[] { new Lazy(() => typeof (TransientObject3)) });
+
resolver.AddType();
resolver.AddType(new Lazy(() => typeof(TransientObject2)));
@@ -35,16 +41,17 @@ namespace Umbraco.Tests.Resolvers
Assert.IsFalse(resolver.HasResolvedTypes);
- var instances1 = resolver.Objects;
+ var values = resolver.Objects;
Assert.IsTrue(resolver.HasResolvedTypes);
- Assert.AreEqual(3, instances1.Count());
- Assert.IsTrue(instances1.Select(x => x.GetType()).ContainsAll(new []{typeof(TransientObject1), typeof(TransientObject2), typeof(TransientObject3)}));
+ Assert.AreEqual(3, values.Count());
+ Assert.IsTrue(values.Select(x => x.GetType())
+ .ContainsAll(new [] { typeof(TransientObject1), typeof(TransientObject2), typeof(TransientObject3) }));
}
[Test]
- public void Type_List_Delegates_Combination()
+ public void LazyResolverResolvesTypeProducers()
{
Func> types = () => new[] { typeof(TransientObject3), typeof(TransientObject2) };
@@ -53,14 +60,15 @@ namespace Umbraco.Tests.Resolvers
Resolution.Freeze();
- var instances1 = resolver.Objects;
+ var values = resolver.Objects;
- Assert.AreEqual(3, instances1.Count());
- Assert.IsTrue(instances1.Select(x => x.GetType()).ContainsAll(new[] { typeof(TransientObject1), typeof(TransientObject2), typeof(TransientObject3) }));
+ Assert.AreEqual(3, values.Count());
+ Assert.IsTrue(values.Select(x => x.GetType())
+ .ContainsAll(new[] { typeof(TransientObject1), typeof(TransientObject2), typeof(TransientObject3) }));
}
[Test]
- public void Type_List_Delegates_And_Lazy_Type_Combination()
+ public void LazyResolverResolvesBothWays()
{
Func> types = () => new[] { typeof(TransientObject3) };
@@ -70,67 +78,79 @@ namespace Umbraco.Tests.Resolvers
Resolution.Freeze();
- var instances1 = resolver.Objects;
+ var values = resolver.Objects;
- Assert.AreEqual(3, instances1.Count());
- Assert.IsTrue(instances1.Select(x => x.GetType()).ContainsAll(new[] { typeof(TransientObject1), typeof(TransientObject2), typeof(TransientObject3) }));
+ Assert.AreEqual(3, values.Count());
+ Assert.IsTrue(values.Select(x => x.GetType())
+ .ContainsAll(new[] { typeof(TransientObject1), typeof(TransientObject2), typeof(TransientObject3) }));
}
[Test]
- public void Throws_If_Duplication()
+ public void LazyResolverThrowsOnDuplicate()
{
Func> types = () => new[] { typeof(TransientObject3), typeof(TransientObject2), typeof(TransientObject1) };
var resolver = new LazyResolver(types);
- //duplicate, but will not throw here
+
+ // duplicate, but will not throw here
resolver.AddType();
Resolution.Freeze();
Assert.Throws(() =>
{
- var instances = resolver.Objects;
+ var values = resolver.Objects;
});
-
-
}
+ [Test]
+ public void LazyResolverThrowsOnInvalidType()
+ {
+ Func> types = () => new[] { typeof(TransientObject3), typeof(TransientObject2), typeof(TransientObject1) };
+
+ var resolver = new LazyResolver(types);
+
+ // invalid, but will not throw here
+ resolver.AddType(new Lazy(() => typeof(TransientObject4)));
+
+ Resolution.Freeze();
+
+ Assert.Throws(() =>
+ {
+ var values = resolver.Objects;
+ });
+ }
+
#region Test classes
private interface ITestInterface
- {
- }
+ { }
private class TransientObject1 : ITestInterface
- {
- }
+ { }
private class TransientObject2 : ITestInterface
- {
- }
+ { }
private class TransientObject3 : ITestInterface
- {
- }
+ { }
+
+ private class TransientObject4
+ { }
private sealed class LazyResolver : LazyManyObjectsResolverBase
{
public LazyResolver()
: base(ObjectLifetimeScope.Transient)
- {
- }
+ { }
public LazyResolver(IEnumerable> values)
:base (values, ObjectLifetimeScope.Transient)
- {
-
- }
+ { }
- public LazyResolver(Func> typeList)
- : base(typeList, ObjectLifetimeScope.Transient)
- {
-
- }
+ public LazyResolver(Func> typeList)
+ : base(typeList, ObjectLifetimeScope.Transient)
+ { }
public IEnumerable Objects
{
diff --git a/src/Umbraco.Tests/Resolvers/ManyResolverTests.cs b/src/Umbraco.Tests/Resolvers/ManyResolverTests.cs
index c9389ffdec..c72b4cd3d1 100644
--- a/src/Umbraco.Tests/Resolvers/ManyResolverTests.cs
+++ b/src/Umbraco.Tests/Resolvers/ManyResolverTests.cs
@@ -49,7 +49,7 @@ namespace Umbraco.Tests.Resolvers
public class Resolved4 // not! : Resolved
{ }
- public class ManyResolver : ManyObjectsResolverBase
+ public sealed class ManyResolver : ManyObjectsResolverBase
{
public ManyResolver()
: base()
diff --git a/src/Umbraco.Tests/Resolvers/SingleResolverTests.cs b/src/Umbraco.Tests/Resolvers/SingleResolverTests.cs
index 8513324cfe..b6282cd208 100644
--- a/src/Umbraco.Tests/Resolvers/SingleResolverTests.cs
+++ b/src/Umbraco.Tests/Resolvers/SingleResolverTests.cs
@@ -35,7 +35,7 @@ namespace Umbraco.Tests.Resolvers
public class Resolved
{ }
- public class SingleResolver : SingleObjectResolverBase
+ public sealed class SingleResolver : SingleObjectResolverBase
{
public SingleResolver()
: base()