From e71a5fd5ebc072c664b82dbe1207ad0aed38ad42 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Wed, 12 Dec 2012 09:00:00 -0100 Subject: [PATCH] Fixing an issue with the MediaService. Making the two UOW Providers public, so they can be used for newing up services. Adding a few constructor options to the PP UOW Provider to avoid config lookup. --- .../Repositories/ContentRepository.cs | 2 +- .../Repositories/MediaRepository.cs | 15 ++++-- .../UnitOfWork/FileUnitOfWorkProvider.cs | 2 +- .../UnitOfWork/PetaPocoUnitOfWorkProvider.cs | 51 +++++++++++++++---- src/Umbraco.Core/Services/ContentService.cs | 8 +-- src/Umbraco.Core/Services/IMediaService.cs | 2 +- src/Umbraco.Core/Services/MediaService.cs | 11 ++-- .../Services/ThreadSafetyServiceTest.cs | 10 ++-- 8 files changed, 67 insertions(+), 34 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index ce2874e1af..d0c087d9a2 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -263,7 +263,7 @@ namespace Umbraco.Core.Persistence.Repositories Database.Insert(dto); //Create the PropertyData for this version - cmsPropertyData - var propertyFactory = new PropertyFactory(((Content)entity).ContentType, entity.Version, entity.Id); + var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id); var propertyDataDtos = propertyFactory.BuildDto(entity.Properties); //Add Properties foreach (var propertyDataDto in propertyDataDtos) diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs index c01e76c203..d021f7559b 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs @@ -176,12 +176,21 @@ namespace Umbraco.Core.Persistence.Repositories Database.Insert(dto); //Create the PropertyData for this version - cmsPropertyData - var propertyFactory = new PropertyFactory(((Models.Media)entity).ContentType, entity.Version, entity.Id); + var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id); var propertyDataDtos = propertyFactory.BuildDto(entity.Properties); + var keyDictionary = new Dictionary(); + //Add Properties foreach (var propertyDataDto in propertyDataDtos) { - Database.Insert(propertyDataDto); + var primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto)); + keyDictionary.Add(propertyDataDto.PropertyTypeId, primaryKey); + } + + //Update Properties with its newly set Id + foreach (var property in entity.Properties) + { + property.Id = keyDictionary[property.PropertyTypeId]; } ((ICanBeDirty)entity).ResetDirtyProperties(); @@ -215,7 +224,7 @@ namespace Umbraco.Core.Persistence.Repositories Database.Insert(dto); //Create the PropertyData for this version - cmsPropertyData - var propertyFactory = new PropertyFactory(((Models.Media)entity).ContentType, entity.Version, entity.Id); + var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id); var propertyDataDtos = propertyFactory.BuildDto(entity.Properties); //Add Properties foreach (var propertyDataDto in propertyDataDtos) diff --git a/src/Umbraco.Core/Persistence/UnitOfWork/FileUnitOfWorkProvider.cs b/src/Umbraco.Core/Persistence/UnitOfWork/FileUnitOfWorkProvider.cs index 44010c60ce..c27e86a515 100644 --- a/src/Umbraco.Core/Persistence/UnitOfWork/FileUnitOfWorkProvider.cs +++ b/src/Umbraco.Core/Persistence/UnitOfWork/FileUnitOfWorkProvider.cs @@ -3,7 +3,7 @@ /// /// Represents a Unit of Work Provider for creating a /// - internal class FileUnitOfWorkProvider : IUnitOfWorkProvider + public class FileUnitOfWorkProvider : IUnitOfWorkProvider { #region Implementation of IUnitOfWorkProvider diff --git a/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWorkProvider.cs b/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWorkProvider.cs index 9ab08c9497..7bae47fe62 100644 --- a/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWorkProvider.cs +++ b/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWorkProvider.cs @@ -1,19 +1,47 @@ -using System; -using System.Threading; -using System.Web; -using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration; namespace Umbraco.Core.Persistence.UnitOfWork { /// /// Represents a Unit of Work Provider for creating a /// - internal class PetaPocoUnitOfWorkProvider : IDatabaseUnitOfWorkProvider + public class PetaPocoUnitOfWorkProvider : IDatabaseUnitOfWorkProvider { - + private readonly string _connectionString; + private readonly string _providerName; + + /// + /// Parameterless constructor + /// + public PetaPocoUnitOfWorkProvider() + { + _connectionString = GlobalSettings.UmbracoConnectionName; + } + + /// + /// Constructor to explicitly set the connectionstring to use + /// + /// Connection String to use + public PetaPocoUnitOfWorkProvider(string connectionString) + { + _connectionString = connectionString; + } + + /// + /// Constructor to explicitly set the connectionstring and provider name to use, + /// which will avoid the lookup of any additional config settings. + /// + /// Connection String to use + /// Database Provider + public PetaPocoUnitOfWorkProvider(string connectionString, string providerName) + { + _connectionString = connectionString; + _providerName = providerName; + } + #region Implementation of IUnitOfWorkProvider - /// + /// /// Creates a Unit of work with a new UmbracoDatabase instance for the work item/transaction. /// /// @@ -24,9 +52,10 @@ namespace Umbraco.Core.Persistence.UnitOfWork /// public IDatabaseUnitOfWork GetUnitOfWork() { - return new PetaPocoUnitOfWork( - new UmbracoDatabase( - GlobalSettings.UmbracoConnectionName)); + var database = string.IsNullOrEmpty(_providerName) + ? new UmbracoDatabase(_connectionString) + : new UmbracoDatabase(_connectionString, _providerName); + return new PetaPocoUnitOfWork(database); } #endregion @@ -37,7 +66,7 @@ namespace Umbraco.Core.Persistence.UnitOfWork /// internal static IDatabaseUnitOfWork CreateUnitOfWork() { - var provider = new PetaPocoUnitOfWorkProvider(); + var provider = new PetaPocoUnitOfWorkProvider(GlobalSettings.UmbracoConnectionName); return provider.GetUnitOfWork(); } } diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 9b6d6bfbda..76b7e4ebee 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -8,7 +8,6 @@ using Umbraco.Core.Models; using Umbraco.Core.Models.EntityBase; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Querying; -using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.UnitOfWork; using Umbraco.Core.Publishing; @@ -24,7 +23,10 @@ namespace Umbraco.Core.Services private readonly IUserService _userService; private HttpContextBase _httpContext; - public ContentService(IDatabaseUnitOfWorkProvider provider, IPublishingStrategy publishingStrategy) + public ContentService(IDatabaseUnitOfWorkProvider provider) : this(provider, new PublishingStrategy()) + {} + + internal ContentService(IDatabaseUnitOfWorkProvider provider, IPublishingStrategy publishingStrategy) { _uowProvider = provider; _publishingStrategy = publishingStrategy; @@ -37,8 +39,6 @@ namespace Umbraco.Core.Services _uowProvider = provider; } - //TODO Add GetLatestUnpublishedVersions(int id){} - /// /// Creates an object using the alias of the /// that this Content is based on. diff --git a/src/Umbraco.Core/Services/IMediaService.cs b/src/Umbraco.Core/Services/IMediaService.cs index 5a4edcd351..bbbae59b70 100644 --- a/src/Umbraco.Core/Services/IMediaService.cs +++ b/src/Umbraco.Core/Services/IMediaService.cs @@ -16,7 +16,7 @@ namespace Umbraco.Core.Services /// Alias of the /// Optional id of the user creating the media item /// - IMedia CreateContent(int parentId, string mediaTypeAlias, int userId = -1); + IMedia CreateMedia(int parentId, string mediaTypeAlias, int userId = -1); /// /// Gets an object by Id diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs index 28e8419bfe..c9613f20b6 100644 --- a/src/Umbraco.Core/Services/MediaService.cs +++ b/src/Umbraco.Core/Services/MediaService.cs @@ -6,7 +6,6 @@ using Umbraco.Core.Auditing; using Umbraco.Core.Models; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Querying; -using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.UnitOfWork; namespace Umbraco.Core.Services @@ -44,7 +43,7 @@ namespace Umbraco.Core.Services /// Alias of the /// Optional id of the user creating the media item /// - public IMedia CreateContent(int parentId, string mediaTypeAlias, int userId = -1) + public IMedia CreateMedia(int parentId, string mediaTypeAlias, int userId = -1) { var uow = _uowProvider.GetUnitOfWork(); using (var repository = RepositoryResolver.Current.Factory.CreateMediaTypeRepository(uow)) @@ -55,12 +54,12 @@ namespace Umbraco.Core.Services if (!mediaTypes.Any()) throw new Exception(string.Format("No ContentType matching the passed in Alias: '{0}' was found", mediaTypeAlias)); - var contentType = mediaTypes.First(); + var mediaType = mediaTypes.First(); - if (contentType == null) + if (mediaType == null) throw new Exception(string.Format("ContentType matching the passed in Alias: '{0}' was null", mediaTypeAlias)); - var media = new Models.Media(parentId, contentType); + var media = new Models.Media(parentId, mediaType); var e = new NewEventArgs { Alias = mediaTypeAlias, ParentId = parentId }; @@ -307,7 +306,6 @@ namespace Umbraco.Core.Services /// Id of the User deleting the Media public void Delete(IMedia media, int userId = -1) { - var uow = _uowProvider.GetUnitOfWork(); using (var repository = RepositoryResolver.Current.Factory.CreateMediaRepository(uow)) { @@ -346,7 +344,6 @@ namespace Umbraco.Core.Services { SetUser(media, userId); repository.AddOrUpdate(media); - repository.AddOrUpdate(media); uow.Commit(); if (Saved != null) diff --git a/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs b/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs index 11438a4050..c4ff52c17c 100644 --- a/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs +++ b/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs @@ -65,7 +65,7 @@ namespace Umbraco.Tests.Services /// private volatile Exception _error = null; - private const int MaxThreadCount = 1; + private const int MaxThreadCount = 20; [Test] public void Ensure_All_Threads_Execute_Successfully_Content_Service() @@ -145,20 +145,18 @@ namespace Umbraco.Tests.Services { try { - var folderMediaType = ServiceContext.ContentTypeService.GetMediaType(1031); - Debug.WriteLine("Created content on thread: " + Thread.CurrentThread.ManagedThreadId); //create 2 content items - - var folder1 = MockedMedia.CreateMediaFolder(folderMediaType, -1); + + var folder1 = mediaService.CreateMedia(-1, "Folder", 0); folder1.Name = "test" + Guid.NewGuid(); Debug.WriteLine("Saving folder1 on thread: " + Thread.CurrentThread.ManagedThreadId); mediaService.Save(folder1, 0); Thread.Sleep(100); //quick pause for maximum overlap! - var folder2 = MockedMedia.CreateMediaFolder(folderMediaType, -1); + var folder2 = mediaService.CreateMedia(-1, "Folder", 0); folder2.Name = "test" + Guid.NewGuid(); Debug.WriteLine("Saving folder2 on thread: " + Thread.CurrentThread.ManagedThreadId); mediaService.Save(folder2, 0);