diff --git a/src/Umbraco.Core/ObjectResolution/Resolution.cs b/src/Umbraco.Core/ObjectResolution/Resolution.cs
index 0b478d54cf..31661f6f7b 100644
--- a/src/Umbraco.Core/ObjectResolution/Resolution.cs
+++ b/src/Umbraco.Core/ObjectResolution/Resolution.cs
@@ -68,44 +68,6 @@ namespace Umbraco.Core.ObjectResolution
// about using it for anything else. Also, while the backdoor is open, the resolution system is locked so nothing
// can work properly => deadlocks. Therefore, open the backdoor, do resolution changes EXCLUSIVELY, and close the door!
- ///
- /// Returns a disposable object that reprents dirty access to temporarily unfrozen resolution configuration.
- ///
- ///
- /// Should not be used.
- /// Should be used in a using(Resolution.DirtyBackdoorToConfiguration) { ... } mode.
- /// Because we just lift the frozen state, and we don't actually re-freeze, the Frozen event does not trigger.
- ///
- internal static IDisposable DirtyBackdoorToConfiguration
- {
- get { return new DirtyBackdoor(); }
- }
-
- // keep the class here because it needs write-access to Resolution.IsFrozen
- private class DirtyBackdoor : IDisposable
- {
-
- private readonly IDisposable _lock;
- private readonly bool _frozen;
-
- public DirtyBackdoor()
- {
- LogHelper.Debug(typeof(DirtyBackdoor), "Creating back door for resolution");
-
- _lock = new WriteLock(ConfigurationLock);
- _frozen = _isFrozen;
- _isFrozen = false;
- }
-
- public void Dispose()
- {
- LogHelper.Debug(typeof(DirtyBackdoor), "Disposing back door for resolution");
-
- _isFrozen = _frozen;
- _lock.Dispose();
- }
- }
-
///
/// Freezes resolution.
///
diff --git a/src/Umbraco.Tests/Resolvers/ActionsResolverTests.cs b/src/Umbraco.Tests/Resolvers/ActionCollectionTests.cs
similarity index 72%
rename from src/Umbraco.Tests/Resolvers/ActionsResolverTests.cs
rename to src/Umbraco.Tests/Resolvers/ActionCollectionTests.cs
index 3ddffaa694..dc75cd0431 100644
--- a/src/Umbraco.Tests/Resolvers/ActionsResolverTests.cs
+++ b/src/Umbraco.Tests/Resolvers/ActionCollectionTests.cs
@@ -1,184 +1,177 @@
-using System.Linq;
-using NUnit.Framework;
-using Umbraco.Core;
-using Umbraco.Core.ObjectResolution;
-using Umbraco.Web.UI.Pages;
-using Umbraco.Web;
-using Umbraco.Web._Legacy.Actions;
-
-namespace Umbraco.Tests.Resolvers
-{
- [TestFixture]
- public class ActionsResolverTests : ResolverBaseTest
- {
-
- [TearDown]
- public void TearDown()
- {
- ActionsResolver.Reset();
- }
-
- // NOTE
- // ManyResolverTests ensure that we'll get our actions back and ActionsResolver works,
- // so all we're testing here is that plugin manager _does_ find our actions
- // which should be ensured by PlugingManagerTests anyway, so this is useless?
- // maybe not as it seems to handle the "instance" thing... so we test that we respect the singleton?
- [Test]
- public void FindAllActions()
- {
- ActionsResolver.Current = new ActionsResolver(
- new ActivatorServiceProvider(), ProfilingLogger.Logger,
- () => PluginManager.ResolveActions());
-
- Resolution.Freeze();
-
- var actions = ActionsResolver.Current.Actions;
- Assert.AreEqual(2, actions.Count());
-
- // order is unspecified, but both must be there
- bool hasAction1 = actions.ElementAt(0) is SingletonAction || actions.ElementAt(1) is SingletonAction;
- bool hasAction2 = actions.ElementAt(0) is NonSingletonAction || actions.ElementAt(1) is NonSingletonAction;
- Assert.IsTrue(hasAction1);
- Assert.IsTrue(hasAction2);
-
- SingletonAction action = (SingletonAction)(actions.ElementAt(0) is SingletonAction ? actions.ElementAt(0) : actions.ElementAt(1));
-
- // ensure we respect the singleton
- Assert.AreSame(SingletonAction.Instance, action);
- }
-
- #region Classes for tests
-
- public class SingletonAction : IAction
- {
- //create singleton
- private static readonly SingletonAction instance = new SingletonAction();
-
- public static SingletonAction Instance
- {
- get { return instance; }
- }
-
- #region IAction Members
-
- public char Letter
- {
- get
- {
- return 'I';
- }
- }
-
- public string JsFunctionName
- {
- get
- {
- return string.Format("{0}.actionAssignDomain()", ClientTools.Scripts.GetAppActions);
- }
- }
-
- public string JsSource
- {
- get
- {
- return null;
- }
- }
-
- public string Alias
- {
- get
- {
- return "assignDomain";
- }
- }
-
- public string Icon
- {
- get
- {
- return ".sprDomain";
- }
- }
-
- public bool ShowInNotifier
- {
- get
- {
- return false;
- }
- }
- public bool CanBePermissionAssigned
- {
- get
- {
- return true;
- }
- }
- #endregion
- }
-
- public class NonSingletonAction : IAction
- {
- #region IAction Members
-
- public char Letter
- {
- get
- {
- return 'Q';
- }
- }
-
- public string JsFunctionName
- {
- get
- {
- return string.Format("{0}.actionAssignDomain()", ClientTools.Scripts.GetAppActions);
- }
- }
-
- public string JsSource
- {
- get
- {
- return null;
- }
- }
-
- public string Alias
- {
- get
- {
- return "asfasdf";
- }
- }
-
- public string Icon
- {
- get
- {
- return ".sprDomain";
- }
- }
-
- public bool ShowInNotifier
- {
- get
- {
- return false;
- }
- }
- public bool CanBePermissionAssigned
- {
- get
- {
- return true;
- }
- }
- #endregion
- }
-
- #endregion
- }
+using System.Linq;
+using LightInject;
+using Moq;
+using NUnit.Framework;
+using Umbraco.Core;
+using Umbraco.Core.DependencyInjection;
+using Umbraco.Core.ObjectResolution;
+using Umbraco.Web.UI.Pages;
+using Umbraco.Web;
+using Umbraco.Web._Legacy.Actions;
+
+namespace Umbraco.Tests.Resolvers
+{
+ [TestFixture]
+ public class ActionCollectionTests : ResolverBaseTest
+ {
+ // NOTE
+ // ManyResolverTests ensure that we'll get our actions back and ActionsResolver works,
+ // so all we're testing here is that plugin manager _does_ find our actions
+ // which should be ensured by PlugingManagerTests anyway, so this is useless?
+ // maybe not as it seems to handle the "instance" thing... so we test that we respect the singleton?
+ [Test]
+ public void FindAllActions()
+ {
+ var collectionBuilder = new ActionCollectionBuilder();
+ collectionBuilder.SetProducer(() => PluginManager.ResolveActions());
+
+ var actions = collectionBuilder.CreateCollection();
+ Assert.AreEqual(2, actions.Count());
+
+ // order is unspecified, but both must be there
+ var hasAction1 = actions.ElementAt(0) is SingletonAction || actions.ElementAt(1) is SingletonAction;
+ var hasAction2 = actions.ElementAt(0) is NonSingletonAction || actions.ElementAt(1) is NonSingletonAction;
+ Assert.IsTrue(hasAction1);
+ Assert.IsTrue(hasAction2);
+
+ var action = (SingletonAction)(actions.ElementAt(0) is SingletonAction ? actions.ElementAt(0) : actions.ElementAt(1));
+
+ // ensure we respect the singleton
+ Assert.AreSame(SingletonAction.Instance, action);
+ }
+
+ #region Classes for tests
+
+ public class SingletonAction : IAction
+ {
+ //create singleton
+ private static readonly SingletonAction instance = new SingletonAction();
+
+ public static SingletonAction Instance
+ {
+ get { return instance; }
+ }
+
+ #region IAction Members
+
+ public char Letter
+ {
+ get
+ {
+ return 'I';
+ }
+ }
+
+ public string JsFunctionName
+ {
+ get
+ {
+ return string.Format("{0}.actionAssignDomain()", ClientTools.Scripts.GetAppActions);
+ }
+ }
+
+ public string JsSource
+ {
+ get
+ {
+ return null;
+ }
+ }
+
+ public string Alias
+ {
+ get
+ {
+ return "assignDomain";
+ }
+ }
+
+ public string Icon
+ {
+ get
+ {
+ return ".sprDomain";
+ }
+ }
+
+ public bool ShowInNotifier
+ {
+ get
+ {
+ return false;
+ }
+ }
+ public bool CanBePermissionAssigned
+ {
+ get
+ {
+ return true;
+ }
+ }
+ #endregion
+ }
+
+ public class NonSingletonAction : IAction
+ {
+ #region IAction Members
+
+ public char Letter
+ {
+ get
+ {
+ return 'Q';
+ }
+ }
+
+ public string JsFunctionName
+ {
+ get
+ {
+ return string.Format("{0}.actionAssignDomain()", ClientTools.Scripts.GetAppActions);
+ }
+ }
+
+ public string JsSource
+ {
+ get
+ {
+ return null;
+ }
+ }
+
+ public string Alias
+ {
+ get
+ {
+ return "asfasdf";
+ }
+ }
+
+ public string Icon
+ {
+ get
+ {
+ return ".sprDomain";
+ }
+ }
+
+ public bool ShowInNotifier
+ {
+ get
+ {
+ return false;
+ }
+ }
+ public bool CanBePermissionAssigned
+ {
+ get
+ {
+ return true;
+ }
+ }
+ #endregion
+ }
+
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/Resolvers/XsltExtensionsResolverTests.cs b/src/Umbraco.Tests/Resolvers/XsltExtensionsResolverTests.cs
index b0f834bf89..fe17fd9b6b 100644
--- a/src/Umbraco.Tests/Resolvers/XsltExtensionsResolverTests.cs
+++ b/src/Umbraco.Tests/Resolvers/XsltExtensionsResolverTests.cs
@@ -17,12 +17,6 @@ namespace Umbraco.Tests.Resolvers
[TestFixture]
public class XsltExtensionsResolverTests : ResolverBaseTest
{
- [TearDown]
- public void TearDown()
- {
- ActionsResolver.Reset();
- }
-
// NOTE
// ManyResolverTests ensure that we'll get our actions back and ActionsResolver works,
// so all we're testing here is that plugin manager _does_ find our actions
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index fda799fd40..493e92e5ea 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -479,7 +479,7 @@
-
+
diff --git a/src/Umbraco.Web/Current.cs b/src/Umbraco.Web/Current.cs
index b1b65cae7b..f77159e819 100644
--- a/src/Umbraco.Web/Current.cs
+++ b/src/Umbraco.Web/Current.cs
@@ -6,6 +6,7 @@ using Umbraco.Core.Strings;
using Umbraco.Web.HealthCheck;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.Routing;
+using Umbraco.Web._Legacy.Actions;
using CoreCurrent = Umbraco.Core.DependencyInjection.Current;
namespace Umbraco.Web
@@ -118,6 +119,12 @@ namespace Umbraco.Web
public static HealthCheckCollectionBuilder HealthCheckCollectionBuilder
=> Container.GetInstance();
+ public static ActionCollectionBuilder ActionCollectionBuilder
+ => Container.GetInstance();
+
+ public static ActionCollection Actions
+ => Container.GetInstance();
+
#endregion
#region Core Getters
diff --git a/src/Umbraco.Web/Models/Trees/MenuItemList.cs b/src/Umbraco.Web/Models/Trees/MenuItemList.cs
index 76be2e4c00..36d596817a 100644
--- a/src/Umbraco.Web/Models/Trees/MenuItemList.cs
+++ b/src/Umbraco.Web/Models/Trees/MenuItemList.cs
@@ -122,7 +122,7 @@ namespace Umbraco.Web.Models.Trees
internal MenuItem CreateMenuItem(string name, bool hasSeparator = false, IDictionary additionalData = null)
where T : IAction
{
- var item = ActionsResolver.Current.GetAction();
+ var item = Current.Actions.GetAction();
if (item != null)
{
var menuItem = new MenuItem(item, name)
diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs
index f46218deb5..eaf6faae58 100644
--- a/src/Umbraco.Web/Trees/ContentTreeController.cs
+++ b/src/Umbraco.Web/Trees/ContentTreeController.cs
@@ -18,8 +18,8 @@ namespace Umbraco.Web.Trees
//We will not allow the tree to render unless the user has access to any of the sections that the tree gets rendered
// this is not ideal but until we change permissions to be tree based (not section) there's not much else we can do here.
[UmbracoApplicationAuthorize(
- Constants.Applications.Content,
- Constants.Applications.Media,
+ Constants.Applications.Content,
+ Constants.Applications.Media,
Constants.Applications.Users,
Constants.Applications.Settings,
Constants.Applications.Developer,
@@ -29,10 +29,10 @@ namespace Umbraco.Web.Trees
[CoreTree]
public class ContentTreeController : ContentTreeControllerBase
{
-
+
protected override TreeNode CreateRootNode(FormDataCollection queryStrings)
{
- var node = base.CreateRootNode(queryStrings);
+ var node = base.CreateRootNode(queryStrings);
//if the user's start node is not default, then ensure the root doesn't have a menu
if (Security.CurrentUser.StartContentId != Constants.System.Root)
{
@@ -56,7 +56,7 @@ namespace Umbraco.Web.Trees
{
get { return Security.CurrentUser.StartContentId; }
}
-
+
///
/// Creates a tree node for a content item based on an UmbracoEntity
///
@@ -90,7 +90,7 @@ namespace Umbraco.Web.Trees
node.AdditionalData.Add("isContainer", true);
node.SetContainerStyle();
}
-
+
if (entity.IsPublished == false)
node.SetNotPublishedStyle();
@@ -142,7 +142,7 @@ namespace Umbraco.Web.Trees
// add default actions for *all* users
menu.Items.Add(Services.TextService.Localize("actions", ActionRePublish.Instance.Alias)).ConvertLegacyMenuItem(null, "content", "content");
menu.Items.Add(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
-
+
return menu;
}
@@ -161,7 +161,7 @@ namespace Umbraco.Web.Trees
var nodeMenu = GetAllNodeMenuItems(item);
var allowedMenuItems = GetAllowedUserMenuItemsForNode(item);
-
+
FilterUserAllowedMenuItems(nodeMenu, allowedMenuItems);
//if the media item is in the recycle bin, don't have a default menu, just show the regular menu
@@ -173,9 +173,9 @@ namespace Umbraco.Web.Trees
else
{
//set the default to create
- nodeMenu.DefaultMenuAlias = ActionNew.Instance.Alias;
+ nodeMenu.DefaultMenuAlias = ActionNew.Instance.Alias;
}
-
+
return nodeMenu;
}
@@ -209,31 +209,45 @@ namespace Umbraco.Web.Trees
protected MenuItemCollection GetAllNodeMenuItems(IUmbracoEntity item)
{
var menu = new MenuItemCollection();
- menu.Items.Add(Services.TextService.Localize("actions", ActionNew.Instance.Alias));
- menu.Items.Add(Services.TextService.Localize("actions", ActionDelete.Instance.Alias));
-
+ AddActionNode(item, menu);
+ AddActionNode(item, menu);
+
//need to ensure some of these are converted to the legacy system - until we upgrade them all to be angularized.
- menu.Items.Add(Services.TextService.Localize("actions", ActionMove.Instance.Alias), true);
- menu.Items.Add(Services.TextService.Localize("actions", ActionCopy.Instance.Alias));
- menu.Items.Add(Services.TextService.Localize("actions", ActionChangeDocType.Instance.Alias)).ConvertLegacyMenuItem(item, "content", "content");
+ AddActionNode(item, menu, true);
+ AddActionNode(item, menu);
+ AddActionNode(item, menu, convert: true);
- menu.Items.Add(Services.TextService.Localize("actions", ActionSort.Instance.Alias), true).ConvertLegacyMenuItem(item, "content", "content");
+ AddActionNode(item, menu, true, true);
- menu.Items.Add(Services.TextService.Localize("actions", ActionRollback.Instance.Alias)).ConvertLegacyMenuItem(item, "content", "content");
- menu.Items.Add(Services.TextService.Localize("actions", ActionAudit.Instance.Alias)).ConvertLegacyMenuItem(item, "content", "content");
- menu.Items.Add(Services.TextService.Localize("actions", ActionPublish.Instance.Alias), true).ConvertLegacyMenuItem(item, "content", "content");
- menu.Items.Add(Services.TextService.Localize("actions", ActionToPublish.Instance.Alias)).ConvertLegacyMenuItem(item, "content", "content");
- menu.Items.Add(Services.TextService.Localize("actions", ActionAssignDomain.Instance.Alias)).ConvertLegacyMenuItem(item, "content", "content");
- menu.Items.Add(Services.TextService.Localize("actions", ActionRights.Instance.Alias)).ConvertLegacyMenuItem(item, "content", "content");
- menu.Items.Add(Services.TextService.Localize("actions", ActionProtect.Instance.Alias), true).ConvertLegacyMenuItem(item, "content", "content");
-
- menu.Items.Add(Services.TextService.Localize("actions", ActionNotify.Instance.Alias), true).ConvertLegacyMenuItem(item, "content", "content");
- menu.Items.Add(Services.TextService.Localize("actions", ActionSendToTranslate.Instance.Alias)).ConvertLegacyMenuItem(item, "content", "content");
+ AddActionNode(item, menu, convert: true);
+ AddActionNode(item, menu, convert: true);
+ AddActionNode(item, menu, true, true);
+ AddActionNode(item, menu, convert: true);
+ AddActionNode(item, menu, convert: true);
+ AddActionNode(item, menu, convert: true);
+ AddActionNode(item, menu, true, true);
- menu.Items.Add(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
+ AddActionNode(item, menu, true, true);
+ AddActionNode(item, menu, convert: true);
+
+ AddActionNode(item, menu, true);
return menu;
}
+ private void AddActionNode(IUmbracoEntity item, MenuItemCollection menu, bool hasSeparator = false, bool convert = false)
+ where TAction : IAction
+ {
+ var menuItem = menu.Items.Add(Services.TextService.Localize("actions", Current.Actions.GetAction().Alias), hasSeparator);
+ if (convert) menuItem.ConvertLegacyMenuItem(item, "content", "content");
+ }
+
+ private void AddActionNode(IUmbracoEntity item, MenuItemCollection menu, bool hasSeparator = false, bool convert = false)
+ where TItem : MenuItem, new()
+ where TAction : IAction
+ {
+ var menuItem = menu.Items.Add(Services.TextService.Localize("actions", Current.Actions.GetAction().Alias), hasSeparator);
+ if (convert) menuItem.ConvertLegacyMenuItem(item, "content", "content");
+ }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Trees/LegacyTreeJavascript.cs b/src/Umbraco.Web/Trees/LegacyTreeJavascript.cs
index 17716724c1..30e677455e 100644
--- a/src/Umbraco.Web/Trees/LegacyTreeJavascript.cs
+++ b/src/Umbraco.Web/Trees/LegacyTreeJavascript.cs
@@ -47,7 +47,7 @@ namespace Umbraco.Web.Trees
public static string GetLegacyIActionJavascript()
{
var js = new StringBuilder();
- foreach (var a in ActionsResolver.Current.Actions.ToList())
+ foreach (var a in Current.Actions)
{
// NH: Added a try/catch block to this as an error in a 3rd party action can crash the whole menu initialization
try
diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs
index d07069dea6..277fd3b0be 100644
--- a/src/Umbraco.Web/WebBootManager.cs
+++ b/src/Umbraco.Web/WebBootManager.cs
@@ -476,9 +476,8 @@ namespace Umbraco.Web
}));
}
- ActionsResolver.Current = new ActionsResolver(
- ServiceProvider, ProfilingLogger.Logger,
- () => PluginManager.ResolveActions());
+ ActionCollectionBuilder.Register(Container)
+ .SetProducer(() => PluginManager.ResolveActions());
SurfaceControllerResolver.Current = new SurfaceControllerResolver(
ServiceProvider, ProfilingLogger.Logger,
diff --git a/src/Umbraco.Web/_Legacy/Actions/Action.cs b/src/Umbraco.Web/_Legacy/Actions/Action.cs
index 611e45bafd..32a808664b 100644
--- a/src/Umbraco.Web/_Legacy/Actions/Action.cs
+++ b/src/Umbraco.Web/_Legacy/Actions/Action.cs
@@ -19,8 +19,8 @@ namespace Umbraco.Web._Legacy.Actions
///
/// The Action class itself has responsibility for registering actions and actionhandlers,
/// and contains methods which will be invoked whenever a change is made to ex. a document, media or member
- ///
- /// An action/actionhandler will automatically be registered, using reflection
+ ///
+ /// An action/actionhandler will automatically be registered, using reflection
/// which is enabling thirdparty developers to extend the core functionality of
/// umbraco without changing the codebase.
///
@@ -47,20 +47,8 @@ namespace Umbraco.Web._Legacy.Actions
{
lock (Lock)
{
- // NOTE use the DirtyBackdoor to change the resolution configuration EXCLUSIVELY
- // ie do NOT do ANYTHING else while holding the backdoor, because while it is open
- // the whole resolution system is locked => nothing can work properly => deadlocks
-
- var newResolver = new ActionsResolver(
- new ActivatorServiceProvider(), LoggerResolver.Current.Logger,
- () => TypeFinder.FindClassesOfType(PluginManager.Current.AssembliesToScan));
-
- using (Umbraco.Core.ObjectResolution.Resolution.DirtyBackdoorToConfiguration)
- {
- ActionsResolver.Reset(false); // and do NOT reset the whole resolution!
- ActionsResolver.Current = newResolver;
- }
-
+ // this will reset the collection
+ Current.ActionCollectionBuilder.SetProducer(() => TypeFinder.FindClassesOfType(PluginManager.Current.AssembliesToScan));
}
}
@@ -81,7 +69,7 @@ namespace Umbraco.Web._Legacy.Actions
///
public static List GetJavaScriptFileReferences()
{
- return ActionsResolver.Current.Actions
+ return Current.Actions
.Where(x => !string.IsNullOrWhiteSpace(x.JsSource))
.Select(x => x.JsSource).ToList();
//return ActionJsReference;
@@ -90,7 +78,7 @@ namespace Umbraco.Web._Legacy.Actions
///
/// Javascript menuitems - tree contextmenu
/// Umbraco console
- ///
+ ///
/// Suggestion: this method should be moved to the presentation layer.
///
///
@@ -101,7 +89,7 @@ namespace Umbraco.Web._Legacy.Actions
{
string _actionJsList = "";
- foreach (IAction action in ActionsResolver.Current.Actions)
+ foreach (IAction action in Current.Actions)
{
// Adding try/catch so this rutine doesn't fail if one of the actions fail
// Add to language JsList
@@ -139,7 +127,7 @@ namespace Umbraco.Web._Legacy.Actions
List list = new List();
foreach (var c in entityPermission.AssignedPermissions.Where(x => x.Length == 1).Select(x => x.ToCharArray()[0]))
{
- IAction action = ActionsResolver.Current.Actions.ToList().Find(
+ IAction action = Current.Actions.ToList().Find(
delegate (IAction a)
{
return a.Letter == c;
@@ -162,7 +150,7 @@ namespace Umbraco.Web._Legacy.Actions
List list = new List();
foreach (char c in actions.ToCharArray())
{
- IAction action = ActionsResolver.Current.Actions.ToList().Find(
+ IAction action = Current.Actions.ToList().Find(
delegate(IAction a)
{
return a.Letter == c;
@@ -190,7 +178,7 @@ namespace Umbraco.Web._Legacy.Actions
///
public static List GetPermissionAssignable()
{
- return ActionsResolver.Current.Actions.ToList().FindAll(
+ return Current.Actions.ToList().FindAll(
delegate(IAction a)
{
return (a.CanBePermissionAssigned);
diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionAssignDomain.cs b/src/Umbraco.Web/_Legacy/Actions/ActionAssignDomain.cs
index 5f87feaf50..70601cf959 100644
--- a/src/Umbraco.Web/_Legacy/Actions/ActionAssignDomain.cs
+++ b/src/Umbraco.Web/_Legacy/Actions/ActionAssignDomain.cs
@@ -2,74 +2,83 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
-using Umbraco.Core.Logging;
-using Umbraco.Core.ObjectResolution;
-using Umbraco.Core._Legacy.PackageActions;
+using LightInject;
+using Umbraco.Core.DependencyInjection;
using Umbraco.Web.UI.Pages;
namespace Umbraco.Web._Legacy.Actions
{
- ///
- /// A resolver to return all IAction objects
- ///
- public sealed class ActionsResolver : LazyManyObjectsResolverBase
+ public class ActionCollectionBuilder : ICollectionBuilder
{
- ///
- /// Constructor
- ///
- ///
- ///
- ///
- internal ActionsResolver(IServiceProvider serviceProvider, ILogger logger, Func> packageActions)
- : base(serviceProvider, logger, packageActions)
- {
+ private static Func> _producer;
+ public static ActionCollectionBuilder Register(IServiceContainer container)
+ {
+ // register the builder - per container
+ var builderLifetime = new PerContainerLifetime();
+ container.Register(builderLifetime);
+
+ // get the builder, get the collection lifetime
+ var builder = container.GetInstance();
+ var collectionLifetime = builder.CollectionLifetime;
+
+ // register the collection - special lifetime
+ container.Register(factory => factory.GetInstance().CreateCollection(), collectionLifetime);
+
+ return builder;
}
- ///
- /// Gets the implementations.
- ///
- public IEnumerable Actions
- {
- get
- {
- return Values;
- }
- }
-
- ///
- /// Gets an Action if it exists.
- ///
- ///
- ///
- internal IAction GetAction()
- where T : IAction
- {
- return Actions.SingleOrDefault(x => x.GetType() == typeof(T));
- }
-
- protected override IEnumerable CreateInstances()
+ public ActionCollection CreateCollection()
{
var actions = new List();
- var foundIActions = InstanceTypes;
- foreach (var type in foundIActions)
+ foreach (var type in _producer())
{
- IAction typeInstance;
- var instance = type.GetProperty("Instance", BindingFlags.Public | BindingFlags.Static);
- //if the singletone initializer is not found, try simply creating an instance of the IAction if it supports public constructors
- if (instance == null)
- typeInstance = ServiceProvider.GetService(type) as IAction;
- else
- typeInstance = instance.GetValue(null, null) as IAction;
-
- if (typeInstance != null)
- {
- actions.Add(typeInstance);
- }
+ var getter = type.GetProperty("Instance", BindingFlags.Public | BindingFlags.Static);
+ var instance = getter == null
+ ? Activator.CreateInstance(type) as IAction
+ : getter.GetValue(null, null) as IAction;
+ if (instance == null) continue;
+ actions.Add(instance);
}
- return actions;
+ return new ActionCollection(actions);
}
+ public void SetProducer(Func> producer)
+ {
+ _producer = producer;
+ CollectionLifetime.Reset();
+ }
+
+ private ResettablePerContainerLifetime CollectionLifetime { get; } = new ResettablePerContainerLifetime();
+
+ private class ResettablePerContainerLifetime : ILifetime
+ {
+ private object _instance;
+
+ public object GetInstance(Func