Merge pull request #4059 from umbraco/temp8-fs
Cleanup Filesystems registrations
This commit is contained in:
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Components
|
||||
public class Composition : IRegister
|
||||
{
|
||||
private readonly Dictionary<Type, ICollectionBuilder> _builders = new Dictionary<Type, ICollectionBuilder>();
|
||||
private readonly Dictionary<Type, Unique> _uniques = new Dictionary<Type, Unique>();
|
||||
private readonly Dictionary<string, Action<IRegister>> _uniques = new Dictionary<string, Action<IRegister>>();
|
||||
private readonly IRegister _register;
|
||||
|
||||
/// <summary>
|
||||
@@ -83,11 +83,32 @@ namespace Umbraco.Core.Components
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Register<TService>(Func<IFactory, TService> factory, Lifetime lifetime = Lifetime.Transient)
|
||||
where TService : class
|
||||
=> _register.Register(factory, lifetime);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RegisterInstance(Type serviceType, object instance)
|
||||
=> _register.RegisterInstance(serviceType, instance);
|
||||
public void Register(Type serviceType, object instance)
|
||||
=> _register.Register(serviceType, instance);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RegisterFor<TService, TTarget>(Lifetime lifetime = Lifetime.Transient)
|
||||
where TService : class
|
||||
=> _register.RegisterFor<TService, TTarget>(lifetime);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RegisterFor<TService, TTarget>(Type implementingType, Lifetime lifetime = Lifetime.Transient)
|
||||
where TService : class
|
||||
=> _register.RegisterFor<TService, TTarget>(implementingType, lifetime);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RegisterFor<TService, TTarget>(Func<IFactory, TService> factory, Lifetime lifetime = Lifetime.Transient)
|
||||
where TService : class
|
||||
=> _register.RegisterFor<TService, TTarget>(factory, lifetime);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RegisterFor<TService, TTarget>(TService instance)
|
||||
where TService : class
|
||||
=> _register.RegisterFor<TService, TTarget>(instance);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RegisterAuto(Type serviceBaseType)
|
||||
@@ -104,10 +125,12 @@ namespace Umbraco.Core.Components
|
||||
onCreating();
|
||||
|
||||
foreach (var unique in _uniques.Values)
|
||||
unique.RegisterWith(_register);
|
||||
unique(_register);
|
||||
_uniques.Clear(); // no point keep them around
|
||||
|
||||
foreach (var builder in _builders.Values)
|
||||
builder.RegisterWith(_register);
|
||||
_builders.Clear(); // no point keep them around
|
||||
|
||||
Configs.RegisterWith(_register);
|
||||
|
||||
@@ -123,74 +146,78 @@ namespace Umbraco.Core.Components
|
||||
|
||||
#region Unique
|
||||
|
||||
private string GetUniqueName<TService>()
|
||||
=> GetUniqueName(typeof(TService));
|
||||
|
||||
private string GetUniqueName(Type serviceType)
|
||||
=> serviceType.FullName;
|
||||
|
||||
private string GetUniqueName<TService, TTarget>()
|
||||
=> GetUniqueName(typeof(TService), typeof(TTarget));
|
||||
|
||||
private string GetUniqueName(Type serviceType, Type targetType)
|
||||
=> serviceType.FullName + "::" + targetType.FullName;
|
||||
|
||||
/// <summary>
|
||||
/// Registers a unique service.
|
||||
/// Registers a unique service as its own implementation.
|
||||
/// </summary>
|
||||
/// <remarks>Unique services have one single implementation, and a Singleton lifetime.</remarks>
|
||||
public void RegisterUnique(Type serviceType)
|
||||
=> _uniques[GetUniqueName(serviceType)] = register => register.Register(serviceType, Lifetime.Singleton);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a unique service with an implementation type.
|
||||
/// </summary>
|
||||
/// <remarks>Unique services have one single implementation, and a Singleton lifetime.</remarks>
|
||||
public void RegisterUnique(Type serviceType, Type implementingType)
|
||||
=> _uniques[serviceType] = new Unique(serviceType, implementingType);
|
||||
=> _uniques[GetUniqueName(serviceType)] = register => register.Register(serviceType, implementingType, Lifetime.Singleton);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a unique service.
|
||||
/// </summary>
|
||||
/// <remarks>Unique services have one single implementation, and a Singleton lifetime.</remarks>
|
||||
public void RegisterUnique(Type serviceType, object instance)
|
||||
=> _uniques[serviceType] = new Unique(serviceType, instance);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a unique service.
|
||||
/// Registers a unique service with an implementation factory.
|
||||
/// </summary>
|
||||
/// <remarks>Unique services have one single implementation, and a Singleton lifetime.</remarks>
|
||||
public void RegisterUnique<TService>(Func<IFactory, TService> factory)
|
||||
=> _uniques[typeof(TService)] = new Unique<TService>(factory);
|
||||
where TService : class
|
||||
=> _uniques[GetUniqueName<TService>()] = register => register.Register<TService>(factory, Lifetime.Singleton);
|
||||
|
||||
private class Unique
|
||||
{
|
||||
private readonly Type _serviceType;
|
||||
private readonly Type _implementingType;
|
||||
private readonly object _instance;
|
||||
/// <summary>
|
||||
/// Registers a unique service with an implementing instance.
|
||||
/// </summary>
|
||||
/// <remarks>Unique services have one single implementation, and a Singleton lifetime.</remarks>
|
||||
public void RegisterUnique(Type serviceType, object instance)
|
||||
=> _uniques[GetUniqueName(serviceType)] = register => register.Register(serviceType, instance);
|
||||
|
||||
protected Unique(Type serviceType)
|
||||
{
|
||||
_serviceType = serviceType;
|
||||
}
|
||||
/// <summary>
|
||||
/// Registers a unique service for a target, as its own implementation.
|
||||
/// </summary>
|
||||
/// <remarks>Unique services have one single implementation, and a Singleton lifetime.</remarks>
|
||||
public void RegisterUniqueFor<TService, TTarget>()
|
||||
where TService : class
|
||||
=> _uniques[GetUniqueName<TService, TTarget>()] = register => register.RegisterFor<TService, TTarget>(Lifetime.Singleton);
|
||||
|
||||
public Unique(Type serviceType, Type implementingType)
|
||||
: this(serviceType)
|
||||
{
|
||||
_implementingType = implementingType;
|
||||
}
|
||||
/// <summary>
|
||||
/// Registers a unique service for a target, with an implementing type.
|
||||
/// </summary>
|
||||
/// <remarks>Unique services have one single implementation, and a Singleton lifetime.</remarks>
|
||||
public void RegisterUniqueFor<TService, TTarget>(Type implementingType)
|
||||
where TService : class
|
||||
=> _uniques[GetUniqueName<TService, TTarget>()] = register => register.RegisterFor<TService, TTarget>(implementingType, Lifetime.Singleton);
|
||||
|
||||
public Unique(Type serviceType, object instance)
|
||||
: this(serviceType)
|
||||
{
|
||||
_instance = instance;
|
||||
}
|
||||
/// <summary>
|
||||
/// Registers a unique service for a target, with an implementation factory.
|
||||
/// </summary>
|
||||
/// <remarks>Unique services have one single implementation, and a Singleton lifetime.</remarks>
|
||||
public void RegisterUniqueFor<TService, TTarget>(Func<IFactory, TService> factory)
|
||||
where TService : class
|
||||
=> _uniques[GetUniqueName<TService, TTarget>()] = register => register.RegisterFor<TService, TTarget>(factory, Lifetime.Singleton);
|
||||
|
||||
public virtual void RegisterWith(IRegister register)
|
||||
{
|
||||
if (_implementingType != null)
|
||||
register.Register(_serviceType, _implementingType, Lifetime.Singleton);
|
||||
else if (_instance != null)
|
||||
register.RegisterInstance(_serviceType, _instance);
|
||||
}
|
||||
}
|
||||
|
||||
private class Unique<TService> : Unique
|
||||
{
|
||||
private readonly Func<IFactory, TService> _factory;
|
||||
|
||||
public Unique(Func<IFactory, TService> factory)
|
||||
: base(typeof(TService))
|
||||
{
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
public override void RegisterWith(IRegister register)
|
||||
{
|
||||
register.Register(_factory, Lifetime.Singleton);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Registers a unique service for a target, with an implementing instance.
|
||||
/// </summary>
|
||||
/// <remarks>Unique services have one single implementation, and a Singleton lifetime.</remarks>
|
||||
public void RegisterUniqueFor<TService, TTarget>(TService instance)
|
||||
where TService : class
|
||||
=> _uniques[GetUniqueName<TService, TTarget>()] = register => register.RegisterFor<TService, TTarget>(instance);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -26,15 +26,16 @@ namespace Umbraco.Core.Components
|
||||
/// <typeparam name="TFileSystem">The type of the filesystem.</typeparam>
|
||||
/// <typeparam name="TImplementing">The implementing type.</typeparam>
|
||||
/// <param name="composition">The composition.</param>
|
||||
/// <param name="supportingFileSystemFactory">A factory method creating the supporting filesystem.</param>
|
||||
/// <returns>The register.</returns>
|
||||
public static void RegisterFileSystem<TFileSystem, TImplementing>(this Composition composition, Func<IFactory, IFileSystem> supportingFileSystemFactory)
|
||||
public static void RegisterFileSystem<TFileSystem, TImplementing>(this Composition composition)
|
||||
where TImplementing : FileSystemWrapper, TFileSystem
|
||||
where TFileSystem : class
|
||||
{
|
||||
composition.RegisterUnique<TFileSystem>(factory =>
|
||||
{
|
||||
var fileSystems = factory.GetInstance<FileSystems>();
|
||||
return fileSystems.GetFileSystem<TImplementing>(supportingFileSystemFactory(factory));
|
||||
var supporting = factory.GetInstance<SupportingFileSystems>();
|
||||
return fileSystems.GetFileSystem<TImplementing>(supporting.For<TFileSystem>());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -43,15 +44,15 @@ namespace Umbraco.Core.Components
|
||||
/// </summary>
|
||||
/// <typeparam name="TFileSystem">The type of the filesystem.</typeparam>
|
||||
/// <param name="composition">The composition.</param>
|
||||
/// <param name="supportingFileSystemFactory">A factory method creating the supporting filesystem.</param>
|
||||
/// <returns>The register.</returns>
|
||||
public static void RegisterFileSystem<TFileSystem>(this Composition composition, Func<IFactory, IFileSystem> supportingFileSystemFactory)
|
||||
public static void RegisterFileSystem<TFileSystem>(this Composition composition)
|
||||
where TFileSystem : FileSystemWrapper
|
||||
{
|
||||
composition.RegisterUnique(factory =>
|
||||
{
|
||||
var fileSystems = factory.GetInstance<FileSystems>();
|
||||
return fileSystems.GetFileSystem<TFileSystem>(supportingFileSystemFactory(factory));
|
||||
var supporting = factory.GetInstance<SupportingFileSystems>();
|
||||
return fileSystems.GetFileSystem<TFileSystem>(supporting.For<TFileSystem>());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -280,6 +281,22 @@ namespace Umbraco.Core.Components
|
||||
composition.RegisterUnique(_ => helper);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the underlying media filesystem.
|
||||
/// </summary>
|
||||
/// <param name="composition">A composition.</param>
|
||||
/// <param name="filesystemFactory">A filesystem factory.</param>
|
||||
public static void SetMediaFileSystem(this Composition composition, Func<IFactory, IFileSystem> filesystemFactory)
|
||||
=> composition.RegisterUniqueFor<IFileSystem, IMediaFileSystem>(filesystemFactory);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the underlying media filesystem.
|
||||
/// </summary>
|
||||
/// <param name="composition">A composition.</param>
|
||||
/// <param name="filesystemFactory">A filesystem factory.</param>
|
||||
public static void SetMediaFileSystem(this Composition composition, Func<IFileSystem> filesystemFactory)
|
||||
=> composition.RegisterUniqueFor<IFileSystem, IMediaFileSystem>(_ => filesystemFactory());
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Composing
|
||||
/// <typeparam name="TItem">The type of the items.</typeparam>
|
||||
public abstract class CollectionBuilderBase<TBuilder, TCollection, TItem> : ICollectionBuilder<TCollection, TItem>
|
||||
where TBuilder: CollectionBuilderBase<TBuilder, TCollection, TItem>
|
||||
where TCollection : IBuilderCollection<TItem>
|
||||
where TCollection : class, IBuilderCollection<TItem>
|
||||
{
|
||||
private readonly List<Type> _types = new List<Type>();
|
||||
private readonly object _locker = new object();
|
||||
|
||||
@@ -12,10 +12,9 @@ namespace Umbraco.Core.Composing.Composers
|
||||
*
|
||||
* Create a component and use it to modify the composition by adding something like:
|
||||
*
|
||||
* composition.Container.RegisterFileSystem<IMediaFileSystem, MediaFileSystem>(
|
||||
* factory => new PhysicalFileSystem("~/somewhere"));
|
||||
* composition.RegisterUniqueFor<IFileSystem, IMediaFileSystem>(...);
|
||||
*
|
||||
* return whatever supporting filesystem you like.
|
||||
* and register whatever supporting filesystem you like.
|
||||
*
|
||||
*
|
||||
* HOW TO IMPLEMENT MY OWN FILESYSTEM
|
||||
@@ -30,12 +29,15 @@ namespace Umbraco.Core.Composing.Composers
|
||||
* { }
|
||||
* }
|
||||
*
|
||||
* The ctor can have more parameters that will be resolved by the container.
|
||||
* The ctor can have more parameters, that will be resolved by the container.
|
||||
*
|
||||
* Register your filesystem, in a component:
|
||||
*
|
||||
* composition.Container.RegisterFileSystem<MyFileSystem>(
|
||||
* factory => new PhysicalFileSystem("~/my"));
|
||||
* composition.RegisterFileSystem<MyFileSystem>();
|
||||
*
|
||||
* Register the underlying filesystem:
|
||||
*
|
||||
* composition.RegisterUniqueFor<IFileSystem, MyFileSystem>(...);
|
||||
*
|
||||
* And that's it, you can inject MyFileSystem wherever it's needed.
|
||||
*
|
||||
@@ -48,8 +50,8 @@ namespace Umbraco.Core.Composing.Composers
|
||||
* Make the class implement the interface, then
|
||||
* register your filesystem, in a component:
|
||||
*
|
||||
* composition.Container.RegisterFileSystem<IMyFileSystem, MyFileSystem>(
|
||||
* factory => new PhysicalFileSystem("~/my"));
|
||||
* composition.RegisterFileSystem<IMyFileSystem, MyFileSystem>();
|
||||
* composition.RegisterUniqueFor<IFileSystem, IMyFileSystem>(...);
|
||||
*
|
||||
* And that's it, you can inject IMyFileSystem wherever it's needed.
|
||||
*
|
||||
@@ -79,9 +81,16 @@ namespace Umbraco.Core.Composing.Composers
|
||||
// register the scheme for media paths
|
||||
composition.RegisterUnique<IMediaPathScheme, TwoGuidsMediaPathScheme>();
|
||||
|
||||
// register the IMediaFileSystem implementation with a supporting filesystem
|
||||
composition.RegisterFileSystem<IMediaFileSystem, MediaFileSystem>(
|
||||
factory => new PhysicalFileSystem("~/media"));
|
||||
// register the IMediaFileSystem implementation
|
||||
composition.RegisterFileSystem<IMediaFileSystem, MediaFileSystem>();
|
||||
|
||||
// register the supporting filesystems provider
|
||||
composition.Register(factory => new SupportingFileSystems(factory), Lifetime.Singleton);
|
||||
|
||||
// register the IFileSystem supporting the IMediaFileSystem
|
||||
// THIS IS THE ONLY THING THAT NEEDS TO CHANGE, IN ORDER TO REPLACE THE UNDERLYING FILESYSTEM
|
||||
// and, SupportingFileSystem.For<IMediaFileSystem>() returns the underlying filesystem
|
||||
composition.SetMediaFileSystem(() => new PhysicalFileSystem("~/media"));
|
||||
|
||||
return composition;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,13 @@ namespace Umbraco.Core.Composing
|
||||
public static void RegisterUnique<TService, TImplementing>(this Composition composition)
|
||||
=> composition.RegisterUnique(typeof(TService), typeof(TImplementing));
|
||||
|
||||
/// <summary>
|
||||
/// Registers a unique service with an implementation type, for a target.
|
||||
/// </summary>
|
||||
public static void RegisterUniqueFor<TService, TTarget, TImplementing>(this Composition composition)
|
||||
where TService : class
|
||||
=> composition.RegisterUniqueFor<TService, TTarget>(typeof(TImplementing));
|
||||
|
||||
/// <summary>
|
||||
/// Registers a unique service with an implementing instance.
|
||||
/// </summary>
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace Umbraco.Core.Composing
|
||||
/// <returns>An instance of the specified type.</returns>
|
||||
/// <remarks>Throws an exception if the factory failed to get an instance of the specified type.</remarks>
|
||||
public static T GetInstance<T>(this IFactory factory)
|
||||
where T : class
|
||||
=> (T)factory.GetInstance(typeof(T));
|
||||
|
||||
/// <summary>
|
||||
@@ -28,6 +29,7 @@ namespace Umbraco.Core.Composing
|
||||
/// of the specified type. Throws an exception if the factory does know how
|
||||
/// to get an instance of the specified type, but failed to do so.</remarks>
|
||||
public static T TryGetInstance<T>(this IFactory factory)
|
||||
where T : class
|
||||
=> (T)factory.TryGetInstance(typeof(T));
|
||||
|
||||
/// <summary>
|
||||
@@ -42,6 +44,7 @@ namespace Umbraco.Core.Composing
|
||||
/// <para>The arguments are used as dependencies by the factory.</para>
|
||||
/// </remarks>
|
||||
public static T CreateInstance<T>(this IFactory factory, params object[] args)
|
||||
where T : class
|
||||
=> (T)factory.CreateInstance(typeof(T), args);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -3,13 +3,6 @@ using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
// Implementing:
|
||||
//
|
||||
// The factory
|
||||
// - always picks the constructor with the most parameters
|
||||
// - supports Lazy parameters (and prefers them over non-Lazy) in constructors
|
||||
// - what happens with 'releasing' is unclear
|
||||
|
||||
/// <summary>
|
||||
/// Defines a service factory for Umbraco.
|
||||
/// </summary>
|
||||
@@ -28,6 +21,15 @@ namespace Umbraco.Core.Composing
|
||||
/// <remarks>Throws an exception if the container failed to get an instance of the specified type.</remarks>
|
||||
object GetInstance(Type type);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a targeted instance of a service.
|
||||
/// </summary>
|
||||
/// <typeparam name="TService">The type of the service.</typeparam>
|
||||
/// <typeparam name="TTarget">The type of the target.</typeparam>
|
||||
/// <returns>The instance of the specified type for the specified target.</returns>
|
||||
/// <remarks>Throws an exception if the container failed to get an instance of the specified type.</remarks>
|
||||
TService GetInstanceFor<TService, TTarget>();
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get an instance of a service.
|
||||
/// </summary>
|
||||
@@ -48,7 +50,8 @@ namespace Umbraco.Core.Composing
|
||||
/// Gets all instances of a service.
|
||||
/// </summary>
|
||||
/// <typeparam name="TService">The type of the service.</typeparam>
|
||||
IEnumerable<TService> GetAllInstances<TService>();
|
||||
IEnumerable<TService> GetAllInstances<TService>()
|
||||
where TService : class;
|
||||
|
||||
/// <summary>
|
||||
/// Releases an instance.
|
||||
|
||||
@@ -2,17 +2,6 @@
|
||||
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
// Implementing:
|
||||
//
|
||||
// The register
|
||||
// - supports registering a service, even after some instances of other services have been created
|
||||
// - supports re-registering a service, as long as no instance of that service has been created
|
||||
// - throws when re-registering a service, and an instance of that service has been created
|
||||
//
|
||||
// - registers only one implementation of a nameless service, re-registering replaces the previous
|
||||
// registration - names are required to register multiple implementations - and getting an
|
||||
// IEnumerable of the service, nameless, returns them all
|
||||
|
||||
/// <summary>
|
||||
/// Defines a service register for Umbraco.
|
||||
/// </summary>
|
||||
@@ -36,12 +25,53 @@ namespace Umbraco.Core.Composing
|
||||
/// <summary>
|
||||
/// Registers a service with an implementation factory.
|
||||
/// </summary>
|
||||
void Register<TService>(Func<IFactory, TService> factory, Lifetime lifetime = Lifetime.Transient);
|
||||
void Register<TService>(Func<IFactory, TService> factory, Lifetime lifetime = Lifetime.Transient)
|
||||
where TService : class;
|
||||
|
||||
/// <summary>
|
||||
/// Registers a service with an implementing instance.
|
||||
/// </summary>
|
||||
void RegisterInstance(Type serviceType, object instance);
|
||||
void Register(Type serviceType, object instance);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a service for a target, as its own implementation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// There can only be one implementation or instanced registered for a service and target;
|
||||
/// what happens if many are registered is not specified.
|
||||
/// </remarks>
|
||||
void RegisterFor<TService, TTarget>(Lifetime lifetime = Lifetime.Transient)
|
||||
where TService : class;
|
||||
|
||||
/// <summary>
|
||||
/// Registers a service for a target, with an implementation type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// There can only be one implementation or instanced registered for a service and target;
|
||||
/// what happens if many are registered is not specified.
|
||||
/// </remarks>
|
||||
void RegisterFor<TService, TTarget>(Type implementingType, Lifetime lifetime = Lifetime.Transient)
|
||||
where TService : class;
|
||||
|
||||
/// <summary>
|
||||
/// Registers a service for a target, with an implementation factory.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// There can only be one implementation or instanced registered for a service and target;
|
||||
/// what happens if many are registered is not specified.
|
||||
/// </remarks>
|
||||
void RegisterFor<TService, TTarget>(Func<IFactory, TService> factory, Lifetime lifetime = Lifetime.Transient)
|
||||
where TService : class;
|
||||
|
||||
/// <summary>
|
||||
/// Registers a service for a target, with an implementing instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// There can only be one implementation or instanced registered for a service and target;
|
||||
/// what happens if many are registered is not specified.
|
||||
/// </remarks>
|
||||
void RegisterFor<TService, TTarget>(TService instance)
|
||||
where TService : class;
|
||||
|
||||
/// <summary>
|
||||
/// Registers a base type for auto-registration.
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Composing
|
||||
/// <typeparam name="TItem">The type of the items.</typeparam>
|
||||
public abstract class LazyCollectionBuilderBase<TBuilder, TCollection, TItem> : CollectionBuilderBase<TBuilder, TCollection, TItem>
|
||||
where TBuilder : LazyCollectionBuilderBase<TBuilder, TCollection, TItem>
|
||||
where TCollection : IBuilderCollection<TItem>
|
||||
where TCollection : class, IBuilderCollection<TItem>
|
||||
{
|
||||
private readonly List<Func<IEnumerable<Type>>> _producers = new List<Func<IEnumerable<Type>>>();
|
||||
private readonly List<Type> _excluded = new List<Type>();
|
||||
|
||||
@@ -102,18 +102,25 @@ namespace Umbraco.Core.Composing.LightInject
|
||||
/// <inheritdoc />
|
||||
public IFactory CreateFactory() => this;
|
||||
|
||||
private static string GetTargetedServiceName<TTarget>() => "TARGET:" + typeof(TTarget).FullName;
|
||||
|
||||
#region Factory
|
||||
|
||||
/// <inheritdoc />
|
||||
public object GetInstance(Type type)
|
||||
=> Container.GetInstance(type);
|
||||
|
||||
/// <inheritdoc />
|
||||
public TService GetInstanceFor<TService, TTarget>()
|
||||
=> Container.GetInstance<TService>(GetTargetedServiceName<TTarget>());
|
||||
|
||||
/// <inheritdoc />
|
||||
public object TryGetInstance(Type type)
|
||||
=> Container.TryGetInstance(type);
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<T> GetAllInstances<T>()
|
||||
where T : class
|
||||
=> Container.GetAllInstances<T>();
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -138,21 +145,7 @@ namespace Umbraco.Core.Composing.LightInject
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Register(Type serviceType, Lifetime lifetime = Lifetime.Transient)
|
||||
{
|
||||
switch (lifetime)
|
||||
{
|
||||
case Lifetime.Transient:
|
||||
Container.Register(serviceType);
|
||||
break;
|
||||
case Lifetime.Request:
|
||||
case Lifetime.Scope:
|
||||
case Lifetime.Singleton:
|
||||
Container.Register(serviceType, GetLifetime(lifetime));
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException($"Lifetime {lifetime} is not supported.");
|
||||
}
|
||||
}
|
||||
=> Container.Register(serviceType, GetLifetime(lifetime));
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Register(Type serviceType, Type implementingType, Lifetime lifetime = Lifetime.Transient)
|
||||
@@ -174,22 +167,41 @@ namespace Umbraco.Core.Composing.LightInject
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Register<TService>(Func<IFactory, TService> factory, Lifetime lifetime = Lifetime.Transient)
|
||||
where TService : class
|
||||
{
|
||||
switch (lifetime)
|
||||
{
|
||||
case Lifetime.Transient:
|
||||
Container.Register(f => factory(this));
|
||||
break;
|
||||
case Lifetime.Request:
|
||||
case Lifetime.Scope:
|
||||
case Lifetime.Singleton:
|
||||
Container.Register(f => factory(this), GetLifetime(lifetime));
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException($"Lifetime {lifetime} is not supported.");
|
||||
}
|
||||
Container.Register(f => factory(this), GetLifetime(lifetime));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Register(Type serviceType, object instance)
|
||||
=> Container.RegisterInstance(serviceType, instance);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RegisterFor<TService, TTarget>(Lifetime lifetime = Lifetime.Transient)
|
||||
where TService : class
|
||||
=> RegisterFor<TService, TTarget>(typeof(TService), lifetime);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RegisterFor<TService, TTarget>(Type implementingType, Lifetime lifetime = Lifetime.Transient)
|
||||
where TService : class
|
||||
{
|
||||
// note that there can only be one implementation or instance registered "for" a service
|
||||
Container.Register(typeof(TService), implementingType, GetTargetedServiceName<TTarget>(), GetLifetime(lifetime));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RegisterFor<TService, TTarget>(Func<IFactory, TService> factory, Lifetime lifetime = Lifetime.Transient)
|
||||
where TService : class
|
||||
{
|
||||
// note that there can only be one implementation or instance registered "for" a service
|
||||
Container.Register(f => factory(this), GetTargetedServiceName<TTarget>(), GetLifetime(lifetime));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RegisterFor<TService, TTarget>(TService instance)
|
||||
where TService : class
|
||||
=> Container.RegisterInstance(typeof(TService), instance, GetTargetedServiceName<TTarget>());
|
||||
|
||||
private ILifetime GetLifetime(Lifetime lifetime)
|
||||
{
|
||||
switch (lifetime)
|
||||
@@ -207,10 +219,6 @@ namespace Umbraco.Core.Composing.LightInject
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RegisterInstance(Type serviceType, object instance)
|
||||
=> Container.RegisterInstance(serviceType, instance);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RegisterAuto(Type serviceBaseType)
|
||||
{
|
||||
@@ -223,17 +231,6 @@ namespace Umbraco.Core.Composing.LightInject
|
||||
}, null);
|
||||
}
|
||||
|
||||
// was the Light-Inject specific way of dealing with args, but we've replaced it with our own
|
||||
// beware! does NOT work on singletons, see https://github.com/seesharper/LightInject/issues/294
|
||||
//
|
||||
///// <inheritdoc />
|
||||
//public void RegisterConstructorDependency<TDependency>(Func<IContainer, ParameterInfo, TDependency> factory)
|
||||
// => Container.RegisterConstructorDependency((f, x) => factory(this, x));
|
||||
//
|
||||
///// <inheritdoc />
|
||||
//public void RegisterConstructorDependency<TDependency>(Func<IContainer, ParameterInfo, object[], TDependency> factory)
|
||||
// => Container.RegisterConstructorDependency((f, x, a) => factory(this, x, a));
|
||||
|
||||
#endregion
|
||||
|
||||
#region Control
|
||||
@@ -256,21 +253,14 @@ namespace Umbraco.Core.Composing.LightInject
|
||||
|
||||
private class AssemblyScanner : IAssemblyScanner
|
||||
{
|
||||
//private readonly IAssemblyScanner _scanner;
|
||||
|
||||
//public AssemblyScanner(IAssemblyScanner scanner)
|
||||
//{
|
||||
// _scanner = scanner;
|
||||
//}
|
||||
|
||||
public void Scan(Assembly assembly, IServiceRegistry serviceRegistry, Func<ILifetime> lifetime, Func<Type, Type, bool> shouldRegister, Func<Type, Type, string> serviceNameProvider)
|
||||
{
|
||||
// nothing - we *could* scan non-Umbraco assemblies, though
|
||||
// nothing - we don't want LightInject to scan
|
||||
}
|
||||
|
||||
public void Scan(Assembly assembly, IServiceRegistry serviceRegistry)
|
||||
{
|
||||
// nothing - we *could* scan non-Umbraco assemblies, though
|
||||
// nothing - we don't want LightInject to scan
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@ namespace Umbraco.Core.Composing.LightInject
|
||||
// of PerWebRequestScopeManagerProvider - but all delegates see is the mixed one - and therefore
|
||||
// they can transition without issues.
|
||||
//
|
||||
// The PerWebRequestScopeManager maintains the scope in HttpContext and LightInject registers a
|
||||
// module (PreApplicationStartMethod) which disposes it on EndRequest
|
||||
//
|
||||
// the mixed provider is installed in container.ConfigureUmbracoCore() and then,
|
||||
// when doing eg container.EnableMvc() or anything that does container.EnablePerWebRequestScope()
|
||||
// we need to take great care to preserve the mixed scope manager provider!
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Umbraco.Core.Composing
|
||||
/// <typeparam name="TItem">The type of the items.</typeparam>
|
||||
public abstract class OrderedCollectionBuilderBase<TBuilder, TCollection, TItem> : CollectionBuilderBase<TBuilder, TCollection, TItem>
|
||||
where TBuilder : OrderedCollectionBuilderBase<TBuilder, TCollection, TItem>
|
||||
where TCollection : IBuilderCollection<TItem>
|
||||
where TCollection : class, IBuilderCollection<TItem>
|
||||
{
|
||||
protected abstract TBuilder This { get; }
|
||||
|
||||
|
||||
@@ -11,22 +11,32 @@
|
||||
public static void Register<TService, TImplementing>(this IRegister register, Lifetime lifetime = Lifetime.Transient)
|
||||
=> register.Register(typeof(TService), typeof(TImplementing), lifetime);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a service with an implementation type, for a target.
|
||||
/// </summary>
|
||||
public static void RegisterFor<TService, TImplementing, TTarget>(this IRegister register, Lifetime lifetime = Lifetime.Transient)
|
||||
where TService : class
|
||||
=> register.RegisterFor<TService, TTarget>(typeof(TImplementing), lifetime);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a service as its own implementation.
|
||||
/// </summary>
|
||||
public static void Register<TService>(this IRegister register, Lifetime lifetime = Lifetime.Transient)
|
||||
where TService : class
|
||||
=> register.Register(typeof(TService), lifetime);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a service with an implementing instance.
|
||||
/// </summary>
|
||||
public static void RegisterInstance<TService>(this IRegister register, TService instance)
|
||||
=> register.RegisterInstance(typeof(TService), instance);
|
||||
public static void Register<TService>(this IRegister register, TService instance)
|
||||
where TService : class
|
||||
=> register.Register(typeof(TService), instance);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a base type for auto-registration.
|
||||
/// </summary>
|
||||
public static void RegisterAuto<TServiceBase>(this IRegister register)
|
||||
where TServiceBase : class
|
||||
=> register.RegisterAuto(typeof(TServiceBase));
|
||||
}
|
||||
}
|
||||
|
||||
18
src/Umbraco.Core/Composing/TargetedServiceFactory.cs
Normal file
18
src/Umbraco.Core/Composing/TargetedServiceFactory.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a base class for targeted service factories.
|
||||
/// </summary>
|
||||
/// <typeparam name="TService"></typeparam>
|
||||
public abstract class TargetedServiceFactory<TService>
|
||||
{
|
||||
private readonly IFactory _factory;
|
||||
|
||||
protected TargetedServiceFactory(IFactory factory)
|
||||
{
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
public TService For<TTarget>() => _factory.GetInstanceFor<TService, TTarget>();
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Composing
|
||||
/// <typeparam name="TItem">The type of the items.</typeparam>
|
||||
public abstract class WeightedCollectionBuilderBase<TBuilder, TCollection, TItem> : CollectionBuilderBase<TBuilder, TCollection, TItem>
|
||||
where TBuilder : WeightedCollectionBuilderBase<TBuilder, TCollection, TItem>
|
||||
where TCollection : IBuilderCollection<TItem>
|
||||
where TCollection : class, IBuilderCollection<TItem>
|
||||
{
|
||||
protected abstract TBuilder This { get; }
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace Umbraco.Core.Configuration
|
||||
if (_registerings == null)
|
||||
throw new InvalidOperationException("Configurations have already been registered.");
|
||||
|
||||
register.RegisterInstance(this);
|
||||
register.Register(this);
|
||||
|
||||
foreach (var registering in _registerings.Values)
|
||||
registering(register);
|
||||
|
||||
11
src/Umbraco.Core/IO/SupportingFileSystems.cs
Normal file
11
src/Umbraco.Core/IO/SupportingFileSystems.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
public class SupportingFileSystems : TargetedServiceFactory<IFileSystem>
|
||||
{
|
||||
public SupportingFileSystems(IFactory factory)
|
||||
: base(factory)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -196,6 +196,7 @@
|
||||
<Compile Include="Composing\LightInject\LightInjectContainer.cs" />
|
||||
<Compile Include="Composing\LightInject\MixedLightInjectScopeManagerProvider.cs" />
|
||||
<Compile Include="Composing\OrderedCollectionBuilderBase.cs" />
|
||||
<Compile Include="Composing\TargetedServiceFactory.cs" />
|
||||
<Compile Include="Composing\TypeFinder.cs" />
|
||||
<Compile Include="Composing\TypeHelper.cs" />
|
||||
<Compile Include="Composing\TypeLoader.cs" />
|
||||
@@ -343,6 +344,7 @@
|
||||
<Compile Include="IO\IMediaPathScheme.cs" />
|
||||
<Compile Include="IO\MediaPathSchemes\OriginalMediaPathScheme.cs" />
|
||||
<Compile Include="IO\MediaPathSchemes\TwoGuidsMediaPathScheme.cs" />
|
||||
<Compile Include="IO\SupportingFileSystems.cs" />
|
||||
<Compile Include="KeyValuePairExtensions.cs" />
|
||||
<Compile Include="Logging\IProfilingLogger.cs" />
|
||||
<Compile Include="Logging\LogHttpRequest.cs" />
|
||||
|
||||
@@ -194,8 +194,8 @@ namespace Umbraco.Tests.Composing
|
||||
var register = GetRegister();
|
||||
|
||||
// define two instances
|
||||
register.RegisterInstance(typeof(Thing1), new Thing1());
|
||||
register.RegisterInstance(typeof(Thing1), new Thing2());
|
||||
register.Register(typeof(Thing1), new Thing1());
|
||||
register.Register(typeof(Thing1), new Thing2());
|
||||
|
||||
var factory = register.CreateFactory();
|
||||
|
||||
@@ -212,8 +212,8 @@ namespace Umbraco.Tests.Composing
|
||||
var register = GetRegister();
|
||||
|
||||
// define two instances
|
||||
register.RegisterInstance(typeof(IThing), new Thing1());
|
||||
register.RegisterInstance(typeof(IThing), new Thing2());
|
||||
register.Register(typeof(IThing), new Thing1());
|
||||
register.Register(typeof(IThing), new Thing2());
|
||||
|
||||
var factory = register.CreateFactory();
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Web;
|
||||
using System.Web;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Exceptions;
|
||||
@@ -11,7 +10,7 @@ namespace Umbraco.Web.Composing
|
||||
/// </summary>
|
||||
/// <typeparam name="TModule">The type of the injected module.</typeparam>
|
||||
public abstract class ModuleInjector<TModule> : IHttpModule
|
||||
where TModule : IHttpModule
|
||||
where TModule : class, IHttpModule
|
||||
{
|
||||
protected TModule Module { get; private set; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user