IContainer is IRegister+IFactory

This commit is contained in:
Stephan
2018-11-28 11:05:41 +01:00
parent f290065bb6
commit 49a0b68b28
103 changed files with 814 additions and 3843 deletions

View File

@@ -41,6 +41,7 @@ namespace Umbraco.Core.Components
public int Weight = -1;
}
public void Compose()
{
var orderedComponentTypes = PrepareComponentTypes();
@@ -49,11 +50,11 @@ namespace Umbraco.Core.Components
ComposeComponents();
}
public void Initialize()
public void Initialize(IFactory factory)
{
using (var scope = _composition.Container.GetInstance<IScopeProvider>().CreateScope())
using (var scope = factory.GetInstance<IScopeProvider>().CreateScope())
{
InitializeComponents();
InitializeComponents(factory);
scope.Complete();
}
}
@@ -303,12 +304,12 @@ namespace Umbraco.Core.Components
}
}
private void InitializeComponents()
private void InitializeComponents(IFactory factory)
{
// use a container scope to ensure that PerScope instances are disposed
// components that require instances that should not survive should register them with PerScope lifetime
using (_logger.DebugDuration<Components>($"Initializing components. (log when >{LogThresholdMilliseconds}ms)", "Initialized components."))
using (_composition.Container.BeginScope())
using (factory.BeginScope())
{
foreach (var component in _components)
{
@@ -320,7 +321,7 @@ namespace Umbraco.Core.Components
foreach (var initializer in initializers)
{
var parameters = initializer.GetParameters()
.Select(x => GetParameter(componentType, x.ParameterType))
.Select(x => GetParameter(factory, componentType, x.ParameterType))
.ToArray();
initializer.Invoke(component, parameters);
}
@@ -329,13 +330,13 @@ namespace Umbraco.Core.Components
}
}
private object GetParameter(Type componentType, Type parameterType)
private object GetParameter(IFactory factory, Type componentType, Type parameterType)
{
object param;
try
{
param = _composition.Container.TryGetInstance(parameterType);
param = factory.TryGetInstance(parameterType);
}
catch (Exception e)
{

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Components
{
@@ -12,35 +13,32 @@ namespace Umbraco.Core.Components
/// avoid accessing the container. This is because everything needs to be properly registered and with
/// the proper lifecycle. These methods will take care of it. Directly registering into the container
/// may cause issues.</remarks>
public class Composition
public class Composition : IRegister
{
private readonly Dictionary<Type, ICollectionBuilder> _builders = new Dictionary<Type, ICollectionBuilder>();
private readonly IRegister _register;
/// <summary>
/// Initializes a new instance of the <see cref="Composition"/> class.
/// </summary>
/// <param name="container">A container.</param>
/// <param name="typeLoader">The type loader.</param>
/// <param name="register">A register.</param>
/// <param name="typeLoader">A type loader.</param>
/// <param name="logger">A logger.</param>
/// <param name="level">The runtime level.</param>
public Composition(IContainer container, TypeLoader typeLoader, RuntimeLevel level)
public Composition(IRegister register, TypeLoader typeLoader, IProfilingLogger logger, RuntimeLevel level)
{
Container = container;
_register = register;
TypeLoader = typeLoader;
Logger = logger;
RuntimeLevel = level;
}
// used for tests
internal Composition(IContainer container, RuntimeLevel level)
{
Container = container;
RuntimeLevel = level;
}
#region Services
/// <summary>
/// Gets the container.
/// Gets the logger.
/// </summary>
/// <remarks>Use with care!</remarks>
public IContainer Container { get; }
public IProfilingLogger Logger { get; }
/// <summary>
/// Gets the type loader.
@@ -52,6 +50,45 @@ namespace Umbraco.Core.Components
/// </summary>
public RuntimeLevel RuntimeLevel { get; }
#endregion
#region IRegister
/// <inheritdoc />
public object ConcreteContainer => _register.ConcreteContainer;
/// <inheritdoc />
public void Register(Type serviceType, Lifetime lifetime = Lifetime.Transient)
=> _register.Register(serviceType, lifetime);
/// <inheritdoc />
public void Register(Type serviceType, Type implementingType, Lifetime lifetime = Lifetime.Transient)
=> _register.Register(serviceType, implementingType, lifetime);
/// <inheritdoc />
public void Register<TService>(Func<IFactory, TService> factory, Lifetime lifetime = Lifetime.Transient)
=> _register.Register(factory, lifetime);
/// <inheritdoc />
public void RegisterInstance(Type serviceType, object instance)
=> _register.RegisterInstance(serviceType, instance);
/// <inheritdoc />
public void RegisterAuto(Type serviceBaseType)
=> _register.RegisterAuto(serviceBaseType);
/// <inheritdoc />
public IContainer ConfigureForWeb()
=> _register.ConfigureForWeb();
/// <inheritdoc />
public IContainer EnablePerWebRequestScope()
=> _register.EnablePerWebRequestScope();
#endregion
#region Collection Builders
/// <summary>
/// Gets a collection builder (and registers the collection).
/// </summary>
@@ -66,11 +103,13 @@ namespace Umbraco.Core.Components
return (TBuilder) o;
var builder = new TBuilder();
builder.Initialize(Container);
builder.Initialize(_register);
_builders[typeOfBuilder] = builder;
return builder;
}
#endregion
}
}

View File

@@ -24,56 +24,56 @@ namespace Umbraco.Core.Components
/// </summary>
/// <param name="composition">The composition.</param>
public static CacheRefresherCollectionBuilder CacheRefreshers(this Composition composition)
=> composition.Container.GetInstance<CacheRefresherCollectionBuilder>();
=> composition.GetCollectionBuilder<CacheRefresherCollectionBuilder>();
/// <summary>
/// Gets the mappers collection builder.
/// </summary>
/// <param name="composition">The composition.</param>
public static MapperCollectionBuilder Mappers(this Composition composition)
=> composition.Container.GetInstance<MapperCollectionBuilder>();
=> composition.GetCollectionBuilder<MapperCollectionBuilder>();
/// <summary>
/// Gets the package actions collection builder.
/// </summary>
/// <param name="composition">The composition.</param>
internal static PackageActionCollectionBuilder PackageActions(this Composition composition)
=> composition.Container.GetInstance<PackageActionCollectionBuilder>();
=> composition.GetCollectionBuilder<PackageActionCollectionBuilder>();
/// <summary>
/// Gets the data editor collection builder.
/// </summary>
/// <param name="composition">The composition.</param>
public static DataEditorCollectionBuilder DataEditors(this Composition composition)
=> composition.Container.GetInstance<DataEditorCollectionBuilder>();
=> composition.GetCollectionBuilder<DataEditorCollectionBuilder>();
/// <summary>
/// Gets the property value converters collection builder.
/// </summary>
/// <param name="composition">The composition.</param>
public static PropertyValueConverterCollectionBuilder PropertyValueConverters(this Composition composition)
=> composition.Container.GetInstance<PropertyValueConverterCollectionBuilder>();
=> composition.GetCollectionBuilder<PropertyValueConverterCollectionBuilder>();
/// <summary>
/// Gets the url segment providers collection builder.
/// </summary>
/// <param name="composition">The composition.</param>
public static UrlSegmentProviderCollectionBuilder UrlSegmentProviders(this Composition composition)
=> composition.Container.GetInstance<UrlSegmentProviderCollectionBuilder>();
=> composition.GetCollectionBuilder<UrlSegmentProviderCollectionBuilder>();
/// <summary>
/// Gets the validators collection builder.
/// </summary>
/// <param name="composition">The composition.</param>
internal static ManifestValueValidatorCollectionBuilder Validators(this Composition composition)
=> composition.Container.GetInstance<ManifestValueValidatorCollectionBuilder>();
=> composition.GetCollectionBuilder<ManifestValueValidatorCollectionBuilder>();
/// <summary>
/// Gets the post-migrations collection builder.
/// </summary>
/// <param name="composition">The composition.</param>
internal static PostMigrationCollectionBuilder PostMigrations(this Composition composition)
=> composition.Container.GetInstance<PostMigrationCollectionBuilder>();
=> composition.GetCollectionBuilder<PostMigrationCollectionBuilder>();
#endregion
@@ -87,7 +87,7 @@ namespace Umbraco.Core.Components
public static void SetCultureDictionaryFactory<T>(this Composition composition)
where T : ICultureDictionaryFactory
{
composition.Container.RegisterSingleton<ICultureDictionaryFactory, T>();
composition.RegisterSingleton<ICultureDictionaryFactory, T>();
}
/// <summary>
@@ -95,9 +95,9 @@ namespace Umbraco.Core.Components
/// </summary>
/// <param name="composition">The composition.</param>
/// <param name="factory">A function creating a culture dictionary factory.</param>
public static void SetCultureDictionaryFactory(this Composition composition, Func<IContainer, ICultureDictionaryFactory> factory)
public static void SetCultureDictionaryFactory(this Composition composition, Func<IFactory, ICultureDictionaryFactory> factory)
{
composition.Container.RegisterSingleton(factory);
composition.RegisterSingleton(factory);
}
/// <summary>
@@ -107,7 +107,7 @@ namespace Umbraco.Core.Components
/// <param name="factory">A factory.</param>
public static void SetCultureDictionaryFactory(this Composition composition, ICultureDictionaryFactory factory)
{
composition.Container.RegisterSingleton(_ => factory);
composition.RegisterSingleton(_ => factory);
}
/// <summary>
@@ -118,7 +118,7 @@ namespace Umbraco.Core.Components
public static void SetPublishedContentModelFactory<T>(this Composition composition)
where T : IPublishedModelFactory
{
composition.Container.RegisterSingleton<IPublishedModelFactory, T>();
composition.RegisterSingleton<IPublishedModelFactory, T>();
}
/// <summary>
@@ -126,9 +126,9 @@ namespace Umbraco.Core.Components
/// </summary>
/// <param name="composition">The composition.</param>
/// <param name="factory">A function creating a published content model factory.</param>
public static void SetPublishedContentModelFactory(this Composition composition, Func<IContainer, IPublishedModelFactory> factory)
public static void SetPublishedContentModelFactory(this Composition composition, Func<IFactory, IPublishedModelFactory> factory)
{
composition.Container.RegisterSingleton(factory);
composition.RegisterSingleton(factory);
}
/// <summary>
@@ -138,7 +138,7 @@ namespace Umbraco.Core.Components
/// <param name="factory">A published content model factory.</param>
public static void SetPublishedContentModelFactory(this Composition composition, IPublishedModelFactory factory)
{
composition.Container.RegisterSingleton(_ => factory);
composition.RegisterSingleton(_ => factory);
}
/// <summary>
@@ -149,7 +149,7 @@ namespace Umbraco.Core.Components
public static void SetServerRegistrar<T>(this Composition composition)
where T : IServerRegistrar
{
composition.Container.RegisterSingleton<IServerRegistrar, T>();
composition.RegisterSingleton<IServerRegistrar, T>();
}
/// <summary>
@@ -157,9 +157,9 @@ namespace Umbraco.Core.Components
/// </summary>
/// <param name="composition">The composition.</param>
/// <param name="factory">A function creating a server registar.</param>
public static void SetServerRegistrar(this Composition composition, Func<IContainer, IServerRegistrar> factory)
public static void SetServerRegistrar(this Composition composition, Func<IFactory, IServerRegistrar> factory)
{
composition.Container.RegisterSingleton(factory);
composition.RegisterSingleton(factory);
}
/// <summary>
@@ -169,7 +169,7 @@ namespace Umbraco.Core.Components
/// <param name="registrar">A server registrar.</param>
public static void SetServerRegistrar(this Composition composition, IServerRegistrar registrar)
{
composition.Container.RegisterSingleton(_ => registrar);
composition.RegisterSingleton(_ => registrar);
}
/// <summary>
@@ -180,7 +180,7 @@ namespace Umbraco.Core.Components
public static void SetServerMessenger<T>(this Composition composition)
where T : IServerMessenger
{
composition.Container.Register<IServerMessenger, T>(Lifetime.Singleton);
composition.Register<IServerMessenger, T>(Lifetime.Singleton);
}
/// <summary>
@@ -188,9 +188,9 @@ namespace Umbraco.Core.Components
/// </summary>
/// <param name="composition">The composition.</param>
/// <param name="factory">A function creating a server messenger.</param>
public static void SetServerMessenger(this Composition composition, Func<IContainer, IServerMessenger> factory)
public static void SetServerMessenger(this Composition composition, Func<IFactory, IServerMessenger> factory)
{
composition.Container.RegisterSingleton(factory);
composition.RegisterSingleton(factory);
}
/// <summary>
@@ -200,7 +200,7 @@ namespace Umbraco.Core.Components
/// <param name="registrar">A server messenger.</param>
public static void SetServerMessenger(this Composition composition, IServerMessenger registrar)
{
composition.Container.RegisterSingleton(_ => registrar);
composition.RegisterSingleton(_ => registrar);
}
/// <summary>
@@ -211,7 +211,7 @@ namespace Umbraco.Core.Components
public static void SetShortStringHelper<T>(this Composition composition)
where T : IShortStringHelper
{
composition.Container.RegisterSingleton<IShortStringHelper, T>();
composition.RegisterSingleton<IShortStringHelper, T>();
}
/// <summary>
@@ -219,9 +219,9 @@ namespace Umbraco.Core.Components
/// </summary>
/// <param name="composition">The composition.</param>
/// <param name="factory">A function creating a short string helper.</param>
public static void SetShortStringHelper(this Composition composition, Func<IContainer, IShortStringHelper> factory)
public static void SetShortStringHelper(this Composition composition, Func<IFactory, IShortStringHelper> factory)
{
composition.Container.RegisterSingleton(factory);
composition.RegisterSingleton(factory);
}
/// <summary>
@@ -231,7 +231,7 @@ namespace Umbraco.Core.Components
/// <param name="helper">A short string helper.</param>
public static void SetShortStringHelper(this Composition composition, IShortStringHelper helper)
{
composition.Container.RegisterSingleton(_ => helper);
composition.RegisterSingleton(_ => helper);
}
#endregion

View File

@@ -21,7 +21,7 @@ namespace Umbraco.Core.Composing
/// <summary>
/// Gets the container.
/// </summary>
protected IContainer Container { get; private set; }
protected IRegister Container { get; private set; }
/// <summary>
/// Gets the internal list of types as an IEnumerable (immutable).
@@ -32,7 +32,7 @@ namespace Umbraco.Core.Composing
/// Initializes a new instance of the builder.
/// </summary>
/// <remarks>By default, this registers the collection automatically.</remarks>
public virtual void Initialize(IContainer container)
public virtual void Initialize(IRegister container)
{
if (Container != null)
throw new InvalidOperationException("This builder has already been initialized.");
@@ -40,7 +40,7 @@ namespace Umbraco.Core.Composing
Container = container;
// register the collection
Container.Register(_ => CreateCollection(), CollectionLifetime);
Container.Register(factory => CreateCollection(factory), CollectionLifetime);
}
/// <summary>
@@ -98,12 +98,12 @@ namespace Umbraco.Core.Composing
/// Creates the collection items.
/// </summary>
/// <returns>The collection items.</returns>
protected virtual IEnumerable<TItem> CreateItems()
protected virtual IEnumerable<TItem> CreateItems(IFactory factory)
{
RegisterTypes(); // will do it only once
return _registeredTypes // respect order
.Select(x => (TItem) Container.GetInstance(x))
.Select(x => (TItem) factory.GetInstance(x))
.ToArray(); // safe
}
@@ -112,9 +112,9 @@ namespace Umbraco.Core.Composing
/// </summary>
/// <returns>A collection.</returns>
/// <remarks>Creates a new collection each time it is invoked.</remarks>
public virtual TCollection CreateCollection()
public virtual TCollection CreateCollection(IFactory factory)
{
return Container.CreateInstance<TCollection>(CreateItems());
return factory.CreateInstance<TCollection>(CreateItems(factory));
}
protected Type EnsureType(Type type, string action)

View File

@@ -11,13 +11,11 @@ namespace Umbraco.Core.Composing.Composers
{
public static Composition ComposeConfiguration(this Composition composition)
{
var container = composition.Container;
container.Register(factory => UmbracoConfig.For.UmbracoSettings());
container.Register(factory => factory.GetInstance<IUmbracoSettingsSection>().Content);
container.Register(factory => factory.GetInstance<IUmbracoSettingsSection>().Templates);
container.Register(factory => factory.GetInstance<IUmbracoSettingsSection>().RequestHandler);
container.Register(factory => UmbracoConfig.For.GlobalSettings());
composition.Register(factory => UmbracoConfig.For.UmbracoSettings());
composition.Register(factory => factory.GetInstance<IUmbracoSettingsSection>().Content);
composition.Register(factory => factory.GetInstance<IUmbracoSettingsSection>().Templates);
composition.Register(factory => factory.GetInstance<IUmbracoSettingsSection>().RequestHandler);
composition.Register(factory => UmbracoConfig.For.GlobalSettings());
// fixme - other sections we need to add?

View File

@@ -9,8 +9,7 @@ namespace Umbraco.Core.Composing.Composers
{
public static Composition ComposeCoreMappingProfiles(this Composition composition)
{
var container = composition.Container;
container.Register<Profile, IdentityMapperProfile>();
composition.Register<Profile, IdentityMapperProfile>();
return composition;
}
}

View File

@@ -67,22 +67,20 @@ namespace Umbraco.Core.Composing.Composers
public static Composition ComposeFileSystems(this Composition composition)
{
var container = composition.Container;
// register FileSystems, which manages all filesystems
// it needs to be registered (not only the interface) because it provides additional
// functionality eg for scoping, and is injected in the scope provider - whereas the
// interface is really for end-users to get access to filesystems.
container.RegisterSingleton(factory => factory.CreateInstance<FileSystems>(container));
composition.RegisterSingleton(factory => factory.CreateInstance<FileSystems>(factory));
// register IFileSystems, which gives access too all filesystems
container.RegisterSingleton<IFileSystems>(factory => factory.GetInstance<FileSystems>());
composition.RegisterSingleton<IFileSystems>(factory => factory.GetInstance<FileSystems>());
// register the scheme for media paths
container.RegisterSingleton<IMediaPathScheme, TwoGuidsMediaPathScheme>();
composition.RegisterSingleton<IMediaPathScheme, TwoGuidsMediaPathScheme>();
// register the IMediaFileSystem implementation with a supporting filesystem
container.RegisterFileSystem<IMediaFileSystem, MediaFileSystem>(
composition.RegisterFileSystem<IMediaFileSystem, MediaFileSystem>(
factory => new PhysicalFileSystem("~/media"));
return composition;

View File

@@ -11,44 +11,42 @@ namespace Umbraco.Core.Composing.Composers
{
public static Composition ComposeRepositories(this Composition composition)
{
var container = composition.Container;
// repositories
container.RegisterSingleton<IAuditRepository, AuditRepository>();
container.RegisterSingleton<IAuditEntryRepository, AuditEntryRepository>();
container.RegisterSingleton<IContentTypeRepository, ContentTypeRepository>();
container.RegisterSingleton<IDataTypeContainerRepository, DataTypeContainerRepository>();
container.RegisterSingleton<IDataTypeRepository, DataTypeRepository>();
container.RegisterSingleton<IDictionaryRepository, DictionaryRepository>();
container.RegisterSingleton<IDocumentBlueprintRepository, DocumentBlueprintRepository>();
container.RegisterSingleton<IDocumentRepository, DocumentRepository>();
container.RegisterSingleton<IDocumentTypeContainerRepository, DocumentTypeContainerRepository>();
container.RegisterSingleton<IDomainRepository, DomainRepository>();
container.RegisterSingleton<IEntityRepository, EntityRepository>();
container.RegisterSingleton<IExternalLoginRepository, ExternalLoginRepository>();
container.RegisterSingleton<ILanguageRepository, LanguageRepository>();
container.RegisterSingleton<IMacroRepository, MacroRepository>();
container.RegisterSingleton<IMediaRepository, MediaRepository>();
container.RegisterSingleton<IMediaTypeContainerRepository, MediaTypeContainerRepository>();
container.RegisterSingleton<IMediaTypeRepository, MediaTypeRepository>();
container.RegisterSingleton<IMemberGroupRepository, MemberGroupRepository>();
container.RegisterSingleton<IMemberRepository, MemberRepository>();
container.RegisterSingleton<IMemberTypeRepository, MemberTypeRepository>();
container.RegisterSingleton<INotificationsRepository, NotificationsRepository>();
container.RegisterSingleton<IPublicAccessRepository, PublicAccessRepository>();
container.RegisterSingleton<IRedirectUrlRepository, RedirectUrlRepository>();
container.RegisterSingleton<IRelationRepository, RelationRepository>();
container.RegisterSingleton<IRelationTypeRepository, RelationTypeRepository>();
container.RegisterSingleton<IServerRegistrationRepository, ServerRegistrationRepository>();
container.RegisterSingleton<ITagRepository, TagRepository>();
container.RegisterSingleton<ITemplateRepository, TemplateRepository>();
container.RegisterSingleton<IUserGroupRepository, UserGroupRepository>();
container.RegisterSingleton<IUserRepository, UserRepository>();
container.RegisterSingleton<IConsentRepository, ConsentRepository>();
container.RegisterSingleton<IPartialViewMacroRepository, PartialViewMacroRepository>();
container.RegisterSingleton<IPartialViewRepository, PartialViewRepository>();
container.RegisterSingleton<IScriptRepository, ScriptRepository>();
container.RegisterSingleton<IStylesheetRepository, StylesheetRepository>();
composition.RegisterSingleton<IAuditRepository, AuditRepository>();
composition.RegisterSingleton<IAuditEntryRepository, AuditEntryRepository>();
composition.RegisterSingleton<IContentTypeRepository, ContentTypeRepository>();
composition.RegisterSingleton<IDataTypeContainerRepository, DataTypeContainerRepository>();
composition.RegisterSingleton<IDataTypeRepository, DataTypeRepository>();
composition.RegisterSingleton<IDictionaryRepository, DictionaryRepository>();
composition.RegisterSingleton<IDocumentBlueprintRepository, DocumentBlueprintRepository>();
composition.RegisterSingleton<IDocumentRepository, DocumentRepository>();
composition.RegisterSingleton<IDocumentTypeContainerRepository, DocumentTypeContainerRepository>();
composition.RegisterSingleton<IDomainRepository, DomainRepository>();
composition.RegisterSingleton<IEntityRepository, EntityRepository>();
composition.RegisterSingleton<IExternalLoginRepository, ExternalLoginRepository>();
composition.RegisterSingleton<ILanguageRepository, LanguageRepository>();
composition.RegisterSingleton<IMacroRepository, MacroRepository>();
composition.RegisterSingleton<IMediaRepository, MediaRepository>();
composition.RegisterSingleton<IMediaTypeContainerRepository, MediaTypeContainerRepository>();
composition.RegisterSingleton<IMediaTypeRepository, MediaTypeRepository>();
composition.RegisterSingleton<IMemberGroupRepository, MemberGroupRepository>();
composition.RegisterSingleton<IMemberRepository, MemberRepository>();
composition.RegisterSingleton<IMemberTypeRepository, MemberTypeRepository>();
composition.RegisterSingleton<INotificationsRepository, NotificationsRepository>();
composition.RegisterSingleton<IPublicAccessRepository, PublicAccessRepository>();
composition.RegisterSingleton<IRedirectUrlRepository, RedirectUrlRepository>();
composition.RegisterSingleton<IRelationRepository, RelationRepository>();
composition.RegisterSingleton<IRelationTypeRepository, RelationTypeRepository>();
composition.RegisterSingleton<IServerRegistrationRepository, ServerRegistrationRepository>();
composition.RegisterSingleton<ITagRepository, TagRepository>();
composition.RegisterSingleton<ITemplateRepository, TemplateRepository>();
composition.RegisterSingleton<IUserGroupRepository, UserGroupRepository>();
composition.RegisterSingleton<IUserRepository, UserRepository>();
composition.RegisterSingleton<IConsentRepository, ConsentRepository>();
composition.RegisterSingleton<IPartialViewMacroRepository, PartialViewMacroRepository>();
composition.RegisterSingleton<IPartialViewRepository, PartialViewRepository>();
composition.RegisterSingleton<IScriptRepository, ScriptRepository>();
composition.RegisterSingleton<IStylesheetRepository, StylesheetRepository>();
return composition;
}

View File

@@ -15,58 +15,56 @@ namespace Umbraco.Core.Composing.Composers
{
public static Composition ComposeServices(this Composition composition)
{
var container = composition.Container;
// register a transient messages factory, which will be replaced by the web
// boot manager when running in a web context
container.RegisterSingleton<IEventMessagesFactory, TransientEventMessagesFactory>();
composition.RegisterSingleton<IEventMessagesFactory, TransientEventMessagesFactory>();
// register the service context
container.RegisterSingleton<ServiceContext>();
composition.RegisterSingleton<ServiceContext>();
// register the special idk map
container.RegisterSingleton<IdkMap>();
composition.RegisterSingleton<IdkMap>();
// register the services
container.RegisterSingleton<IKeyValueService, KeyValueService>();
container.RegisterSingleton<IPublicAccessService, PublicAccessService>();
container.RegisterSingleton<IDomainService, DomainService>();
container.RegisterSingleton<IAuditService, AuditService>();
container.RegisterSingleton<ITagService, TagService>();
container.RegisterSingleton<IContentService, ContentService>();
container.RegisterSingleton<IUserService, UserService>();
container.RegisterSingleton<IMemberService, MemberService>();
container.RegisterSingleton<IMediaService, MediaService>();
container.RegisterSingleton<IContentTypeService, ContentTypeService>();
container.RegisterSingleton<IMediaTypeService, MediaTypeService>();
container.RegisterSingleton<IDataTypeService, DataTypeService>();
container.RegisterSingleton<IFileService, FileService>();
container.RegisterSingleton<ILocalizationService, LocalizationService>();
container.RegisterSingleton<IPackagingService, PackagingService>();
container.RegisterSingleton<IServerRegistrationService, ServerRegistrationService>();
container.RegisterSingleton<IEntityService, EntityService>();
container.RegisterSingleton<IRelationService, RelationService>();
container.RegisterSingleton<IMacroService, MacroService>();
container.RegisterSingleton<IMemberTypeService, MemberTypeService>();
container.RegisterSingleton<IMemberGroupService, MemberGroupService>();
container.RegisterSingleton<INotificationService, NotificationService>();
container.RegisterSingleton<IExternalLoginService, ExternalLoginService>();
container.RegisterSingleton<IRedirectUrlService, RedirectUrlService>();
container.RegisterSingleton<IConsentService, ConsentService>();
container.Register<LocalizedTextServiceFileSources>(SourcesFactory);
container.RegisterSingleton<ILocalizedTextService>(factory => new LocalizedTextService(
composition.RegisterSingleton<IKeyValueService, KeyValueService>();
composition.RegisterSingleton<IPublicAccessService, PublicAccessService>();
composition.RegisterSingleton<IDomainService, DomainService>();
composition.RegisterSingleton<IAuditService, AuditService>();
composition.RegisterSingleton<ITagService, TagService>();
composition.RegisterSingleton<IContentService, ContentService>();
composition.RegisterSingleton<IUserService, UserService>();
composition.RegisterSingleton<IMemberService, MemberService>();
composition.RegisterSingleton<IMediaService, MediaService>();
composition.RegisterSingleton<IContentTypeService, ContentTypeService>();
composition.RegisterSingleton<IMediaTypeService, MediaTypeService>();
composition.RegisterSingleton<IDataTypeService, DataTypeService>();
composition.RegisterSingleton<IFileService, FileService>();
composition.RegisterSingleton<ILocalizationService, LocalizationService>();
composition.RegisterSingleton<IPackagingService, PackagingService>();
composition.RegisterSingleton<IServerRegistrationService, ServerRegistrationService>();
composition.RegisterSingleton<IEntityService, EntityService>();
composition.RegisterSingleton<IRelationService, RelationService>();
composition.RegisterSingleton<IMacroService, MacroService>();
composition.RegisterSingleton<IMemberTypeService, MemberTypeService>();
composition.RegisterSingleton<IMemberGroupService, MemberGroupService>();
composition.RegisterSingleton<INotificationService, NotificationService>();
composition.RegisterSingleton<IExternalLoginService, ExternalLoginService>();
composition.RegisterSingleton<IRedirectUrlService, RedirectUrlService>();
composition.RegisterSingleton<IConsentService, ConsentService>();
composition.Register<LocalizedTextServiceFileSources>(SourcesFactory);
composition.RegisterSingleton<ILocalizedTextService>(factory => new LocalizedTextService(
factory.GetInstance<Lazy<LocalizedTextServiceFileSources>>(),
factory.GetInstance<ILogger>()));
//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.
container.RegisterSingleton<IApplicationTreeService, EmptyApplicationTreeService>();
container.RegisterSingleton<ISectionService, EmptySectionService>();
composition.RegisterSingleton<IApplicationTreeService, EmptyApplicationTreeService>();
composition.RegisterSingleton<ISectionService, EmptySectionService>();
return composition;
}
private static LocalizedTextServiceFileSources SourcesFactory(IContainer container)
private static LocalizedTextServiceFileSources SourcesFactory(IFactory container)
{
var mainLangFolder = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.Umbraco + "/config/lang/"));
var appPlugins = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.AppPlugins));

View File

@@ -26,7 +26,7 @@ namespace Umbraco.Core.Composing
/// </remarks>
public static class Current
{
private static IContainer _container;
private static IFactory _factory;
private static IShortStringHelper _shortStringHelper;
private static ILogger _logger;
@@ -35,30 +35,30 @@ namespace Umbraco.Core.Composing
private static IPublishedValueFallback _publishedValueFallback;
/// <summary>
/// Gets or sets the DI container.
/// Gets or sets the factory.
/// </summary>
public static IContainer Container
public static IFactory Factory
{
get
{
if (_container == null) throw new Exception("No container has been set.");
return _container;
if (_factory == null) throw new Exception("No factory has been set.");
return _factory;
}
set
{
if (_container != null) throw new Exception("A container has already been set.");
_container = value;
if (_factory != null) throw new Exception("A factory has already been set.");
_factory = value;
}
}
internal static bool HasContainer => _container != null;
internal static bool HasContainer => _factory != null;
// for UNIT TESTS exclusively!
// resets *everything* that is 'current'
internal static void Reset()
{
_container?.Dispose();
_container = null;
_factory.DisposeIfDisposable();
_factory = null;
_shortStringHelper = null;
_logger = null;
@@ -80,89 +80,89 @@ namespace Umbraco.Core.Composing
// not happen. Will do when we get rid of IShortStringHelper.
public static IShortStringHelper ShortStringHelper
=> _shortStringHelper ?? (_shortStringHelper = _container?.TryGetInstance<IShortStringHelper>()
=> _shortStringHelper ?? (_shortStringHelper = _factory?.TryGetInstance<IShortStringHelper>()
?? new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(UmbracoConfig.For.UmbracoSettings())));
public static ILogger Logger
=> _logger ?? (_logger = _container?.TryGetInstance<ILogger>()
=> _logger ?? (_logger = _factory?.TryGetInstance<ILogger>()
?? new DebugDiagnosticsLogger());
public static IProfiler Profiler
=> _profiler ?? (_profiler = _container?.TryGetInstance<IProfiler>()
=> _profiler ?? (_profiler = _factory?.TryGetInstance<IProfiler>()
?? new LogProfiler(Logger));
public static IProfilingLogger ProfilingLogger
=> _profilingLogger ?? (_profilingLogger = _container?.TryGetInstance<IProfilingLogger>())
=> _profilingLogger ?? (_profilingLogger = _factory?.TryGetInstance<IProfilingLogger>())
?? new ProfilingLogger(Logger, Profiler);
public static IRuntimeState RuntimeState
=> Container.GetInstance<IRuntimeState>();
=> Factory.GetInstance<IRuntimeState>();
public static TypeLoader TypeLoader
=> Container.GetInstance<TypeLoader>();
=> Factory.GetInstance<TypeLoader>();
public static IFileSystems FileSystems
=> Container.GetInstance<IFileSystems>();
=> Factory.GetInstance<IFileSystems>();
public static IMediaFileSystem MediaFileSystem
=> Container.GetInstance<IMediaFileSystem>();
=> Factory.GetInstance<IMediaFileSystem>();
public static UrlSegmentProviderCollection UrlSegmentProviders
=> Container.GetInstance<UrlSegmentProviderCollection>();
=> Factory.GetInstance<UrlSegmentProviderCollection>();
public static CacheRefresherCollection CacheRefreshers
=> Container.GetInstance<CacheRefresherCollection>();
=> Factory.GetInstance<CacheRefresherCollection>();
public static DataEditorCollection DataEditors
=> Container.GetInstance<DataEditorCollection>();
=> Factory.GetInstance<DataEditorCollection>();
public static PropertyEditorCollection PropertyEditors
=> Container.GetInstance<PropertyEditorCollection>();
=> Factory.GetInstance<PropertyEditorCollection>();
public static ParameterEditorCollection ParameterEditors
=> Container.GetInstance<ParameterEditorCollection>();
=> Factory.GetInstance<ParameterEditorCollection>();
internal static ManifestValueValidatorCollection ManifestValidators
=> Container.GetInstance<ManifestValueValidatorCollection>();
=> Factory.GetInstance<ManifestValueValidatorCollection>();
internal static PackageActionCollection PackageActions
=> Container.GetInstance<PackageActionCollection>();
=> Factory.GetInstance<PackageActionCollection>();
internal static PropertyValueConverterCollection PropertyValueConverters
=> Container.GetInstance<PropertyValueConverterCollection>();
=> Factory.GetInstance<PropertyValueConverterCollection>();
internal static IPublishedModelFactory PublishedModelFactory
=> Container.GetInstance<IPublishedModelFactory>();
=> Factory.GetInstance<IPublishedModelFactory>();
public static IServerMessenger ServerMessenger
=> Container.GetInstance<IServerMessenger>();
=> Factory.GetInstance<IServerMessenger>();
public static IServerRegistrar ServerRegistrar
=> Container.GetInstance<IServerRegistrar>();
=> Factory.GetInstance<IServerRegistrar>();
public static ICultureDictionaryFactory CultureDictionaryFactory
=> Container.GetInstance<ICultureDictionaryFactory>();
=> Factory.GetInstance<ICultureDictionaryFactory>();
public static CacheHelper ApplicationCache
=> Container.GetInstance<CacheHelper>();
=> Factory.GetInstance<CacheHelper>();
public static ServiceContext Services
=> Container.GetInstance<ServiceContext>();
=> Factory.GetInstance<ServiceContext>();
public static IScopeProvider ScopeProvider
=> Container.GetInstance<IScopeProvider>();
=> Factory.GetInstance<IScopeProvider>();
public static ISqlContext SqlContext
=> Container.GetInstance<ISqlContext>();
=> Factory.GetInstance<ISqlContext>();
public static IPublishedContentTypeFactory PublishedContentTypeFactory
=> Container.GetInstance<IPublishedContentTypeFactory>();
=> Factory.GetInstance<IPublishedContentTypeFactory>();
public static IPublishedValueFallback PublishedValueFallback
=> _publishedValueFallback ?? Container.GetInstance<IPublishedValueFallback>() ?? new NoopPublishedValueFallback();
=> _publishedValueFallback ?? Factory.GetInstance<IPublishedValueFallback>() ?? new NoopPublishedValueFallback();
public static IVariationContextAccessor VariationContextAccessor
=> Container.GetInstance<IVariationContextAccessor>();
=> Factory.GetInstance<IVariationContextAccessor>();
#endregion
}

View File

@@ -8,7 +8,7 @@
/// <summary>
/// Initializes a new instance of the builder, and registers the collection.
/// </summary>
void Initialize(IContainer container);
void Initialize(IRegister container);
}
/// <summary>
@@ -24,6 +24,6 @@
/// </summary>
/// <returns>A collection.</returns>
/// <remarks>Creates a new collection each time it is invoked.</remarks>
TCollection CreateCollection();
TCollection CreateCollection(IFactory factory);
}
}

View File

@@ -20,17 +20,76 @@ namespace Umbraco.Core.Composing
// IEnumerable of the service, nameless, returns them all
/// <summary>
/// Defines a container for Umbraco.
/// Defines a service register for Umbraco.
/// </summary>
public interface IContainer : IDisposable
public interface IRegister
{
/// <summary>
/// Gets the concrete container.
/// </summary>
object ConcreteContainer { get; }
#region Factory
/// <summary>
/// Registers a service as its own implementation.
/// </summary>
void Register(Type serviceType, Lifetime lifetime = Lifetime.Transient);
/// <summary>
/// Registers a service with an implementation type.
/// </summary>
void Register(Type serviceType, Type implementingType, Lifetime lifetime = Lifetime.Transient);
/// <summary>
/// Registers a service with an implementation factory.
/// </summary>
void Register<TService>(Func<IFactory, TService> factory, Lifetime lifetime = Lifetime.Transient);
/// <summary>
/// Registers a service with an implementing instance.
/// </summary>
void RegisterInstance(Type serviceType, object instance);
/// <summary>
/// Registers a base type for auto-registration.
/// </summary>
/// <remarks>
/// <para>Auto-registration means that anytime the container is asked to create an instance
/// of a type deriving from <paramref name="serviceBaseType"/>, it will first register that
/// type automatically.</para>
/// <para>This can be used for instance for views or controllers. Then, one just needs to
/// register a common base class or interface, and the container knows how to create instances.</para>
/// </remarks>
void RegisterAuto(Type serviceBaseType);
#region Control
/// <summary>
/// Configures the container for web support.
/// </summary>
/// <returns>The container.</returns>
/// <remarks>
/// <para>Enables support for MVC, WebAPI, but *not* per-request scope. This is used early in the boot
/// process, where anything "scoped" should not be linked to a web request.</para>
/// </remarks>
IContainer ConfigureForWeb();
/// <summary>
/// Enables per-request scope.
/// </summary>
/// <returns>The container.</returns>
/// <remarks>
/// <para>Ties scopes to web requests.</para>
/// </remarks>
IContainer EnablePerWebRequestScope();
#endregion
}
/// <summary>
/// Defines a service factory for Umbraco.
/// </summary>
public interface IFactory
{
/// <summary>
/// Gets an instance of a service.
/// </summary>
@@ -72,46 +131,6 @@ namespace Umbraco.Core.Composing
/// </remarks>
void Release(object instance);
#endregion
#region Registry
/// <summary>
/// Registers a service as its own implementation.
/// </summary>
void Register(Type serviceType, Lifetime lifetime = Lifetime.Transient);
/// <summary>
/// Registers a service with an implementation type.
/// </summary>
void Register(Type serviceType, Type implementingType, Lifetime lifetime = Lifetime.Transient);
/// <summary>
/// Registers a service with an implementation factory.
/// </summary>
void Register<TService>(Func<IContainer, TService> factory, Lifetime lifetime = Lifetime.Transient);
/// <summary>
/// Registers a service with an implementing instance.
/// </summary>
void RegisterInstance(Type serviceType, object instance);
/// <summary>
/// Registers a base type for auto-registration.
/// </summary>
/// <remarks>
/// <para>Auto-registration means that anytime the container is asked to create an instance
/// of a type deriving from <paramref name="serviceBaseType"/>, it will first register that
/// type automatically.</para>
/// <para>This can be used for instance for views or controllers. Then, one just needs to
/// register a common base class or interface, and the container knows how to create instances.</para>
/// </remarks>
void RegisterAuto(Type serviceBaseType);
#endregion
#region Control
/// <summary>
/// Begins a scope.
/// </summary>
@@ -120,26 +139,11 @@ namespace Umbraco.Core.Composing
/// <para>Scopes can be nested. Each instance is disposed individually.</para>
/// </remarks>
IDisposable BeginScope();
/// <summary>
/// Configures the container for web support.
/// </summary>
/// <returns>The container.</returns>
/// <remarks>
/// <para>Enables support for MVC, WebAPI, but *not* per-request scope. This is used early in the boot
/// process, where anything "scoped" should not be linked to a web request.</para>
/// </remarks>
IContainer ConfigureForWeb();
/// <summary>
/// Enables per-request scope.
/// </summary>
/// <returns>The container.</returns>
/// <remarks>
/// <para>Ties scopes to web requests.</para>
/// </remarks>
IContainer EnablePerWebRequestScope();
#endregion
}
/// <summary>
/// Defines a container for Umbraco.
/// </summary>
public interface IContainer : IRegister, IFactory, IDisposable // fixme kill?
{ }
}

View File

@@ -14,8 +14,7 @@ namespace Umbraco.Core.Composing
where TBuilder : LazyCollectionBuilderBase<TBuilder, TCollection, TItem>
where TCollection : IBuilderCollection<TItem>
{
private readonly List<Func<IEnumerable<Type>>> _producers1 = new List<Func<IEnumerable<Type>>>();
private readonly List<Func<IContainer, IEnumerable<Type>>> _producers2 = new List<Func<IContainer, IEnumerable<Type>>>();
private readonly List<Func<IEnumerable<Type>>> _producers = new List<Func<IEnumerable<Type>>>();
private readonly List<Type> _excluded = new List<Type>();
protected abstract TBuilder This { get; }
@@ -29,9 +28,8 @@ namespace Umbraco.Core.Composing
Configure(types =>
{
types.Clear();
_producers1.Clear();
_producers2.Clear();
_excluded.Clear();
_producers.Clear();
_excluded.Clear();
});
return This;
}
@@ -107,21 +105,7 @@ namespace Umbraco.Core.Composing
{
Configure(types =>
{
_producers1.Add(producer);
});
return This;
}
/// <summary>
/// Adds a types producer to the collection.
/// </summary>
/// <param name="producer">The types producer.</param>
/// <returns>The builder.</returns>
public TBuilder Add(Func<IContainer, IEnumerable<Type>> producer)
{
Configure(types =>
{
_producers2.Add(producer);
_producers.Add(producer);
});
return This;
}
@@ -160,8 +144,7 @@ namespace Umbraco.Core.Composing
protected override IEnumerable<Type> GetRegisteringTypes(IEnumerable<Type> types)
{
return types
.Union(_producers1.SelectMany(x => x()))
.Union(_producers2.SelectMany(x => x(Container)))
.Union(_producers.SelectMany(x => x()))
.Distinct()
.Select(x => EnsureType(x, "register"))
.Except(_excluded);

View File

@@ -174,7 +174,7 @@ namespace Umbraco.Core.Composing.LightInject
}
/// <inheritdoc />
public void Register<TService>(Func<IContainer, TService> factory, Lifetime lifetime = Lifetime.Transient)
public void Register<TService>(Func<IFactory, TService> factory, Lifetime lifetime = Lifetime.Transient)
{
switch (lifetime)
{

View File

@@ -78,26 +78,6 @@ namespace Umbraco.Core.Composing
return This;
}
/// <summary>
/// Appends types to the collections.
/// </summary>
/// <param name="types">The types to append.</param>
/// <returns>The builder.</returns>
public TBuilder Append(Func<IContainer, IEnumerable<Type>> types)
{
Configure(list =>
{
foreach (var type in types(Container))
{
// would be detected by CollectionBuilderBase when registering, anyways, but let's fail fast
EnsureType(type, "register");
if (list.Contains(type)) list.Remove(type);
list.Add(type);
}
});
return This;
}
/// <summary>
/// Appends a type after another type.
/// </summary>

View File

@@ -10,7 +10,7 @@ namespace Umbraco.Core.Composing
/// <summary>
/// Provides extension methods to the <see cref="IContainer"/> class.
/// </summary>
public static class ContainerExtensions
public static class RegisterExtensions
{
/// <summary>
/// Gets an instance of a service.
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Composing
/// <param name="container">The container.</param>
/// <returns>An instance of the specified type.</returns>
/// <remarks>Throws an exception if the container failed to get an instance of the specified type.</remarks>
public static T GetInstance<T>(this IContainer container)
public static T GetInstance<T>(this IFactory container)
=> (T) container.GetInstance(typeof(T));
/// <summary>
@@ -30,7 +30,7 @@ namespace Umbraco.Core.Composing
/// <remarks>Returns null if the container does not know how to get an instance
/// of the specified type. Throws an exception if the container does know how
/// to get an instance of the specified type, but failed to do so.</remarks>
public static T TryGetInstance<T>(this IContainer container)
public static T TryGetInstance<T>(this IFactory container)
=> (T) container.TryGetInstance(typeof(T));
/// <summary>
@@ -44,49 +44,49 @@ namespace Umbraco.Core.Composing
/// <para>Throws an exception if the container failed to get an instance of the specified type.</para>
/// <para>The arguments are used as dependencies by the container.</para>
/// </remarks>
public static T CreateInstance<T>(this IContainer container, params object[] args)
public static T CreateInstance<T>(this IFactory container, params object[] args)
=> (T) container.CreateInstance(typeof(T), args);
/// <summary>
/// Registers a service with an implementation type.
/// </summary>
public static void Register<TService, TImplementing>(this IContainer container, Lifetime lifetime = Lifetime.Transient)
public static void Register<TService, TImplementing>(this IRegister container, Lifetime lifetime = Lifetime.Transient)
=> container.Register(typeof(TService), typeof(TImplementing), lifetime);
/// <summary>
/// Registers a service as its own implementation.
/// </summary>
public static void Register<TService>(this IContainer container, Lifetime lifetime = Lifetime.Transient)
public static void Register<TService>(this IRegister container, Lifetime lifetime = Lifetime.Transient)
=> container.Register(typeof(TService), lifetime);
/// <summary>
/// Registers a singleton service as its own implementation.
/// </summary>
public static void RegisterSingleton<TService>(this IContainer container)
public static void RegisterSingleton<TService>(this IRegister container)
=> container.Register(typeof(TService), Lifetime.Singleton);
/// <summary>
/// Registers a singleton service with an implementation type.
/// </summary>
public static void RegisterSingleton<TService, TImplementing>(this IContainer container)
public static void RegisterSingleton<TService, TImplementing>(this IRegister container)
=> container.Register(typeof(TService), typeof(TImplementing), Lifetime.Singleton);
/// <summary>
/// Registers a singleton service with an implementation factory.
/// </summary>
public static void RegisterSingleton<TService>(this IContainer container, Func<IContainer, TService> factory)
public static void RegisterSingleton<TService>(this IRegister container, Func<IFactory, TService> factory)
=> container.Register(factory, Lifetime.Singleton);
/// <summary>
/// Registers a service with an implementing instance.
/// </summary>
public static void RegisterInstance<TService>(this IContainer container, TService instance)
public static void RegisterInstance<TService>(this IRegister container, TService instance)
=> container.RegisterInstance(typeof(TService), instance);
/// <summary>
/// Registers a base type for auto-registration.
/// </summary>
public static void RegisterAuto<TServiceBase>(this IContainer container)
public static void RegisterAuto<TServiceBase>(this IRegister container)
=> container.RegisterAuto(typeof(TServiceBase));
/// <summary>
@@ -101,7 +101,7 @@ namespace Umbraco.Core.Composing
/// <para>The arguments are used as dependencies by the container. Other dependencies
/// are retrieved from the container.</para>
/// </remarks>
public static object CreateInstance(this IContainer container, Type type, params object[] args)
public static object CreateInstance(this IFactory container, Type type, params object[] args)
{
// LightInject has this, but then it requires RegisterConstructorDependency etc and has various oddities
// including the most annoying one, which is that it does not work on singletons (hard to fix)
@@ -137,7 +137,7 @@ namespace Umbraco.Core.Composing
/// <param name="container">The container.</param>
/// <param name="supportingFileSystemFactory">A factory method creating the supporting filesystem.</param>
/// <returns>The container.</returns>
public static IContainer RegisterFileSystem<TFileSystem, TImplementing>(this IContainer container, Func<IContainer, IFileSystem> supportingFileSystemFactory)
public static IRegister RegisterFileSystem<TFileSystem, TImplementing>(this IRegister container, Func<IFactory, IFileSystem> supportingFileSystemFactory)
where TImplementing : FileSystemWrapper, TFileSystem
{
container.RegisterSingleton<TFileSystem>(factory =>
@@ -156,7 +156,7 @@ namespace Umbraco.Core.Composing
/// <param name="container">The container.</param>
/// <param name="supportingFileSystemFactory">A factory method creating the supporting filesystem.</param>
/// <returns>The container.</returns>
public static IContainer RegisterFileSystem<TFileSystem>(this IContainer container, Func<IContainer, IFileSystem> supportingFileSystemFactory)
public static IRegister RegisterFileSystem<TFileSystem>(this IRegister container, Func<IFactory, IFileSystem> supportingFileSystemFactory)
where TFileSystem : FileSystemWrapper
{
container.RegisterSingleton(factory =>

View File

@@ -87,6 +87,13 @@ namespace Umbraco.Core.Composing
}
}
/// <summary>
/// Initializes a new, test/blank, instance of the <see cref="TypeLoader"/> class.
/// </summary>
/// <remarks>The initialized instance cannot get types.</remarks>
internal TypeLoader()
{ }
/// <summary>
/// Gets or sets the set of assemblies to scan.
/// </summary>
@@ -514,6 +521,9 @@ namespace Umbraco.Core.Composing
/// <remarks>Caching is disabled when using specific assemblies.</remarks>
public IEnumerable<Type> GetTypes<T>(bool cache = true, IEnumerable<Assembly> specificAssemblies = null)
{
if (_logger == null)
throw new InvalidOperationException("Cannot get types from a test/blank type loader.");
// do not cache anything from specific assemblies
cache &= specificAssemblies == null;
@@ -553,6 +563,9 @@ namespace Umbraco.Core.Composing
public IEnumerable<Type> GetTypesWithAttribute<T, TAttribute>(bool cache = true, IEnumerable<Assembly> specificAssemblies = null)
where TAttribute : Attribute
{
if (_logger == null)
throw new InvalidOperationException("Cannot get types from a test/blank type loader.");
// do not cache anything from specific assemblies
cache &= specificAssemblies == null;
@@ -592,6 +605,9 @@ namespace Umbraco.Core.Composing
public IEnumerable<Type> GetAttributedTypes<TAttribute>(bool cache = true, IEnumerable<Assembly> specificAssemblies = null)
where TAttribute : Attribute
{
if (_logger == null)
throw new InvalidOperationException("Cannot get types from a test/blank type loader.");
// do not cache anything from specific assemblies
cache &= specificAssemblies == null;

View File

@@ -9,7 +9,7 @@ namespace Umbraco.Core.IO
{
public class FileSystems : IFileSystems
{
private readonly IContainer _container;
private readonly IFactory _container;
private readonly ILogger _logger;
private readonly ConcurrentDictionary<Type, Lazy<IFileSystem>> _filesystems = new ConcurrentDictionary<Type, Lazy<IFileSystem>>();
@@ -34,7 +34,7 @@ namespace Umbraco.Core.IO
#region Constructor
// DI wants a public ctor
public FileSystems(IContainer container, ILogger logger)
public FileSystems(IFactory container, ILogger logger)
{
_container = container;
_logger = logger;

View File

@@ -5,9 +5,9 @@ namespace Umbraco.Core.Migrations
{
public class MigrationBuilder : IMigrationBuilder
{
private readonly IContainer _container;
private readonly IFactory _container;
public MigrationBuilder(IContainer container)
public MigrationBuilder(IFactory container)
{
_container = container;
}

View File

@@ -88,7 +88,7 @@ namespace Umbraco.Core.Models
try
{
var globalSettings = (IGlobalSettings) Composing.Current.Container.GetInstance(typeof(IGlobalSettings));
var globalSettings = (IGlobalSettings) Composing.Current.Factory.GetInstance(typeof(IGlobalSettings));
var defaultUiCulture = CultureInfo.GetCultureInfo(globalSettings.DefaultUILanguage);
Thread.CurrentThread.CurrentUICulture = defaultUiCulture;

View File

@@ -6,7 +6,7 @@ namespace Umbraco.Core.Persistence.Mappers
{
protected override MapperCollectionBuilder This => this;
public override void Initialize(IContainer container)
public override void Initialize(IRegister container)
{
base.Initialize(container);

View File

@@ -47,7 +47,7 @@ namespace Umbraco.Core.Runtime
public virtual void Boot(IContainer container)
{
// assign current container
Current.Container = _container = container;
Current.Factory = _container = container;
// create and register the essential services
// ie the bare minimum required to boot
@@ -94,7 +94,7 @@ namespace Umbraco.Core.Runtime
container.RegisterInstance<IRuntimeState>(_state);
// create the composition
var composition = new Composition(container, typeLoader, RuntimeLevel.Boot);
var composition = new Composition(container, typeLoader, profilingLogger, RuntimeLevel.Boot);
// register runtime-level services
Compose(composition);
@@ -134,8 +134,9 @@ namespace Umbraco.Core.Runtime
// we should have a Current.Factory not a Current.Container
// we should compile the register into a factory *now*
// using the factory before this point should just throw
IFactory factory = container;
_components.Initialize();
_components.Initialize(factory);
}
catch (Exception e)
{

View File

@@ -34,8 +34,6 @@ namespace Umbraco.Core.Runtime
{
base.Compose(composition);
var container = composition.Container;
// composers
composition
.ComposeConfiguration()
@@ -50,16 +48,16 @@ namespace Umbraco.Core.Runtime
composition.GetCollectionBuilder<MapperCollectionBuilder>().AddCoreMappers();
// register the scope provider
container.RegisterSingleton<ScopeProvider>(); // implements both IScopeProvider and IScopeAccessor
container.RegisterSingleton<IScopeProvider>(f => f.GetInstance<ScopeProvider>());
container.RegisterSingleton<IScopeAccessor>(f => f.GetInstance<ScopeProvider>());
composition.RegisterSingleton<ScopeProvider>(); // implements both IScopeProvider and IScopeAccessor
composition.RegisterSingleton<IScopeProvider>(f => f.GetInstance<ScopeProvider>());
composition.RegisterSingleton<IScopeAccessor>(f => f.GetInstance<ScopeProvider>());
// register database builder
// *not* a singleton, don't want to keep it around
composition.Container.Register<DatabaseBuilder>();
composition.Register<DatabaseBuilder>();
// register manifest parser, will be injected in collection builders where needed
composition.Container.RegisterSingleton<ManifestParser>();
composition.RegisterSingleton<ManifestParser>();
// register our predefined validators
composition.GetCollectionBuilder<ManifestValueValidatorCollectionBuilder>()
@@ -72,12 +70,12 @@ namespace Umbraco.Core.Runtime
// properties and parameters derive from data editors
composition.GetCollectionBuilder<DataEditorCollectionBuilder>()
.Add(factory => factory.GetInstance<TypeLoader>().GetDataEditors());
composition.Container.RegisterSingleton<PropertyEditorCollection>();
composition.Container.RegisterSingleton<ParameterEditorCollection>();
.Add(() => composition.TypeLoader.GetDataEditors());
composition.RegisterSingleton<PropertyEditorCollection>();
composition.RegisterSingleton<ParameterEditorCollection>();
// register a server registrar, by default it's the db registrar
composition.Container.RegisterSingleton<IServerRegistrar>(f =>
composition.RegisterSingleton<IServerRegistrar>(f =>
{
if ("true".InvariantEquals(ConfigurationManager.AppSettings["umbracoDisableElectionForSingleServer"]))
return new SingleServerRegistrar(f.GetInstance<IRuntimeState>());
@@ -89,7 +87,7 @@ namespace Umbraco.Core.Runtime
// by default we'll use the database server messenger with default options (no callbacks),
// this will be overridden by either the legacy thing or the db thing in the corresponding
// components in the web project - fixme - should obsolete the legacy thing
composition.Container.RegisterSingleton<IServerMessenger>(factory
composition.RegisterSingleton<IServerMessenger>(factory
=> new DatabaseServerMessenger(
factory.GetInstance<IRuntimeState>(),
factory.GetInstance<IScopeProvider>(),
@@ -99,29 +97,29 @@ namespace Umbraco.Core.Runtime
true, new DatabaseServerMessengerOptions()));
composition.GetCollectionBuilder<CacheRefresherCollectionBuilder>()
.Add(factory => factory.GetInstance<TypeLoader>().GetCacheRefreshers());
.Add(() => composition.TypeLoader.GetCacheRefreshers());
composition.GetCollectionBuilder<PackageActionCollectionBuilder>()
.Add(f => f.GetInstance<TypeLoader>().GetPackageActions());
.Add(() => composition.TypeLoader.GetPackageActions());
composition.GetCollectionBuilder<PropertyValueConverterCollectionBuilder>()
.Append(factory => factory.GetInstance<TypeLoader>().GetTypes<IPropertyValueConverter>());
.Append(composition.TypeLoader.GetTypes<IPropertyValueConverter>());
composition.Container.RegisterSingleton<IPublishedContentTypeFactory, PublishedContentTypeFactory>();
composition.RegisterSingleton<IPublishedContentTypeFactory, PublishedContentTypeFactory>();
composition.Container.RegisterSingleton<IShortStringHelper>(factory
composition.RegisterSingleton<IShortStringHelper>(factory
=> new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(factory.GetInstance<IUmbracoSettingsSection>())));
composition.GetCollectionBuilder<UrlSegmentProviderCollectionBuilder>()
.Append<DefaultUrlSegmentProvider>();
composition.GetCollectionBuilder<PostMigrationCollectionBuilder>()
.Add(factory => factory.GetInstance<TypeLoader>().GetTypes<IPostMigration>());
.Add(() => composition.TypeLoader.GetTypes<IPostMigration>());
composition.Container.RegisterSingleton<IMigrationBuilder>(factory => new MigrationBuilder(composition.Container));
composition.RegisterSingleton<IMigrationBuilder>(factory => new MigrationBuilder(factory));
// by default, register a noop factory
composition.Container.RegisterSingleton<IPublishedModelFactory, NoopPublishedModelFactory>();
composition.RegisterSingleton<IPublishedModelFactory, NoopPublishedModelFactory>();
}
internal void Initialize(IEnumerable<Profile> mapperProfiles)

View File

@@ -321,7 +321,7 @@
<Compile Include="Constants-System.cs" />
<Compile Include="Constants-Web.cs" />
<Compile Include="Constants.cs" />
<Compile Include="Composing\ContainerExtensions.cs" />
<Compile Include="Composing\RegisterExtensions.cs" />
<Compile Include="ContentVariationExtensions.cs" />
<Compile Include="DisposableObjectSlim.cs" />
<Compile Include="Events\ExportedMemberEventArgs.cs" />