Removes need for the IdkMap for content/media services since we have a wrapping repo now, adds tests to verify that caching is active for both INT and GUID

This commit is contained in:
Shannon
2017-08-10 10:52:31 +10:00
parent bdf621049f
commit a97a5dc3fd
5 changed files with 131 additions and 47 deletions

View File

@@ -32,7 +32,6 @@ namespace Umbraco.Core.Services
private readonly EntityXmlSerializer _entitySerializer = new EntityXmlSerializer();
private readonly IDataTypeService _dataTypeService;
private readonly IUserService _userService;
private readonly IdkMap _idkMap;
//Support recursive locks because some of the methods that require locking call other methods that require locking.
//for example, the Move method needs to be locked but this calls the Save method which also needs to be locked.
@@ -44,8 +43,7 @@ namespace Umbraco.Core.Services
ILogger logger,
IEventMessagesFactory eventMessagesFactory,
IDataTypeService dataTypeService,
IUserService userService,
IdkMap idkMap)
IUserService userService)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
{
if (dataTypeService == null) throw new ArgumentNullException("dataTypeService");
@@ -53,7 +51,6 @@ namespace Umbraco.Core.Services
_publishingStrategy = new PublishingStrategy(UowProvider.ScopeProvider, eventMessagesFactory, logger);
_dataTypeService = dataTypeService;
_userService = userService;
_idkMap = idkMap;
}
#region Static Queries
@@ -431,13 +428,11 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IContent"/></returns>
public IContent GetById(Guid key)
{
// the repository implements a cache policy on int identifiers, not guids,
// and we are not changing it now, but we still would like to rely on caching
// instead of running a full query against the database, so relying on the
// id-key map, which is fast.
var a = _idkMap.GetIdForKey(key, UmbracoObjectTypes.Document);
return a.Success ? GetById(a.Result) : null;
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateContentRepository(uow);
return repository.Get(key);
}
}
/// <summary>
@@ -1218,13 +1213,14 @@ namespace Umbraco.Core.Services
public IContent GetBlueprintById(Guid id)
{
// the repository implements a cache policy on int identifiers, not guids,
// and we are not changing it now, but we still would like to rely on caching
// instead of running a full query against the database, so relying on the
// id-key map, which is fast.
var a = _idkMap.GetIdForKey(id, UmbracoObjectTypes.DocumentBlueprint);
return a.Success ? GetBlueprintById(a.Result) : null;
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateContentBlueprintRepository(uow);
var blueprint = repository.Get(id);
if (blueprint != null)
((Content)blueprint).IsBlueprint = true;
return blueprint;
}
}
public void SaveBlueprint(IContent content, int userId = 0)

View File

@@ -35,16 +35,14 @@ namespace Umbraco.Core.Services
private readonly IDataTypeService _dataTypeService;
private readonly IUserService _userService;
private readonly MediaFileSystem _mediaFileSystem = FileSystemProviderManager.Current.MediaFileSystem;
private readonly IdkMap _idkMap;
public MediaService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory, IDataTypeService dataTypeService, IUserService userService, IdkMap idkMap)
public MediaService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory, IDataTypeService dataTypeService, IUserService userService)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
{
if (dataTypeService == null) throw new ArgumentNullException("dataTypeService");
if (userService == null) throw new ArgumentNullException("userService");
_dataTypeService = dataTypeService;
_userService = userService;
_idkMap = idkMap;
}
/// <summary>
@@ -365,15 +363,11 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IMedia"/></returns>
public IMedia GetById(Guid key)
{
// the repository implements a cache policy on int identifiers, not guids,
// and we are not changing it now, but we still would like to rely on caching
// instead of running a full query against the database, so relying on the
// id-key map, which is fast.
//
// we should inject the id-key map but ... breaking changes ... yada
var a = _idkMap.GetIdForKey(key, UmbracoObjectTypes.Media);
return a.Success ? GetById(a.Result) : null;
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMediaRepository(uow);
return repository.Get(key);
}
}
/// <summary>

View File

