diff --git a/src/Umbraco.Core/Components/BootLoader.cs b/src/Umbraco.Core/Components/BootLoader.cs
index ee38864933..b80fa93500 100644
--- a/src/Umbraco.Core/Components/BootLoader.cs
+++ b/src/Umbraco.Core/Components/BootLoader.cs
@@ -3,8 +3,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
-using LightInject;
using Umbraco.Core.Collections;
+using Umbraco.Core.Composing;
using Umbraco.Core.Exceptions;
using Umbraco.Core.Logging;
using Umbraco.Core.Scoping;
@@ -15,7 +15,7 @@ namespace Umbraco.Core.Components
internal class BootLoader
{
- private readonly IServiceContainer _container;
+ private readonly IContainer _container;
private readonly ProfilingLogger _proflog;
private readonly ILogger _logger;
private IUmbracoComponent[] _components;
@@ -27,7 +27,7 @@ namespace Umbraco.Core.Components
/// Initializes a new instance of the class.
///
/// The application container.
- public BootLoader(IServiceContainer container)
+ public BootLoader(IContainer container)
{
_container = container ?? throw new ArgumentNullException(nameof(container));
_proflog = container.GetInstance();
@@ -247,15 +247,16 @@ namespace Umbraco.Core.Components
private static void GatherRequirementsFromRequiredAttribute(Type type, ICollection types, IDictionary> requirements)
{
// get 'required' attributes
- // fixme explain
+ // these attributes are *not* inherited because we want to "custom-inherit" for interfaces only
var requiredAttributes = type
- .GetInterfaces().SelectMany(x => x.GetCustomAttributes())
- .Concat(type.GetCustomAttributes());
+ .GetInterfaces().SelectMany(x => x.GetCustomAttributes()) // those marking interfaces
+ .Concat(type.GetCustomAttributes()); // those marking the component
foreach (var attr in requiredAttributes)
{
if (attr.RequiringType == type) continue; // ignore self-requirements (+ exclude in implems, below)
+ // required by an interface = by any enabled component implementing this that interface
if (attr.RequiringType.IsInterface)
{
var implems = types.Where(x => x != type && attr.RequiringType.IsAssignableFrom(x)).ToList();
@@ -265,6 +266,7 @@ namespace Umbraco.Core.Components
requirements[implem].Add(type);
}
}
+ // required by a class
else
{
if (types.Contains(attr.RequiringType))
diff --git a/src/Umbraco.Core/Components/Composition.cs b/src/Umbraco.Core/Components/Composition.cs
index 671469c73a..91fa519694 100644
--- a/src/Umbraco.Core/Components/Composition.cs
+++ b/src/Umbraco.Core/Components/Composition.cs
@@ -1,4 +1,4 @@
-using LightInject;
+using Umbraco.Core.Composing;
namespace Umbraco.Core.Components
{
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Components
///
/// A container.
/// The runtime level.
- public Composition(IServiceContainer container, RuntimeLevel level)
+ public Composition(IContainer container, RuntimeLevel level)
{
Container = container;
RuntimeLevel = level;
@@ -27,7 +27,7 @@ namespace Umbraco.Core.Components
/// Gets the container.
///
/// Use with care!
- public IServiceContainer Container { get; }
+ public IContainer Container { get; }
///
/// Gets the runtime level.
diff --git a/src/Umbraco.Core/Components/CompositionExtensions.cs b/src/Umbraco.Core/Components/CompositionExtensions.cs
index 7e94e4dc2b..abc0fa3862 100644
--- a/src/Umbraco.Core/Components/CompositionExtensions.cs
+++ b/src/Umbraco.Core/Components/CompositionExtensions.cs
@@ -1,6 +1,4 @@
using System;
-using System.Runtime.CompilerServices;
-using LightInject;
using Umbraco.Core.Cache;
using Umbraco.Core.Dictionary;
using Umbraco.Core.Composing;
@@ -97,7 +95,7 @@ namespace Umbraco.Core.Components
///
/// The composition.
/// A function creating a culture dictionary factory.
- public static void SetCultureDictionaryFactory(this Composition composition, Func factory)
+ public static void SetCultureDictionaryFactory(this Composition composition, Func factory)
{
composition.Container.RegisterSingleton(factory);
}
@@ -128,7 +126,7 @@ namespace Umbraco.Core.Components
///
/// The composition.
/// A function creating a published content model factory.
- public static void SetPublishedContentModelFactory(this Composition composition, Func factory)
+ public static void SetPublishedContentModelFactory(this Composition composition, Func factory)
{
composition.Container.RegisterSingleton(factory);
}
@@ -159,7 +157,7 @@ namespace Umbraco.Core.Components
///
/// The composition.
/// A function creating a server registar.
- public static void SetServerRegistrar(this Composition composition, Func factory)
+ public static void SetServerRegistrar(this Composition composition, Func factory)
{
composition.Container.RegisterSingleton(factory);
}
@@ -182,7 +180,7 @@ namespace Umbraco.Core.Components
public static void SetServerMessenger(this Composition composition)
where T : IServerMessenger
{
- composition.Container.RegisterSingleton();
+ composition.Container.Register(Lifetime.Singleton);
}
///
@@ -190,7 +188,7 @@ namespace Umbraco.Core.Components
///
/// The composition.
/// A function creating a server messenger.
- public static void SetServerMessenger(this Composition composition, Func factory)
+ public static void SetServerMessenger(this Composition composition, Func factory)
{
composition.Container.RegisterSingleton(factory);
}
@@ -221,7 +219,7 @@ namespace Umbraco.Core.Components
///
/// The composition.
/// A function creating a short string helper.
- public static void SetShortStringHelper(this Composition composition, Func factory)
+ public static void SetShortStringHelper(this Composition composition, Func factory)
{
composition.Container.RegisterSingleton(factory);
}
diff --git a/src/Umbraco.Core/Composing/CollectionBuilderBase.cs b/src/Umbraco.Core/Composing/CollectionBuilderBase.cs
index 3fac2d3255..2dbefc860f 100644
--- a/src/Umbraco.Core/Composing/CollectionBuilderBase.cs
+++ b/src/Umbraco.Core/Composing/CollectionBuilderBase.cs
@@ -140,7 +140,7 @@ namespace Umbraco.Core.Composing
var type = typeof (TItem);
return _registrations
- .Select(x => (TItem) Container.GetInstanceOrThrow(type, x.ServiceName, x.ImplementingType, args))
+ .Select(x => (TItem) Container.GetInstance(type, x.ServiceName, args))
.ToArray(); // safe
}
diff --git a/src/Umbraco.Core/Composing/Composers/ConfigurationComposer.cs b/src/Umbraco.Core/Composing/Composers/ConfigurationComposer.cs
index e2ba477045..4e8f2ec65c 100644
--- a/src/Umbraco.Core/Composing/Composers/ConfigurationComposer.cs
+++ b/src/Umbraco.Core/Composing/Composers/ConfigurationComposer.cs
@@ -1,5 +1,4 @@
-using LightInject;
-using Umbraco.Core.Configuration;
+using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
namespace Umbraco.Core.Composing.Composers
@@ -9,17 +8,17 @@ namespace Umbraco.Core.Composing.Composers
///
public static class ConfigurationComposer
{
- public static IServiceRegistry ComposeConfiguration(this IServiceRegistry registry)
+ public static IContainer ComposeConfiguration(this IContainer container)
{
- registry.Register(factory => UmbracoConfig.For.UmbracoSettings());
- registry.Register(factory => factory.GetInstance().Content);
- registry.Register(factory => factory.GetInstance().Templates);
- registry.Register(factory => factory.GetInstance().RequestHandler);
- registry.Register(factory => UmbracoConfig.For.GlobalSettings());
+ container.Register(factory => UmbracoConfig.For.UmbracoSettings());
+ container.Register(factory => factory.GetInstance().Content);
+ container.Register(factory => factory.GetInstance().Templates);
+ container.Register(factory => factory.GetInstance().RequestHandler);
+ container.Register(factory => UmbracoConfig.For.GlobalSettings());
// fixme - other sections we need to add?
- return registry;
+ return container;
}
}
}
diff --git a/src/Umbraco.Core/Composing/Composers/CoreMappingProfilesComposer.cs b/src/Umbraco.Core/Composing/Composers/CoreMappingProfilesComposer.cs
index ce9f507b9f..a1fc36a8c4 100644
--- a/src/Umbraco.Core/Composing/Composers/CoreMappingProfilesComposer.cs
+++ b/src/Umbraco.Core/Composing/Composers/CoreMappingProfilesComposer.cs
@@ -1,15 +1,14 @@
-using LightInject;
-using Umbraco.Core.Models.Identity;
+using Umbraco.Core.Models.Identity;
namespace Umbraco.Core.Composing.Composers
{
public static class CoreMappingProfilesComposer
{
- public static IServiceRegistry ComposeCoreMappingProfiles(this IServiceRegistry registry)
+ public static IContainer ComposeCoreMappingProfiles(this IContainer container)
{
- registry.Register();
- return registry;
+ container.Register();
+ return container;
}
}
}
diff --git a/src/Umbraco.Core/Composing/Composers/FileSystemsComposer.cs b/src/Umbraco.Core/Composing/Composers/FileSystemsComposer.cs
index c7ed93680b..565db9c623 100644
--- a/src/Umbraco.Core/Composing/Composers/FileSystemsComposer.cs
+++ b/src/Umbraco.Core/Composing/Composers/FileSystemsComposer.cs
@@ -1,5 +1,4 @@
-using LightInject;
-using Umbraco.Core.Configuration.UmbracoSettings;
+using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
@@ -7,22 +6,22 @@ namespace Umbraco.Core.Composing.Composers
{
public static class FileSystemsComposer
{
- public static IServiceRegistry ComposeFileSystems(this IServiceRegistry registry)
+ public static IContainer ComposeFileSystems(this IContainer container)
{
// register FileSystems, which manages all filesystems
- registry.RegisterSingleton();
+ container.RegisterSingleton();
// register IFileSystems, which gives access too all filesystems
- registry.RegisterSingleton(factory => factory.GetInstance());
+ container.RegisterSingleton(factory => factory.GetInstance());
// register MediaFileSystem, which can be injected directly
- registry.RegisterSingleton(factory => factory.GetInstance().MediaFileSystem);
+ container.RegisterSingleton(factory => factory.GetInstance().MediaFileSystem);
// register MediaFileSystem, so that FileSystems can create it
- registry.Register((f, wrappedFileSystem)
+ container.Register((f, wrappedFileSystem)
=> new MediaFileSystem(wrappedFileSystem, f.GetInstance(), f.GetInstance(), f.GetInstance()));
- return registry;
+ return container;
}
}
}
diff --git a/src/Umbraco.Core/Composing/Composers/RepositoriesComposer.cs b/src/Umbraco.Core/Composing/Composers/RepositoriesComposer.cs
index 79b2b9c223..25399af5c7 100644
--- a/src/Umbraco.Core/Composing/Composers/RepositoriesComposer.cs
+++ b/src/Umbraco.Core/Composing/Composers/RepositoriesComposer.cs
@@ -1,5 +1,4 @@
-using LightInject;
-using Umbraco.Core.Persistence.Repositories;
+using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.Repositories.Implement;
namespace Umbraco.Core.Composing.Composers
@@ -9,48 +8,48 @@ namespace Umbraco.Core.Composing.Composers
///
public static class RepositoriesComposer
{
- public static IServiceRegistry ComposeRepositories(this IServiceRegistry registry)
+ public static IContainer ComposeRepositories(this IContainer container)
{
// repositories
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
- return registry;
+ return container;
}
}
}
diff --git a/src/Umbraco.Core/Composing/Composers/ServicesComposer.cs b/src/Umbraco.Core/Composing/Composers/ServicesComposer.cs
index c774912f2e..fc898dd3b6 100644
--- a/src/Umbraco.Core/Composing/Composers/ServicesComposer.cs
+++ b/src/Umbraco.Core/Composing/Composers/ServicesComposer.cs
@@ -1,7 +1,6 @@
using System;
using System.IO;
using System.Linq;
-using LightInject;
using Umbraco.Core.Cache;
using Umbraco.Core.Events;
using Umbraco.Core.IO;
@@ -13,83 +12,85 @@ namespace Umbraco.Core.Composing.Composers
{
public static class ServicesComposer
{
- public static IServiceRegistry ComposeServices(this IServiceRegistry registry)
+ public static IContainer ComposeServices(this IContainer container)
{
// register a transient messages factory, which will be replaced by the web
// boot manager when running in a web context
- registry.RegisterSingleton();
+ container.RegisterSingleton();
// register the service context
- registry.RegisterSingleton();
+ container.RegisterSingleton();
// register the special idk map
- registry.RegisterSingleton();
+ container.RegisterSingleton();
// register the services
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.RegisterSingleton();
- registry.Register(factory =>
- {
- var mainLangFolder = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.Umbraco + "/config/lang/"));
- var appPlugins = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.AppPlugins));
- var configLangFolder = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.Config + "/lang/"));
-
- var pluginLangFolders = appPlugins.Exists == false
- ? Enumerable.Empty()
- : appPlugins.GetDirectories()
- .SelectMany(x => x.GetDirectories("Lang"))
- .SelectMany(x => x.GetFiles("*.xml", SearchOption.TopDirectoryOnly))
- .Where(x => Path.GetFileNameWithoutExtension(x.FullName).Length == 5)
- .Select(x => new LocalizedTextServiceSupplementaryFileSource(x, false));
-
- //user defined langs that overwrite the default, these should not be used by plugin creators
- var userLangFolders = configLangFolder.Exists == false
- ? Enumerable.Empty()
- : configLangFolder
- .GetFiles("*.user.xml", SearchOption.TopDirectoryOnly)
- .Where(x => Path.GetFileNameWithoutExtension(x.FullName).Length == 10)
- .Select(x => new LocalizedTextServiceSupplementaryFileSource(x, true));
-
- return new LocalizedTextServiceFileSources(
- factory.GetInstance(),
- factory.GetInstance().RuntimeCache,
- mainLangFolder,
- pluginLangFolders.Concat(userLangFolders));
- });
- registry.RegisterSingleton(factory => new LocalizedTextService(
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
+ container.Register(SourcesFactory);
+ container.RegisterSingleton(factory => new LocalizedTextService(
factory.GetInstance>(),
factory.GetInstance()));
//TODO: These are replaced in the web project - we need to declare them so that
// something is wired up, just not sure this is very nice but will work for now.
- registry.RegisterSingleton();
- registry.RegisterSingleton();
+ container.RegisterSingleton();
+ container.RegisterSingleton();
- return registry;
+ return container;
+ }
+
+ private static LocalizedTextServiceFileSources SourcesFactory(IContainer container)
+ {
+ var mainLangFolder = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.Umbraco + "/config/lang/"));
+ var appPlugins = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.AppPlugins));
+ var configLangFolder = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.Config + "/lang/"));
+
+ var pluginLangFolders = appPlugins.Exists == false
+ ? Enumerable.Empty()
+ : appPlugins.GetDirectories()
+ .SelectMany(x => x.GetDirectories("Lang"))
+ .SelectMany(x => x.GetFiles("*.xml", SearchOption.TopDirectoryOnly))
+ .Where(x => Path.GetFileNameWithoutExtension(x.FullName).Length == 5)
+ .Select(x => new LocalizedTextServiceSupplementaryFileSource(x, false));
+
+ //user defined langs that overwrite the default, these should not be used by plugin creators
+ var userLangFolders = configLangFolder.Exists == false
+ ? Enumerable.Empty()
+ : configLangFolder
+ .GetFiles("*.user.xml", SearchOption.TopDirectoryOnly)
+ .Where(x => Path.GetFileNameWithoutExtension(x.FullName).Length == 10)
+ .Select(x => new LocalizedTextServiceSupplementaryFileSource(x, true));
+
+ return new LocalizedTextServiceFileSources(
+ container.GetInstance(),
+ container.GetInstance().RuntimeCache,
+ mainLangFolder,
+ pluginLangFolders.Concat(userLangFolders));
}
}
}
diff --git a/src/Umbraco.Core/Composing/Current.cs b/src/Umbraco.Core/Composing/Current.cs
index fcff2c4b9e..d0025c0c8b 100644
--- a/src/Umbraco.Core/Composing/Current.cs
+++ b/src/Umbraco.Core/Composing/Current.cs
@@ -1,5 +1,4 @@
using System;
-using LightInject;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Dictionary;
@@ -20,7 +19,7 @@ namespace Umbraco.Core.Composing
/// Provides a static service locator for most singletons.
///
///
- /// This class is initialized with the container via LightInjectExtensions.ConfigureUmbracoCore,
+ /// This class is initialized with the container in UmbracoApplicationBase,
/// right after the container is created in UmbracoApplicationBase.HandleApplicationStart.
/// Obviously, this is a service locator, which some may consider an anti-pattern. And yet,
/// practically, it works.
diff --git a/src/Umbraco.Core/Composing/IContainer.cs b/src/Umbraco.Core/Composing/IContainer.cs
index 7183a76af2..ba611063e2 100644
--- a/src/Umbraco.Core/Composing/IContainer.cs
+++ b/src/Umbraco.Core/Composing/IContainer.cs
@@ -1,11 +1,12 @@
using System;
+using System.Collections.Generic;
namespace Umbraco.Core.Composing
{
///
/// Defines a container for Umbraco.
///
- public interface IContainer
+ public interface IContainer : IDisposable
{
///
/// Gets the concrete container.
@@ -22,6 +23,15 @@ namespace Umbraco.Core.Composing
/// Throws an exception if the container failed to get an instance of the specified type.
object GetInstance(Type type);
+ ///
+ /// Gets a named instance.
+ ///
+ /// The type of the instance.
+ /// The name of the instance.
+ /// An instance of the specified type.
+ /// Throws an exception if the container failed to get an instance of the specified type.
+ object GetInstance(Type type, string name);
+
///
/// Gets an instance with arguments.
///
@@ -44,16 +54,62 @@ namespace Umbraco.Core.Composing
/// to get an instance of the specified type, but failed to do so.
object TryGetInstance(Type type);
+ ///
+ /// Gets all instances of a service.
+ ///
+ /// The type of the service.
+ IEnumerable