diff --git a/src/Umbraco.Core/ApplicationContext.cs b/src/Umbraco.Core/ApplicationContext.cs index 815e69acb4..feafd8ed96 100644 --- a/src/Umbraco.Core/ApplicationContext.cs +++ b/src/Umbraco.Core/ApplicationContext.cs @@ -20,41 +20,26 @@ namespace Umbraco.Core /// public class ApplicationContext : IDisposable { - /// - /// Constructor - /// - internal ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext) - : this(dbContext, serviceContext, true) - { - - } - + /// /// Constructor /// /// /// - /// - internal ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, bool enableCache) - : this(enableCache) + /// + internal ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache) { if (dbContext == null) throw new ArgumentNullException("dbContext"); if (serviceContext == null) throw new ArgumentNullException("serviceContext"); + if (cache == null) throw new ArgumentNullException("cache"); _databaseContext = dbContext; - _services = serviceContext; + _services = serviceContext; + ApplicationCache = cache; } - /// - /// Empty constructor normally reserved for unit tests when a DatabaseContext or a ServiceContext is not - /// necessarily required or needs to be set after construction. - /// - internal ApplicationContext() : this(true) - { - } - /// - /// Constructor used to specify if we will enable application cache or not + /// Constructor used to specify if we will enable application cache or not, used for unit tests /// /// internal ApplicationContext(bool enableCache) diff --git a/src/Umbraco.Core/CoreBootManager.cs b/src/Umbraco.Core/CoreBootManager.cs index 8f962ae7c7..9f5fb22966 100644 --- a/src/Umbraco.Core/CoreBootManager.cs +++ b/src/Umbraco.Core/CoreBootManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Web; using AutoMapper; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; @@ -38,7 +39,8 @@ namespace Umbraco.Core private bool _isStarted = false; private bool _isComplete = false; private readonly UmbracoApplicationBase _umbracoApplication; - protected ApplicationContext ApplicationContext { get; private set; } + protected ApplicationContext ApplicationContext { get; set; } + protected CacheHelper ApplicationCache { get; set; } protected UmbracoApplicationBase UmbracoApplication { @@ -60,6 +62,8 @@ namespace Umbraco.Core _timer = DisposableTimer.DebugDuration("Umbraco application starting", "Umbraco application startup complete"); + CreateApplicationCache(); + //create database and service contexts for the app context var dbFactory = new DefaultDatabaseFactory(GlobalSettings.UmbracoConnectionName); Database.Mapper = new PetaPocoMapper(); @@ -67,7 +71,8 @@ namespace Umbraco.Core var serviceContext = new ServiceContext( new PetaPocoUnitOfWorkProvider(dbFactory), new FileUnitOfWorkProvider(), - new PublishingStrategy()); + new PublishingStrategy(), + ApplicationCache); CreateApplicationContext(dbContext, serviceContext); @@ -97,7 +102,15 @@ namespace Umbraco.Core protected virtual void CreateApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext) { //create the ApplicationContext - ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext); + ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext, ApplicationCache); + } + + /// + /// Creates and assigns the ApplicationCache based on a new instance of System.Web.Caching.Cache + /// + protected virtual void CreateApplicationCache() + { + ApplicationCache = new CacheHelper(new System.Web.Caching.Cache(), true); } /// diff --git a/src/Umbraco.Core/Trees/ApplicationTree.cs b/src/Umbraco.Core/Models/ApplicationTree.cs similarity index 98% rename from src/Umbraco.Core/Trees/ApplicationTree.cs rename to src/Umbraco.Core/Models/ApplicationTree.cs index a1931deb3b..edeca6965c 100644 --- a/src/Umbraco.Core/Trees/ApplicationTree.cs +++ b/src/Umbraco.Core/Models/ApplicationTree.cs @@ -1,6 +1,6 @@ using System.Diagnostics; -namespace Umbraco.Core.Trees +namespace Umbraco.Core.Models { [DebuggerDisplay("Tree - {Title} ({ApplicationAlias})")] internal class ApplicationTree diff --git a/src/Umbraco.Core/Sections/Section.cs b/src/Umbraco.Core/Models/Section.cs similarity index 78% rename from src/Umbraco.Core/Sections/Section.cs rename to src/Umbraco.Core/Models/Section.cs index b39cbe009d..953d201bf8 100644 --- a/src/Umbraco.Core/Sections/Section.cs +++ b/src/Umbraco.Core/Models/Section.cs @@ -1,5 +1,8 @@ -namespace Umbraco.Core.Sections +namespace Umbraco.Core.Models { + /// + /// Represents a section defined in the app.config file + /// public class Section { public Section(string name, string @alias, string icon, int sortOrder) diff --git a/src/Umbraco.Core/Models/UserSection.cs b/src/Umbraco.Core/Models/UserSection.cs new file mode 100644 index 0000000000..dd3f27b817 --- /dev/null +++ b/src/Umbraco.Core/Models/UserSection.cs @@ -0,0 +1,44 @@ +using System; +using System.Runtime.Serialization; +using Umbraco.Core.Models.EntityBase; + +namespace Umbraco.Core.Models +{ + /// + /// Represents an allowed section for a user + /// + [Serializable] + [DataContract(IsReference = true)] + internal class UserSection : IAggregateRoot + { + private int? _userId; + private bool _hasIdentity; + + [DataMember] + public string SectionAlias { get; set; } + + //NOTE: WE cannot implement these as the columns don't exist in the db. + [IgnoreDataMember] + Guid IEntity.Key { get; set; } + [IgnoreDataMember] + DateTime IEntity.CreateDate { get; set; } + [IgnoreDataMember] + DateTime IEntity.UpdateDate { get; set; } + + [IgnoreDataMember] + public bool HasIdentity { get { return _userId != null || _hasIdentity; } } + + public int Id + { + get + { + return _userId.HasValue ? _userId.Value : -1; + } + set + { + _userId = value; + _hasIdentity = true; + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Factories/ModelFactoryConfiguration.cs b/src/Umbraco.Core/Persistence/Factories/ModelFactoryConfiguration.cs new file mode 100644 index 0000000000..38b8310805 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Factories/ModelFactoryConfiguration.cs @@ -0,0 +1,17 @@ +using AutoMapper; +using Umbraco.Core.Models.Mapping; + +namespace Umbraco.Core.Persistence.Factories +{ + /// + /// This configures all of the AutoMapper supported mapping factories + /// + internal class ModelFactoryConfiguration : MapperConfiguration + { + public override void ConfigureMappings(IConfiguration config) + { + //TODO: Implement AutoMapper for the other factories! + UserSectionFactory.ConfigureMappings(config); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Factories/UserSectionFactory.cs b/src/Umbraco.Core/Persistence/Factories/UserSectionFactory.cs new file mode 100644 index 0000000000..12e3d1f9d7 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Factories/UserSectionFactory.cs @@ -0,0 +1,38 @@ +using AutoMapper; +using Umbraco.Core.Models; +using Umbraco.Core.Models.Rdbms; + +namespace Umbraco.Core.Persistence.Factories +{ + internal class UserSectionFactory : IEntityFactory + { + #region Implementation of IEntityFactory + + public UserSection BuildEntity(User2AppDto dto) + { + return Mapper.Map(dto); + } + + public User2AppDto BuildDto(UserSection entity) + { + return Mapper.Map(entity); + } + + #endregion + + /// + /// Sets up the automapper mappings + /// + /// + internal static void ConfigureMappings(IConfiguration config) + { + config.CreateMap() + .ForMember(section => section.Id, expression => expression.MapFrom(dto => dto.UserId)) + .ForMember(section => section.SectionAlias, expression => expression.MapFrom(dto => dto.AppAlias)); + + config.CreateMap() + .ForMember(dto => dto.UserId, expression => expression.MapFrom(section => section.Id)) + .ForMember(dto => dto.AppAlias, expression => expression.MapFrom(section => section.SectionAlias)); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/BaseMapper.cs b/src/Umbraco.Core/Persistence/Mappers/BaseMapper.cs index a5e1700566..006821e2b3 100644 --- a/src/Umbraco.Core/Persistence/Mappers/BaseMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/BaseMapper.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Linq.Expressions; using System.Reflection; using Umbraco.Core.Persistence.SqlSyntax; @@ -7,11 +8,24 @@ namespace Umbraco.Core.Persistence.Mappers { public abstract class BaseMapper { + + internal abstract ConcurrentDictionary PropertyInfoCache { get; } + internal abstract void BuildMap(); - internal abstract string Map(string propertyName); + internal string Map(string propertyName) + { + DtoMapModel dtoTypeProperty; + return PropertyInfoCache.TryGetValue(propertyName, out dtoTypeProperty) + ? GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo) + : string.Empty; + } - internal abstract void CacheMap(Expression> sourceMember, Expression> destinationMember); + internal void CacheMap(Expression> sourceMember, Expression> destinationMember) + { + var property = ResolveMapping(sourceMember, destinationMember); + PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); + } internal DtoMapModel ResolveMapping(Expression> sourceMember, Expression> destinationMember) { diff --git a/src/Umbraco.Core/Persistence/Mappers/ContentMapper.cs b/src/Umbraco.Core/Persistence/Mappers/ContentMapper.cs index 3c96d9d60d..7d2f73bac4 100644 --- a/src/Umbraco.Core/Persistence/Mappers/ContentMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/ContentMapper.cs @@ -14,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(IContent))] public sealed class ContentMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -25,6 +25,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { if(PropertyInfoCache.IsEmpty) @@ -52,23 +57,7 @@ namespace Umbraco.Core.Persistence.Mappers //CacheMap(src => src.Template, dto => dto.TemplateId); } } - - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } - + #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs index c15b0a09fd..bb6e7e1423 100644 --- a/src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs @@ -14,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(IContentType))] public sealed class ContentTypeMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -25,6 +25,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { if (PropertyInfoCache.IsEmpty) @@ -48,22 +53,6 @@ namespace Umbraco.Core.Persistence.Mappers } } - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } - #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/DataTypeDefinitionMapper.cs b/src/Umbraco.Core/Persistence/Mappers/DataTypeDefinitionMapper.cs index 27cd0e08c9..bc847431f8 100644 --- a/src/Umbraco.Core/Persistence/Mappers/DataTypeDefinitionMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/DataTypeDefinitionMapper.cs @@ -14,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(IDataTypeDefinition))] public sealed class DataTypeDefinitionMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -25,6 +25,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { CacheMap(src => src.Id, dto => dto.NodeId); @@ -42,22 +47,6 @@ namespace Umbraco.Core.Persistence.Mappers } - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } - #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/DictionaryMapper.cs b/src/Umbraco.Core/Persistence/Mappers/DictionaryMapper.cs index 55b7246c3f..fddbee347a 100644 --- a/src/Umbraco.Core/Persistence/Mappers/DictionaryMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/DictionaryMapper.cs @@ -14,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(IDictionaryItem))] public sealed class DictionaryMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -25,6 +25,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { CacheMap(src => src.Id, dto => dto.PrimaryKey); @@ -32,23 +37,7 @@ namespace Umbraco.Core.Persistence.Mappers CacheMap(src => src.ItemKey, dto => dto.Key); CacheMap(src => src.ParentId, dto => dto.Parent); } - - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } - + #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/DictionaryTranslationMapper.cs b/src/Umbraco.Core/Persistence/Mappers/DictionaryTranslationMapper.cs index be42a5bbb2..ebd39d95a3 100644 --- a/src/Umbraco.Core/Persistence/Mappers/DictionaryTranslationMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/DictionaryTranslationMapper.cs @@ -14,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(IDictionaryTranslation))] public class DictionaryTranslationMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -25,6 +25,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { CacheMap(src => src.Id, dto => dto.PrimaryKey); @@ -33,22 +38,6 @@ namespace Umbraco.Core.Persistence.Mappers CacheMap(src => src.Value, dto => dto.Value); } - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } - #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/LanguageMapper.cs b/src/Umbraco.Core/Persistence/Mappers/LanguageMapper.cs index 99ffe4fb6c..b891bc7ec8 100644 --- a/src/Umbraco.Core/Persistence/Mappers/LanguageMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/LanguageMapper.cs @@ -14,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(Language))] public sealed class LanguageMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -25,6 +25,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { CacheMap(src => src.Id, dto => dto.Id); @@ -32,22 +37,6 @@ namespace Umbraco.Core.Persistence.Mappers CacheMap(src => src.CultureName, dto => dto.CultureName); } - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } - #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/MediaMapper.cs b/src/Umbraco.Core/Persistence/Mappers/MediaMapper.cs index 7c8612164e..66f6258527 100644 --- a/src/Umbraco.Core/Persistence/Mappers/MediaMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/MediaMapper.cs @@ -14,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(Umbraco.Core.Models.Media))] public sealed class MediaMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -25,6 +25,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { if (PropertyInfoCache.IsEmpty) @@ -45,22 +50,6 @@ namespace Umbraco.Core.Persistence.Mappers } } - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } - #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/MediaTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/MediaTypeMapper.cs index dd412edfd0..4a7befff00 100644 --- a/src/Umbraco.Core/Persistence/Mappers/MediaTypeMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/MediaTypeMapper.cs @@ -14,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(MediaType))] public sealed class MediaTypeMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -25,6 +25,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { if (PropertyInfoCache.IsEmpty) @@ -48,22 +53,6 @@ namespace Umbraco.Core.Persistence.Mappers } } - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } - #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/PropertyGroupMapper.cs b/src/Umbraco.Core/Persistence/Mappers/PropertyGroupMapper.cs index 241da5bbe0..d911db1967 100644 --- a/src/Umbraco.Core/Persistence/Mappers/PropertyGroupMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/PropertyGroupMapper.cs @@ -13,7 +13,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(PropertyGroup))] public sealed class PropertyGroupMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -24,6 +24,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { CacheMap(src => src.Id, dto => dto.Id); @@ -32,22 +37,6 @@ namespace Umbraco.Core.Persistence.Mappers CacheMap(src => src.Name, dto => dto.Text); } - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } - #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/PropertyMapper.cs b/src/Umbraco.Core/Persistence/Mappers/PropertyMapper.cs index 7d3d5d357c..5d7fd74dc9 100644 --- a/src/Umbraco.Core/Persistence/Mappers/PropertyMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/PropertyMapper.cs @@ -9,7 +9,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(Property))] public sealed class PropertyMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -20,6 +20,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { CacheMap(src => src.Id, dto => dto.Id); @@ -27,22 +32,6 @@ namespace Umbraco.Core.Persistence.Mappers CacheMap(src => src.PropertyTypeId, dto => dto.PropertyTypeId); } - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } - #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/PropertyTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/PropertyTypeMapper.cs index 99bc8a5a1a..6cc4fc901b 100644 --- a/src/Umbraco.Core/Persistence/Mappers/PropertyTypeMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/PropertyTypeMapper.cs @@ -13,7 +13,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(PropertyType))] public sealed class PropertyTypeMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -24,6 +24,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { if(PropertyInfoCache.IsEmpty) @@ -42,22 +47,6 @@ namespace Umbraco.Core.Persistence.Mappers } } - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } - #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/RelationMapper.cs b/src/Umbraco.Core/Persistence/Mappers/RelationMapper.cs index 1b211795ff..f67c022f62 100644 --- a/src/Umbraco.Core/Persistence/Mappers/RelationMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/RelationMapper.cs @@ -13,7 +13,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(Relation))] public sealed class RelationMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -24,6 +24,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { CacheMap(src => src.Id, dto => dto.Id); @@ -33,23 +38,7 @@ namespace Umbraco.Core.Persistence.Mappers CacheMap(src => src.ParentId, dto => dto.ParentId); CacheMap(src => src.RelationTypeId, dto => dto.RelationType); } - - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } - + #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/RelationTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/RelationTypeMapper.cs index 57461ba288..610667cf05 100644 --- a/src/Umbraco.Core/Persistence/Mappers/RelationTypeMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/RelationTypeMapper.cs @@ -13,7 +13,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(RelationType))] public sealed class RelationTypeMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -24,6 +24,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { CacheMap(src => src.Id, dto => dto.Id); @@ -33,23 +38,7 @@ namespace Umbraco.Core.Persistence.Mappers CacheMap(src => src.Name, dto => dto.Name); CacheMap(src => src.ParentObjectType, dto => dto.ParentObjectType); } - - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } - + #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/ServerRegistrationMapper.cs b/src/Umbraco.Core/Persistence/Mappers/ServerRegistrationMapper.cs index 8f3c465564..24b0632f8a 100644 --- a/src/Umbraco.Core/Persistence/Mappers/ServerRegistrationMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/ServerRegistrationMapper.cs @@ -9,7 +9,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(ServerRegistration))] public sealed class ServerRegistrationMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -20,6 +20,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { CacheMap(src => src.Id, dto => dto.Id); @@ -30,22 +35,6 @@ namespace Umbraco.Core.Persistence.Mappers CacheMap(src => src.ComputerName, dto => dto.ComputerName); } - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } - #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/UmbracoEntityMapper.cs b/src/Umbraco.Core/Persistence/Mappers/UmbracoEntityMapper.cs index d1abd4043f..248d5ebc42 100644 --- a/src/Umbraco.Core/Persistence/Mappers/UmbracoEntityMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/UmbracoEntityMapper.cs @@ -9,8 +9,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof (IUmbracoEntity))] public sealed class UmbracoEntityMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = - new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -21,6 +20,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { CacheMap(src => src.Id, dto => dto.NodeId); @@ -34,24 +38,7 @@ namespace Umbraco.Core.Persistence.Mappers CacheMap(src => src.Key, dto => dto.UniqueId); CacheMap(src => src.CreatorId, dto => dto.UserId); } - - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, - Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } - + #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/UserMapper.cs b/src/Umbraco.Core/Persistence/Mappers/UserMapper.cs index a8235374be..1a7add097a 100644 --- a/src/Umbraco.Core/Persistence/Mappers/UserMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/UserMapper.cs @@ -10,7 +10,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(User))] public sealed class UserMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -21,6 +21,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { CacheMap(src => src.Id, dto => dto.Id); @@ -38,22 +43,6 @@ namespace Umbraco.Core.Persistence.Mappers CacheMap(src => src.Language, dto => dto.UserLanguage); } - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } - #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/UserSectionMapper.cs b/src/Umbraco.Core/Persistence/Mappers/UserSectionMapper.cs new file mode 100644 index 0000000000..9256803f0d --- /dev/null +++ b/src/Umbraco.Core/Persistence/Mappers/UserSectionMapper.cs @@ -0,0 +1,34 @@ +using System.Collections.Concurrent; +using Umbraco.Core.Models; +using Umbraco.Core.Models.Rdbms; + +namespace Umbraco.Core.Persistence.Mappers +{ + [MapperFor(typeof(UserSection))] + public sealed class UserSectionMapper : BaseMapper + { + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); + + //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it + // otherwise that would fail because there is no public constructor. + public UserSectionMapper() + { + BuildMap(); + } + + #region Overrides of BaseMapper + + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + + internal override void BuildMap() + { + CacheMap(src => src.Id, dto => dto.UserId); + CacheMap(src => src.SectionAlias, dto => dto.AppAlias); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/UserTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/UserTypeMapper.cs index 6858ff0610..82f362b6f4 100644 --- a/src/Umbraco.Core/Persistence/Mappers/UserTypeMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/UserTypeMapper.cs @@ -14,7 +14,7 @@ namespace Umbraco.Core.Persistence.Mappers [MapperFor(typeof(UserType))] public sealed class UserTypeMapper : BaseMapper { - private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); //NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it // otherwise that would fail because there is no public constructor. @@ -25,6 +25,11 @@ namespace Umbraco.Core.Persistence.Mappers #region Overrides of BaseMapper + internal override ConcurrentDictionary PropertyInfoCache + { + get { return PropertyInfoCacheInstance; } + } + internal override void BuildMap() { CacheMap(src => src.Id, dto => dto.Id); @@ -33,21 +38,6 @@ namespace Umbraco.Core.Persistence.Mappers CacheMap(src => src.Permissions, dto => dto.DefaultPermissions); } - internal override string Map(string propertyName) - { - if (!PropertyInfoCache.ContainsKey(propertyName)) - return string.Empty; - - var dtoTypeProperty = PropertyInfoCache[propertyName]; - - return base.GetColumnName(dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo); - } - - internal override void CacheMap(Expression> sourceMember, Expression> destinationMember) - { - var property = base.ResolveMapping(sourceMember, destinationMember); - PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property); - } #endregion } diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IRepository.cs index 2a825d3449..9cb4d938c7 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IRepository.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace Umbraco.Core.Persistence.Repositories { - /// + /// /// Defines the base implementation of a Repository /// /// diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserSectionRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserSectionRepository.cs new file mode 100644 index 0000000000..8acd59895f --- /dev/null +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserSectionRepository.cs @@ -0,0 +1,10 @@ +using System; +using Umbraco.Core.Models; + +namespace Umbraco.Core.Persistence.Repositories +{ + internal interface IUserSectionRepository : IRepository, UserSection> + { + + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/UserSectionRepository.cs b/src/Umbraco.Core/Persistence/Repositories/UserSectionRepository.cs new file mode 100644 index 0000000000..f0b90cc566 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Repositories/UserSectionRepository.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Umbraco.Core.Models; +using Umbraco.Core.Models.EntityBase; +using Umbraco.Core.Models.Rdbms; +using Umbraco.Core.Persistence.Caching; +using Umbraco.Core.Persistence.Factories; +using Umbraco.Core.Persistence.Querying; +using Umbraco.Core.Persistence.UnitOfWork; + +namespace Umbraco.Core.Persistence.Repositories +{ + internal class UserSectionRepository : PetaPocoRepositoryBase, UserSection>, IUserSectionRepository, IUnitOfWorkRepository + { + public UserSectionRepository(IDatabaseUnitOfWork work) : base(work) + { + } + + public UserSectionRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache) : base(work, cache) + { + } + + protected override UserSection PerformGet(Tuple id) + { + var sql = GetBaseQuery(false); + sql.Where(GetBaseWhereClause(), new { Id = id }); + var dto = Database.First(sql); + if (dto == null) + return null; + var factory = new UserSectionFactory(); + var entity = factory.BuildEntity(dto); + return entity; + } + + protected override IEnumerable PerformGetAll(params Tuple[] ids) + { + if (ids.Any()) + { + foreach (var id in ids) + { + yield return Get(id); + } + } + else + { + var factory = new UserSectionFactory(); + foreach (var u in Database.Fetch("WHERE user > 0") + .Select(factory.BuildEntity)) + { + yield return u; + } + } + } + + protected override IEnumerable PerformGetByQuery(IQuery query) + { + var sqlClause = GetBaseQuery(false); + var translator = new SqlTranslator(sqlClause, query); + var sql = translator.Translate(); + + var dtos = Database.Fetch(sql); + + return dtos.Select(dto => Get( + new Tuple(dto.UserId, dto.AppAlias))); + } + + protected override Sql GetBaseQuery(bool isCount) + { + var sql = new Sql(); + sql.Select(isCount ? "COUNT(*)" : "*") + .From(); + return sql; + } + + protected override string GetBaseWhereClause() + { + return "user = @Id"; + } + + protected override IEnumerable GetDeleteClauses() + { + var list = new List + { + "DELETE FROM umbracoUser2app WHERE user = @Id AND app = @Section" + }; + return list; + } + + protected override Guid NodeObjectTypeId + { + get { throw new NotImplementedException(); } + } + + protected override void PersistNewItem(UserSection entity) + { + var factory = new UserSectionFactory(); + var dto = factory.BuildDto(entity); + + var id = Convert.ToInt32(Database.Insert(dto)); + entity.Id = id; + } + + protected override void PersistUpdatedItem(UserSection entity) + { + var factory = new UserSectionFactory(); + var dto = factory.BuildDto(entity); + Database.Update(dto); + } + + protected override void PersistDeletedItem(UserSection entity) + { + var deletes = GetDeleteClauses(); + foreach (var delete in deletes) + { + //ensure that we include SectionAlias since its a composite key + Database.Execute(delete, new { Id = entity.Id, Section = entity.SectionAlias }); + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/RepositoryFactory.cs b/src/Umbraco.Core/Persistence/RepositoryFactory.cs index 38189576a7..034b375ef4 100644 --- a/src/Umbraco.Core/Persistence/RepositoryFactory.cs +++ b/src/Umbraco.Core/Persistence/RepositoryFactory.cs @@ -69,6 +69,14 @@ namespace Umbraco.Core.Persistence CreateLanguageRepository(uow)); } + internal virtual IUserSectionRepository CreateUserSectionRepository(IDatabaseUnitOfWork uow) + { + return new UserSectionRepository( + uow, + //Null cache here? I dunno? + NullCacheProvider.Current); + } + public virtual ILanguageRepository CreateLanguageRepository(IDatabaseUnitOfWork uow) { return new LanguageRepository( diff --git a/src/Umbraco.Core/Trees/ApplicationTreeCollection.cs b/src/Umbraco.Core/Services/ApplicationTreeService.cs similarity index 80% rename from src/Umbraco.Core/Trees/ApplicationTreeCollection.cs rename to src/Umbraco.Core/Services/ApplicationTreeService.cs index ecc074ce23..bb1e48b1c6 100644 --- a/src/Umbraco.Core/Trees/ApplicationTreeCollection.cs +++ b/src/Umbraco.Core/Services/ApplicationTreeService.cs @@ -6,11 +6,20 @@ using System.Xml.Linq; using Umbraco.Core.Cache; using Umbraco.Core.Events; using Umbraco.Core.IO; +using Umbraco.Core.Models; +using File = System.IO.File; -namespace Umbraco.Core.Trees +namespace Umbraco.Core.Services { - internal class ApplicationTreeCollection + internal class ApplicationTreeService { + private readonly CacheHelper _cache; + + public ApplicationTreeService(CacheHelper cache) + { + _cache = cache; + } + internal const string TreeConfigFileName = "trees.config"; private static string _treeConfig; private static readonly object Locker = new object(); @@ -37,37 +46,34 @@ namespace Umbraco.Core.Trees /// /// The cache storage for all application trees /// - private static List AppTrees + private List GetAppTrees() { - get - { - return ApplicationContext.Current.ApplicationCache.GetCacheItem( - CacheKeys.ApplicationTreeCacheKey, - () => - { - var list = new List(); + return _cache.GetCacheItem( + CacheKeys.ApplicationTreeCacheKey, + () => + { + var list = new List(); - LoadXml(doc => + LoadXml(doc => { foreach (var addElement in doc.Root.Elements("add").OrderBy(x => + { + var sortOrderAttr = x.Attribute("sortOrder"); + return sortOrderAttr != null ? Convert.ToInt32(sortOrderAttr.Value) : 0; + })) { - var sortOrderAttr = x.Attribute("sortOrder"); - return sortOrderAttr != null ? Convert.ToInt32(sortOrderAttr.Value) : 0; - })) - { - - var applicationAlias = (string)addElement.Attribute("application"); - var type = (string)addElement.Attribute("type"); - var assembly = (string)addElement.Attribute("assembly"); + var applicationAlias = (string) addElement.Attribute("application"); + var type = (string) addElement.Attribute("type"); + var assembly = (string) addElement.Attribute("assembly"); //check if the tree definition (applicationAlias + type + assembly) is already in the list if (list.Any(tree => tree.ApplicationAlias.InvariantEquals(applicationAlias) && tree.Type.InvariantEquals(type)) == false) { - list.Add(new ApplicationTree( + list.Add(new ApplicationTree( addElement.Attribute("initialize") == null || Convert.ToBoolean(addElement.Attribute("initialize").Value), - addElement.Attribute("sortOrder") != null ? Convert.ToByte(addElement.Attribute("sortOrder").Value) : (byte)0, + addElement.Attribute("sortOrder") != null ? Convert.ToByte(addElement.Attribute("sortOrder").Value) : (byte) 0, addElement.Attribute("application").Value, addElement.Attribute("alias").Value, addElement.Attribute("title").Value, @@ -75,17 +81,13 @@ namespace Umbraco.Core.Trees addElement.Attribute("iconOpen").Value, addElement.Attribute("type").Value)); } - - } }, false); - return list; - }); - } + return list; + }); } - /// /// Creates a new application tree. /// @@ -97,7 +99,7 @@ namespace Umbraco.Core.Trees /// The icon closed. /// The icon opened. /// The type. - public static void MakeNew(bool initialize, byte sortOrder, string applicationAlias, string alias, string title, string iconClosed, string iconOpened, string type) + public void MakeNew(bool initialize, byte sortOrder, string applicationAlias, string alias, string title, string iconClosed, string iconOpened, string type) { LoadXml(doc => { @@ -123,7 +125,7 @@ namespace Umbraco.Core.Trees /// /// Saves this instance. /// - public static void SaveTree(ApplicationTree tree) + public void SaveTree(ApplicationTree tree) { LoadXml(doc => { @@ -151,7 +153,7 @@ namespace Umbraco.Core.Trees /// /// Deletes this instance. /// - public static void DeleteTree(ApplicationTree tree) + public void DeleteTree(ApplicationTree tree) { LoadXml(doc => { @@ -167,9 +169,9 @@ namespace Umbraco.Core.Trees /// /// The tree alias. /// An ApplicationTree instance - public static ApplicationTree GetByAlias(string treeAlias) + public ApplicationTree GetByAlias(string treeAlias) { - return AppTrees.Find(t => (t.Alias == treeAlias)); + return GetAppTrees().Find(t => (t.Alias == treeAlias)); } @@ -177,9 +179,9 @@ namespace Umbraco.Core.Trees /// Gets all applicationTrees registered in umbraco from the umbracoAppTree table.. /// /// Returns a ApplicationTree Array - public static IEnumerable GetAll() + public IEnumerable GetAll() { - return AppTrees.OrderBy(x => x.SortOrder); + return GetAppTrees().OrderBy(x => x.SortOrder); } /// @@ -187,9 +189,9 @@ namespace Umbraco.Core.Trees /// /// The application alias. /// Returns a ApplicationTree Array - public static IEnumerable GetApplicationTree(string applicationAlias) + public IEnumerable GetApplicationTrees(string applicationAlias) { - return GetApplicationTree(applicationAlias, false); + return GetApplicationTrees(applicationAlias, false); } /// @@ -198,9 +200,9 @@ namespace Umbraco.Core.Trees /// The application alias. /// /// Returns a ApplicationTree Array - public static IEnumerable GetApplicationTree(string applicationAlias, bool onlyInitializedApplications) + public IEnumerable GetApplicationTrees(string applicationAlias, bool onlyInitializedApplications) { - var list = AppTrees.FindAll( + var list = GetAppTrees().FindAll( t => { if (onlyInitializedApplications) @@ -212,7 +214,7 @@ namespace Umbraco.Core.Trees return list.OrderBy(x => x.SortOrder).ToArray(); } - internal static void LoadXml(Action callback, bool saveAfterCallback) + internal void LoadXml(Action callback, bool saveAfterCallback) { lock (Locker) { @@ -231,7 +233,7 @@ namespace Umbraco.Core.Trees //remove the cache now that it has changed SD: I'm leaving this here even though it // is taken care of by events as well, I think unit tests may rely on it being cleared here. - ApplicationContext.Current.ApplicationCache.ClearCacheItem(CacheKeys.ApplicationTreeCacheKey); + _cache.ClearCacheItem(CacheKeys.ApplicationTreeCacheKey); } } } diff --git a/src/Umbraco.Core/Sections/SectionCollection.cs b/src/Umbraco.Core/Services/SectionService.cs similarity index 60% rename from src/Umbraco.Core/Sections/SectionCollection.cs rename to src/Umbraco.Core/Services/SectionService.cs index 8b3f51c49f..2a895eab0a 100644 --- a/src/Umbraco.Core/Sections/SectionCollection.cs +++ b/src/Umbraco.Core/Services/SectionService.cs @@ -3,18 +3,41 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; using System.Xml.Linq; using Umbraco.Core.Cache; using Umbraco.Core.Events; using Umbraco.Core.IO; -using Umbraco.Core.Trees; +using Umbraco.Core.Models; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.UnitOfWork; +using File = System.IO.File; -namespace Umbraco.Core.Sections +namespace Umbraco.Core.Services { - public class SectionCollection + internal class SectionService { + private readonly IDatabaseUnitOfWorkProvider _uowProvider; + private readonly RepositoryFactory _repositoryFactory; + private readonly EntityService _entityService; + private readonly ApplicationTreeService _applicationTreeService; + private readonly CacheHelper _cache; + + public SectionService( + IDatabaseUnitOfWorkProvider uowProvider, + RepositoryFactory repositoryFactory, + EntityService entityService, + ApplicationTreeService applicationTreeService, + CacheHelper cache) + { + if (applicationTreeService == null) throw new ArgumentNullException("applicationTreeService"); + if (cache == null) throw new ArgumentNullException("cache"); + _uowProvider = uowProvider; + _repositoryFactory = repositoryFactory; + _entityService = entityService; + _applicationTreeService = applicationTreeService; + _cache = cache; + } + internal const string AppConfigFileName = "applications.config"; private static string _appConfig; private static readonly object Locker = new object(); @@ -41,13 +64,11 @@ namespace Umbraco.Core.Sections /// /// The cache storage for all applications /// - internal static IEnumerable
Sections + internal IEnumerable
GetSections() { - get - { - return ApplicationContext.Current.ApplicationCache.GetCacheItem( - CacheKeys.ApplicationsCacheKey, - () => + return _cache.GetCacheItem( + CacheKeys.ApplicationsCacheKey, + () => { ////used for unit tests //if (_testApps != null) @@ -56,27 +77,25 @@ namespace Umbraco.Core.Sections var tmp = new List
(); LoadXml(doc => - { - foreach (var addElement in doc.Root.Elements("add").OrderBy(x => { - var sortOrderAttr = x.Attribute("sortOrder"); - return sortOrderAttr != null ? Convert.ToInt32(sortOrderAttr.Value) : 0; - })) - { - var sortOrderAttr = addElement.Attribute("sortOrder"); - tmp.Add(new Section(addElement.Attribute("name").Value, + foreach (var addElement in doc.Root.Elements("add").OrderBy(x => + { + var sortOrderAttr = x.Attribute("sortOrder"); + return sortOrderAttr != null ? Convert.ToInt32(sortOrderAttr.Value) : 0; + })) + { + var sortOrderAttr = addElement.Attribute("sortOrder"); + tmp.Add(new Section(addElement.Attribute("name").Value, addElement.Attribute("alias").Value, addElement.Attribute("icon").Value, sortOrderAttr != null ? Convert.ToInt32(sortOrderAttr.Value) : 0)); - } - - }, false); + } + }, false); return tmp; }); - } } - internal static void LoadXml(Action callback, bool saveAfterCallback) + internal void LoadXml(Action callback, bool saveAfterCallback) { lock (Locker) { @@ -97,20 +116,48 @@ namespace Umbraco.Core.Sections //remove the cache so it gets re-read ... SD: I'm leaving this here even though it // is taken care of by events as well, I think unit tests may rely on it being cleared here. - ApplicationContext.Current.ApplicationCache.ClearCacheItem(CacheKeys.ApplicationsCacheKey); + _cache.ClearCacheItem(CacheKeys.ApplicationsCacheKey); } } } } + /// + /// Get the user's allowed sections + /// + /// + /// + public IEnumerable
GetAllowedSections(int userId) + { + var allApps = GetSections(); + var apps = new List
(); + + using (var repository = _repositoryFactory.CreateUserSectionRepository(_uowProvider.GetUnitOfWork())) + { + return repository.Get(id); + } + + //using (IRecordsReader appIcons = SqlHelper.ExecuteReader("select app from umbracoUser2app where [user] = @userID", SqlHelper.CreateParameter("@userID", this.Id))) + //{ + // while (appIcons.Read()) + // { + // var app = allApps.SingleOrDefault(x => x.alias == appIcons.GetString("app")); + // if (app != null) + // apps.Add(app); + // } + //} + + return apps; + } + /// /// Gets the application by its alias. /// /// The application alias. /// - public static Section GetByAlias(string appAlias) + public Section GetByAlias(string appAlias) { - return Sections.FirstOrDefault(t => t.Alias == appAlias); + return GetSections().FirstOrDefault(t => t.Alias == appAlias); } /// @@ -120,9 +167,9 @@ namespace Umbraco.Core.Sections /// The application alias. /// The application icon, which has to be located in umbraco/images/tray folder. [MethodImpl(MethodImplOptions.Synchronized)] - public static void MakeNew(string name, string alias, string icon) + public void MakeNew(string name, string alias, string icon) { - MakeNew(name, alias, icon, Sections.Max(x => x.SortOrder) + 1); + MakeNew(name, alias, icon, GetSections().Max(x => x.SortOrder) + 1); } /// @@ -133,9 +180,9 @@ namespace Umbraco.Core.Sections /// The icon. /// The sort order. [MethodImpl(MethodImplOptions.Synchronized)] - public static void MakeNew(string name, string alias, string icon, int sortOrder) + public void MakeNew(string name, string alias, string icon, int sortOrder) { - if (Sections.All(x => x.Alias != alias)) + if (GetSections().All(x => x.Alias != alias)) { LoadXml(doc => { @@ -154,7 +201,7 @@ namespace Umbraco.Core.Sections /// /// Deletes the section /// - public static void DeleteSection(Section section) + public void DeleteSection(Section section) { lock (Locker) { @@ -164,10 +211,10 @@ namespace Umbraco.Core.Sections new { appAlias = section.Alias }); //delete the assigned trees - var trees = ApplicationTreeCollection.GetApplicationTree(section.Alias); + var trees = _applicationTreeService.GetApplicationTrees(section.Alias); foreach (var t in trees) { - ApplicationTreeCollection.DeleteTree(t); + _applicationTreeService.DeleteTree(t); } LoadXml(doc => diff --git a/src/Umbraco.Core/Services/ServiceContext.cs b/src/Umbraco.Core/Services/ServiceContext.cs index d03307eaa5..38e4e075d3 100644 --- a/src/Umbraco.Core/Services/ServiceContext.cs +++ b/src/Umbraco.Core/Services/ServiceContext.cs @@ -24,6 +24,8 @@ namespace Umbraco.Core.Services private Lazy _serverRegistrationService; private Lazy _entityService; private Lazy _relationService; + private Lazy _treeService; + private Lazy _sectionService; /// /// Constructor @@ -31,9 +33,9 @@ namespace Umbraco.Core.Services /// /// /// - internal ServiceContext(IDatabaseUnitOfWorkProvider dbUnitOfWorkProvider, IUnitOfWorkProvider fileUnitOfWorkProvider, BasePublishingStrategy publishingStrategy) + internal ServiceContext(IDatabaseUnitOfWorkProvider dbUnitOfWorkProvider, IUnitOfWorkProvider fileUnitOfWorkProvider, BasePublishingStrategy publishingStrategy, CacheHelper cache) { - BuildServiceCache(dbUnitOfWorkProvider, fileUnitOfWorkProvider, publishingStrategy, + BuildServiceCache(dbUnitOfWorkProvider, fileUnitOfWorkProvider, publishingStrategy, cache, //this needs to be lazy because when we create the service context it's generally before the //resolvers have been initialized! new Lazy(() => RepositoryResolver.Current.Factory)); @@ -46,6 +48,7 @@ namespace Umbraco.Core.Services IDatabaseUnitOfWorkProvider dbUnitOfWorkProvider, IUnitOfWorkProvider fileUnitOfWorkProvider, BasePublishingStrategy publishingStrategy, + CacheHelper cache, Lazy repositoryFactory) { var provider = dbUnitOfWorkProvider; @@ -86,6 +89,12 @@ namespace Umbraco.Core.Services if(_relationService == null) _relationService = new Lazy(() => new RelationService(provider, repositoryFactory.Value, _entityService.Value)); + + if (_treeService == null) + _treeService = new Lazy(() => new ApplicationTreeService(cache)); + + if (_sectionService == null) + _sectionService = new Lazy(() => new SectionService(provider, repositoryFactory.Value, _entityService.Value, _treeService.Value, cache)); } /// @@ -183,5 +192,21 @@ namespace Umbraco.Core.Services { get { return _memberService.Value; } } + + /// + /// Gets the + /// + internal SectionService SectionService + { + get { return _sectionService.Value; } + } + + /// + /// Gets the + /// + internal ApplicationTreeService ApplicationTreeService + { + get { return _treeService.Value; } + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Standalone/ServiceContextManager.cs b/src/Umbraco.Core/Standalone/ServiceContextManager.cs index 579bde0ff2..fb4c36d5c2 100644 --- a/src/Umbraco.Core/Standalone/ServiceContextManager.cs +++ b/src/Umbraco.Core/Standalone/ServiceContextManager.cs @@ -51,7 +51,8 @@ namespace Umbraco.Core.Standalone _serviceContext = new ServiceContext( new PetaPocoUnitOfWorkProvider(dbFactory), new FileUnitOfWorkProvider(), - new PublishingStrategy()); + new PublishingStrategy(), + new CacheHelper(new System.Web.Caching.Cache(), true)); //initialize the DatabaseContext dbContext.Initialize(_providerName); diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index e3de933b23..42054baf8e 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -251,14 +251,17 @@ + + + @@ -335,6 +338,7 @@ + @@ -503,6 +507,7 @@ + @@ -516,6 +521,7 @@ + @@ -690,8 +696,8 @@ - - + + @@ -754,8 +760,8 @@ - - + + diff --git a/src/Umbraco.Tests/BusinessLogic/BaseTest.cs b/src/Umbraco.Tests/BusinessLogic/BaseTest.cs deleted file mode 100644 index 1f3173b926..0000000000 --- a/src/Umbraco.Tests/BusinessLogic/BaseTest.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using AutoMapper; -using NUnit.Framework; -using SqlCE4Umbraco; -using Umbraco.Core; -using Umbraco.Core.IO; -using Umbraco.Core.Models.Mapping; -using Umbraco.Core.Sections; -using Umbraco.Tests.TestHelpers; -using umbraco.BusinessLogic; -using umbraco.DataLayer; -using GlobalSettings = umbraco.GlobalSettings; - -namespace Umbraco.Tests.BusinessLogic -{ - [TestFixture, RequiresSTA] - public abstract class BaseTest - { - /// - /// Removes any resources that were used for the test - /// - [TearDown] - public void Dispose() - { - ClearDatabase(); - ConfigurationManager.AppSettings.Set(Core.Configuration.GlobalSettings.UmbracoConnectionName, ""); - ApplicationContext.Current.DisposeIfDisposable(); - } - - /// - /// Ensures everything is setup to allow for unit tests to execute for each test - /// - [SetUp] - public void Initialize() - { - ApplicationContext.Current = new ApplicationContext(false){IsReady = true}; - InitializeMappers(); - InitializeDatabase(); - InitializeApps(); - InitializeAppConfigFile(); - InitializeTreeConfigFile(); - } - - private void InitializeMappers() - { - Mapper.Initialize(configuration => - { - var mappers = PluginManager.Current.FindAndCreateInstances(); - foreach (var mapper in mappers) - { - mapper.ConfigureMappings(configuration); - } - }); - } - - private void ClearDatabase() - { - var databaseSettings = ConfigurationManager.ConnectionStrings[Core.Configuration.GlobalSettings.UmbracoConnectionName]; - var dataHelper = DataLayerHelper.CreateSqlHelper(databaseSettings.ConnectionString, false) as SqlCEHelper; - - if (dataHelper == null) - throw new InvalidOperationException("The sql helper for unit tests must be of type SqlCEHelper, check the ensure the connection string used for this test is set to use SQLCE"); - dataHelper.ClearDatabase(); - - AppDomain.CurrentDomain.SetData("DataDirectory", null); - } - - private void InitializeDatabase() - { - ConfigurationManager.AppSettings.Set(Core.Configuration.GlobalSettings.UmbracoConnectionName, @"datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;data source=|DataDirectory|\UmbracoPetaPocoTests.sdf"); - - ClearDatabase(); - - AppDomain.CurrentDomain.SetData("DataDirectory", TestHelper.CurrentAssemblyDirectory); - - var databaseSettings = ConfigurationManager.ConnectionStrings[Core.Configuration.GlobalSettings.UmbracoConnectionName]; - var dataHelper = DataLayerHelper.CreateSqlHelper(databaseSettings.ConnectionString, false) as SqlCEHelper; - - var installer = dataHelper.Utility.CreateInstaller(); - if (installer.CanConnect) - { - installer.Install(); - } - } - - private void InitializeApps() - { - SectionCollection.MakeNew("content", "content", "file", 0); - //Application.SetTestApps(new List() - // { - // new Application(Constants.Applications.Content, "content", "content", 0) - // }); - } - - private void InitializeAppConfigFile() - { - SectionCollection.AppConfigFilePath = IOHelper.MapPath(SystemDirectories.Config + "/" + SectionCollection.AppConfigFileName, false); - } - - private void InitializeTreeConfigFile() - { - Core.Trees.ApplicationTreeCollection.TreeConfigFilePath = IOHelper.MapPath(SystemDirectories.Config + "/" + Core.Trees.ApplicationTreeCollection.TreeConfigFileName, false); - } - - } -} \ No newline at end of file diff --git a/src/Umbraco.Tests/Masterpages/dummy.txt b/src/Umbraco.Tests/Masterpages/dummy.txt deleted file mode 100644 index 9c01dce8f4..0000000000 --- a/src/Umbraco.Tests/Masterpages/dummy.txt +++ /dev/null @@ -1 +0,0 @@ -This file is just here to make sure the directory gets created. \ No newline at end of file diff --git a/src/Umbraco.Tests/Persistence/BaseTableByTableTest.cs b/src/Umbraco.Tests/Persistence/BaseTableByTableTest.cs index f8f56d6dcb..d03ddc3142 100644 --- a/src/Umbraco.Tests/Persistence/BaseTableByTableTest.cs +++ b/src/Umbraco.Tests/Persistence/BaseTableByTableTest.cs @@ -1,6 +1,7 @@ using System; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Cache; using Umbraco.Core.Configuration; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.ObjectResolution; @@ -27,14 +28,16 @@ namespace Umbraco.Tests.Persistence RepositoryResolver.Current = new RepositoryResolver( new RepositoryFactory()); - + + //disable cache + var cacheHelper = new CacheHelper(new NullCacheProvider(), false); + ApplicationContext.Current = new ApplicationContext( //assign the db context new DatabaseContext(new DefaultDatabaseFactory()), //assign the service context - new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy()), - //disable cache - false) + new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy(), cacheHelper), + cacheHelper) { IsReady = true }; diff --git a/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs b/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs index 1c7f2a39e6..7ba9ebc917 100644 --- a/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs +++ b/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Threading; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Cache; using Umbraco.Core.Models; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.UnitOfWork; @@ -37,11 +38,14 @@ namespace Umbraco.Tests.Services //overwrite the local object ApplicationContext.DatabaseContext = new DatabaseContext(_dbFactory); + //disable cache + var cacheHelper = new CacheHelper(new NullCacheProvider(), false); + //here we are going to override the ServiceContext because normally with our test cases we use a //global Database object but this is NOT how it should work in the web world or in any multi threaded scenario. //we need a new Database object for each thread. - _uowProvider = new PerThreadPetaPocoUnitOfWorkProvider(_dbFactory); - ApplicationContext.Services = new ServiceContext(_uowProvider, new FileUnitOfWorkProvider(), new PublishingStrategy()); + _uowProvider = new PerThreadPetaPocoUnitOfWorkProvider(_dbFactory); + ApplicationContext.Services = new ServiceContext(_uowProvider, new FileUnitOfWorkProvider(), new PublishingStrategy(), cacheHelper); CreateTestData(); } diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs index 8b46559528..f521b78c1e 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs @@ -4,6 +4,7 @@ using System.Data.SqlServerCe; using System.IO; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Cache; using Umbraco.Core.Configuration; using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence; @@ -60,13 +61,16 @@ namespace Umbraco.Tests.TestHelpers new List { typeof(MySqlSyntaxProvider), typeof(SqlCeSyntaxProvider), typeof(SqlServerSyntaxProvider) }) { CanResolveBeforeFrozen = true }; Resolution.Freeze(); + + //disable cache + var cacheHelper = new CacheHelper(new NullCacheProvider(), false); + ApplicationContext.Current = new ApplicationContext( //assign the db context new DatabaseContext(new DefaultDatabaseFactory()), //assign the service context - new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy()), - //disable cache - false) + new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy(), cacheHelper), + cacheHelper) { IsReady = true }; diff --git a/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs b/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs index 51c71edad8..93be44f03e 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs @@ -1,6 +1,7 @@ using AutoMapper; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Cache; using Umbraco.Core.Configuration; using Umbraco.Core.Models.Mapping; using Umbraco.Core.ObjectResolution; @@ -81,13 +82,15 @@ namespace Umbraco.Tests.TestHelpers /// protected virtual void SetupApplicationContext() { + //disable cache + var cacheHelper = new CacheHelper(new NullCacheProvider(), false); + ApplicationContext.Current = new ApplicationContext( //assign the db context new DatabaseContext(new DefaultDatabaseFactory()), //assign the service context - new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy()), - //disable cache - false) + new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy(), cacheHelper), + cacheHelper) { IsReady = true }; diff --git a/src/Umbraco.Tests/TreesAndSections/ApplicationTreeTest.cs b/src/Umbraco.Tests/TreesAndSections/ApplicationTreeTest.cs index 03a8f00882..7f83e09680 100644 --- a/src/Umbraco.Tests/TreesAndSections/ApplicationTreeTest.cs +++ b/src/Umbraco.Tests/TreesAndSections/ApplicationTreeTest.cs @@ -1,6 +1,5 @@ using NUnit.Framework; -using Umbraco.Core.Sections; -using Umbraco.Core.Trees; +using Umbraco.Core.Services; using Umbraco.Tests.TestHelpers; using System; using System.Linq; @@ -26,22 +25,22 @@ namespace Umbraco.Tests.TreesAndSections { //create new app var name = Guid.NewGuid().ToString("N"); - SectionCollection.MakeNew(name, name, "icon.jpg"); + ApplicationContext.Services.SectionService.MakeNew(name, name, "icon.jpg"); //check if it exists - var app = SectionCollection.GetByAlias(name); + var app = ApplicationContext.Services.SectionService.GetByAlias(name); Assert.IsNotNull(app); //create the new app tree assigned to the new app - ApplicationTreeCollection.MakeNew(false, 0, app.Alias, name, name, "icon.jpg", "icon.jpg", "nulltype"); - var tree = ApplicationTreeCollection.GetByAlias(name); + ApplicationContext.Services.ApplicationTreeService.MakeNew(false, 0, app.Alias, name, name, "icon.jpg", "icon.jpg", "nulltype"); + var tree = ApplicationContext.Services.ApplicationTreeService.GetByAlias(name); Assert.IsNotNull(tree); //now delete the app - SectionCollection.DeleteSection(app); + ApplicationContext.Services.SectionService.DeleteSection(app); //check that the tree is gone - Assert.AreEqual(0, ApplicationTree.getApplicationTree(name).Count()); + Assert.AreEqual(0, ApplicationContext.Services.ApplicationTreeService.GetApplicationTrees(name).Count()); } diff --git a/src/Umbraco.Tests/TreesAndSections/SectionTests.cs b/src/Umbraco.Tests/TreesAndSections/SectionTests.cs index 6f6d0d8056..7a4e6ec9ae 100644 --- a/src/Umbraco.Tests/TreesAndSections/SectionTests.cs +++ b/src/Umbraco.Tests/TreesAndSections/SectionTests.cs @@ -1,5 +1,5 @@ using NUnit.Framework; -using Umbraco.Core.Sections; +using Umbraco.Core.Services; using Umbraco.Tests.TestHelpers; using umbraco.BusinessLogic; using System; @@ -23,15 +23,15 @@ namespace Umbraco.Tests.TreesAndSections public void Application_Make_New() { var name = Guid.NewGuid().ToString("N"); - SectionCollection.MakeNew(name, name, "icon.jpg"); + ApplicationContext.Current.Services.SectionService.MakeNew(name, name, "icon.jpg"); //check if it exists - var app = SectionCollection.GetByAlias(name); + var app = ApplicationContext.Current.Services.SectionService.GetByAlias(name); Assert.IsNotNull(app); //now remove it - SectionCollection.DeleteSection(app); - Assert.IsNull(SectionCollection.GetByAlias(name)); + ApplicationContext.Current.Services.SectionService.DeleteSection(app); + Assert.IsNull(ApplicationContext.Current.Services.SectionService.GetByAlias(name)); } /// @@ -74,10 +74,10 @@ namespace Umbraco.Tests.TreesAndSections var ut = UserType.GetAllUserTypes().First(); var user = User.MakeNew(name, name, name, ut); - SectionCollection.MakeNew(name, name, "icon.jpg"); + ApplicationContext.Current.Services.SectionService.MakeNew(name, name, "icon.jpg"); //check if it exists - var app = SectionCollection.GetByAlias(name); + var app = ApplicationContext.Current.Services.SectionService.GetByAlias(name); Assert.IsNotNull(app); //assign the app @@ -86,7 +86,7 @@ namespace Umbraco.Tests.TreesAndSections Assert.AreEqual(1, user.Applications.Count(x => x.alias == app.Alias)); //delete the app - SectionCollection.DeleteSection(app); + ApplicationContext.Current.Services.SectionService.DeleteSection(app); //make sure the assigned applications are gone Assert.AreEqual(0, user.Applications.Count(x => x.alias == name)); diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 423a8c2410..e8f5f09701 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -294,7 +294,6 @@ - diff --git a/src/Umbraco.Tests/Views/dummy.txt b/src/Umbraco.Tests/Views/dummy.txt deleted file mode 100644 index 9c01dce8f4..0000000000 --- a/src/Umbraco.Tests/Views/dummy.txt +++ /dev/null @@ -1 +0,0 @@ -This file is just here to make sure the directory gets created. \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/gruntFile.js b/src/Umbraco.Web.UI.Client/gruntFile.js index 6923eff1d4..0aabcb0d59 100644 --- a/src/Umbraco.Web.UI.Client/gruntFile.js +++ b/src/Umbraco.Web.UI.Client/gruntFile.js @@ -38,7 +38,7 @@ module.exports = function (grunt) { connect: { devserver: { options: { - port: 8080, + port: 9999, hostname: '0.0.0.0', base: './build', middleware: function(connect, options){ @@ -58,7 +58,7 @@ module.exports = function (grunt) { open : { dev : { - path: 'http://localhost:8080/belle/' + path: 'http://localhost:9999/belle/' } }, diff --git a/src/Umbraco.Web.UI.Client/src/routes.js b/src/Umbraco.Web.UI.Client/src/routes.js index 42779d20fa..ca0d80e7d7 100644 --- a/src/Umbraco.Web.UI.Client/src/routes.js +++ b/src/Umbraco.Web.UI.Client/src/routes.js @@ -38,4 +38,4 @@ app.run(['security', function (security) { // Get the current user when the application starts // (in case they are still logged in from a previous session) security.requestCurrentUser(); -}]); \ No newline at end of file +}]); \ No newline at end of file diff --git a/src/Umbraco.Web.UI/config/ClientDependency.config b/src/Umbraco.Web.UI/config/ClientDependency.config index 9aed0f5518..3498ebd8c3 100644 --- a/src/Umbraco.Web.UI/config/ClientDependency.config +++ b/src/Umbraco.Web.UI/config/ClientDependency.config @@ -10,7 +10,7 @@ NOTES: * Compression/Combination/Minification is not enabled unless debug="false" is specified on the 'compiliation' element in the web.config * A new version will invalidate both client and server cache and create new persisted files --> - +