@@ -261,10 +261,10 @@ namespace Umbraco.Core.Services
_memberService = new Lazy<IMemberService>(() => new MemberService(provider, repositoryFactory, logger, eventMessagesFactory, _memberGroupService.Value, _dataTypeService.Value));
if (_contentService == null)
_contentService = new Lazy<IContentService>(() => new ContentService(provider, repositoryFactory, logger, eventMessagesFactory, _dataTypeService.Value, _userService.Value, idkMap));
_contentService = new Lazy<IContentService>(() => new ContentService(provider, repositoryFactory, logger, eventMessagesFactory, _dataTypeService.Value, _userService.Value));
if (_mediaService == null)
_mediaService = new Lazy<IMediaService>(() => new MediaService(provider, repositoryFactory, logger, eventMessagesFactory, _dataTypeService.Value, _userService.Value, idkMap));
_mediaService = new Lazy<IMediaService>(() => new MediaService(provider, repositoryFactory, logger, eventMessagesFactory, _dataTypeService.Value, _userService.Value));
if (_contentTypeService == null)
_contentTypeService = new Lazy<IContentTypeService>(() => new ContentTypeService(provider, repositoryFactory, logger, eventMessagesFactory, _contentService.Value, _mediaService.Value));

View File

@@ -2,10 +2,12 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Xml.Linq;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
@@ -41,32 +43,75 @@ namespace Umbraco.Tests.Persistence.Repositories
base.TearDown();
}
private ContentRepository CreateRepository(IScopeUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository, out DataTypeDefinitionRepository dtdRepository)
private ContentRepository CreateRepository(IScopeUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository, out DataTypeDefinitionRepository dtdRepository, CacheHelper cacheHelper = null)
{
TemplateRepository tr;
var ctRepository = CreateRepository(unitOfWork, out contentTypeRepository, out tr);
dtdRepository = new DataTypeDefinitionRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, contentTypeRepository);
dtdRepository = new DataTypeDefinitionRepository(unitOfWork, cacheHelper, Logger, SqlSyntax, contentTypeRepository);
return ctRepository;
}
private ContentRepository CreateRepository(IScopeUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository)
private ContentRepository CreateRepository(IScopeUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository, CacheHelper cacheHelper = null)
{
TemplateRepository tr;
return CreateRepository(unitOfWork, out contentTypeRepository, out tr);
return CreateRepository(unitOfWork, out contentTypeRepository, out tr, cacheHelper);
}
private ContentRepository CreateRepository(IScopeUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository, out TemplateRepository templateRepository)
private ContentRepository CreateRepository(IScopeUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository, out TemplateRepository templateRepository, CacheHelper cacheHelper = null)
{
templateRepository = new TemplateRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>());
var tagRepository = new TagRepository(unitOfWork, CacheHelper, Logger, SqlSyntax);
contentTypeRepository = new ContentTypeRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, templateRepository);
var repository = new ContentRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, contentTypeRepository, templateRepository, tagRepository, Mock.Of<IContentSection>());
cacheHelper = cacheHelper ?? CacheHelper;
templateRepository = new TemplateRepository(unitOfWork, cacheHelper, Logger, SqlSyntax, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>());
var tagRepository = new TagRepository(unitOfWork, cacheHelper, Logger, SqlSyntax);
contentTypeRepository = new ContentTypeRepository(unitOfWork, cacheHelper, Logger, SqlSyntax, templateRepository);
var repository = new ContentRepository(unitOfWork, cacheHelper, Logger, SqlSyntax, contentTypeRepository, templateRepository, tagRepository, Mock.Of<IContentSection>());
return repository;
}
private UserGroupRepository CreateUserGroupRepository(IScopeUnitOfWork unitOfWork)
[Test]
public void Cache_Active_By_Int_And_Guid()
{
return new UserGroupRepository(unitOfWork, CacheHelper, Logger, SqlSyntax);
var provider = new PetaPocoUnitOfWorkProvider(Logger);
var unitOfWork = provider.GetUnitOfWork();
ContentTypeRepository contentTypeRepository;
var realCache = new CacheHelper(
new ObjectCacheRuntimeCacheProvider(),
new StaticCacheProvider(),
new StaticCacheProvider(),
new IsolatedRuntimeCache(t => new ObjectCacheRuntimeCacheProvider()));
using (var repository = CreateRepository(unitOfWork, out contentTypeRepository, cacheHelper: realCache))
{
DatabaseContext.Database.DisableSqlCount();
var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage1", "Textpage");
var content = MockedContent.CreateSimpleContent(contentType);
contentTypeRepository.AddOrUpdate(contentType);
repository.AddOrUpdate(content);
unitOfWork.Commit();
DatabaseContext.Database.EnableSqlCount();
//go get it, this should already be cached since the default repository key is the INT
var found = repository.Get(content.Id);
Assert.AreEqual(0, DatabaseContext.Database.SqlCount);
//retrieve again, this should use cache
found = repository.Get(content.Id);
Assert.AreEqual(0, DatabaseContext.Database.SqlCount);
//reset counter
DatabaseContext.Database.DisableSqlCount();
DatabaseContext.Database.EnableSqlCount();
//now get by GUID, this won't be cached yet because the default repo key is not a GUID
found = repository.Get(content.Key);
var sqlCount = DatabaseContext.Database.SqlCount;
Assert.Greater(sqlCount, 0);
//retrieve again, this should use cache now
found = repository.Get(content.Key);
Assert.AreEqual(sqlCount, DatabaseContext.Database.SqlCount);
}
}
[Test]

View File

@@ -5,6 +5,7 @@ using System.Xml.Linq;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
@@ -35,14 +36,62 @@ namespace Umbraco.Tests.Persistence.Repositories
CreateTestData();
}
private MediaRepository CreateRepository(IScopeUnitOfWork unitOfWork, out MediaTypeRepository mediaTypeRepository)
private MediaRepository CreateRepository(IScopeUnitOfWork unitOfWork, out MediaTypeRepository mediaTypeRepository, CacheHelper cacheHelper = null)
{
mediaTypeRepository = new MediaTypeRepository(unitOfWork, CacheHelper, Mock.Of<ILogger>(), SqlSyntax);
var tagRepository = new TagRepository(unitOfWork, CacheHelper, Mock.Of<ILogger>(), SqlSyntax);
var repository = new MediaRepository(unitOfWork, CacheHelper, Mock.Of<ILogger>(), SqlSyntax, mediaTypeRepository, tagRepository, Mock.Of<IContentSection>());
cacheHelper = cacheHelper ?? CacheHelper;
mediaTypeRepository = new MediaTypeRepository(unitOfWork, cacheHelper, Mock.Of<ILogger>(), SqlSyntax);
var tagRepository = new TagRepository(unitOfWork, cacheHelper, Mock.Of<ILogger>(), SqlSyntax);
var repository = new MediaRepository(unitOfWork, cacheHelper, Mock.Of<ILogger>(), SqlSyntax, mediaTypeRepository, tagRepository, Mock.Of<IContentSection>());
return repository;
}
[Test]
public void Cache_Active_By_Int_And_Guid()
{
var provider = new PetaPocoUnitOfWorkProvider(Logger);
var unitOfWork = provider.GetUnitOfWork();
MediaTypeRepository mediaTypeRepository;
var realCache = new CacheHelper(
new ObjectCacheRuntimeCacheProvider(),
new StaticCacheProvider(),
new StaticCacheProvider(),
new IsolatedRuntimeCache(t => new ObjectCacheRuntimeCacheProvider()));
using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository, cacheHelper: realCache))
{
DatabaseContext.Database.DisableSqlCount();
var mediaType = MockedContentTypes.CreateSimpleMediaType("umbTextpage1", "Textpage");
var media = MockedMedia.CreateSimpleMedia(mediaType, "hello", -1);
mediaTypeRepository.AddOrUpdate(mediaType);
repository.AddOrUpdate(media);
unitOfWork.Commit();
DatabaseContext.Database.EnableSqlCount();
//go get it, this should already be cached since the default repository key is the INT
var found = repository.Get(media.Id);
Assert.AreEqual(0, DatabaseContext.Database.SqlCount);
//retrieve again, this should use cache
found = repository.Get(media.Id);
Assert.AreEqual(0, DatabaseContext.Database.SqlCount);
//reset counter
DatabaseContext.Database.DisableSqlCount();
DatabaseContext.Database.EnableSqlCount();
//now get by GUID, this won't be cached yet because the default repo key is not a GUID
found = repository.Get(media.Key);
var sqlCount = DatabaseContext.Database.SqlCount;
Assert.Greater(sqlCount, 0);
//retrieve again, this should use cache now
found = repository.Get(media.Key);
Assert.AreEqual(sqlCount, DatabaseContext.Database.SqlCount);
}
}
[Test]
public void Rebuild_All_Xml_Structures()
{