From a9cb337a964b92b8228aaad672170652bf2b21d3 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Fri, 14 Dec 2012 08:06:32 +0500 Subject: [PATCH] Changes ApplicationContext to expect arguments of DatabaseContext and ServiceContext for it to be constructed. Changes DatabaseContext to not be a singleton. Changes ServiceContext not to be a singleton. Removed ServicesFactory. Updated unit tests to support new changes. --- src/Umbraco.Core/ApplicationContext.cs | 77 ++++++++--- .../Auditing/DataAuditWriteProvider.cs | 2 +- src/Umbraco.Core/CoreBootManager.cs | 11 +- src/Umbraco.Core/DatabaseContext.cs | 43 +++--- .../ObjectResolution/ResolverBase.cs | 2 +- .../Persistence/PetaPocoExtensions.cs | 6 +- .../UnitOfWork/PetaPocoUnitOfWorkProvider.cs | 2 +- src/Umbraco.Core/Services/ServiceContext.cs | 15 --- src/Umbraco.Core/Services/ServiceFactory.cs | 126 +++++++++--------- src/Umbraco.Core/Services/UserService.cs | 2 +- src/Umbraco.Tests/CodeFirst/CodeFirstTests.cs | 3 +- .../ContentTypeDefinitionFactory.cs | 6 +- .../CodeFirst/Definitions/Conventions.cs | 8 +- .../Persistence/DatabaseContextTests.cs | 39 +++++- .../Services/ContentServiceTests.cs | 14 +- .../Services/ThreadSafetyServiceTest.cs | 8 +- .../TestHelpers/BaseDatabaseFactoryTest.cs | 30 +++-- src/Umbraco.Tests/TestHelpers/BaseWebTest.cs | 26 +++- .../Strategies/UpdateContentCache.cs | 10 +- src/Umbraco.Web/UmbracoContext.cs | 2 +- .../install/steps/database.ascx.cs | 6 +- .../install/utills/p.aspx.cs | 2 +- 22 files changed, 262 insertions(+), 178 deletions(-) diff --git a/src/Umbraco.Core/ApplicationContext.cs b/src/Umbraco.Core/ApplicationContext.cs index d96880a2e2..964e771850 100644 --- a/src/Umbraco.Core/ApplicationContext.cs +++ b/src/Umbraco.Core/ApplicationContext.cs @@ -4,6 +4,7 @@ using System.Web; using System.Web.Caching; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; +using Umbraco.Core.Persistence; using Umbraco.Core.Services; @@ -19,15 +20,29 @@ namespace Umbraco.Core { /// /// Constructor - /// - internal ApplicationContext() + /// + internal ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext) + :this() { - //create a new application cache from the HttpRuntime.Cache - ApplicationCache = HttpRuntime.Cache == null - ? new CacheHelper(new Cache()) - : new CacheHelper(HttpRuntime.Cache); + if (dbContext == null) throw new ArgumentNullException("dbContext"); + if (serviceContext == null) throw new ArgumentNullException("serviceContext"); + + _databaseContext = dbContext; + _services = serviceContext; } + /// + /// 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() + { + //create a new application cache from the HttpRuntime.Cache + ApplicationCache = HttpRuntime.Cache == null + ? new CacheHelper(new Cache()) + : new CacheHelper(HttpRuntime.Cache); + } + /// /// Singleton accessor /// @@ -46,7 +61,10 @@ namespace Umbraco.Core // now, the boot task that setup the content store ensures that it is ready bool _isReady = false; readonly System.Threading.ManualResetEventSlim _isReadyEvent = new System.Threading.ManualResetEventSlim(false); - public bool IsReady + private DatabaseContext _databaseContext; + private ServiceContext _services; + + public bool IsReady { get { @@ -136,17 +154,38 @@ namespace Umbraco.Core throw new Exception("ApplicationContext has already been initialized."); } - /// - /// Gets the current DatabaseContext - /// - public DatabaseContext DatabaseContext - { - get { return DatabaseContext.Current; } - } - - /// - /// Gets the current ServiceContext - /// - public ServiceContext Services { get { return ServiceContext.Current; } } + /// + /// Gets the current DatabaseContext + /// + /// + /// Internal set is generally only used for unit tests + /// + public DatabaseContext DatabaseContext + { + get + { + if (_databaseContext == null) + throw new InvalidOperationException("The DatabaseContext has not been set on the ApplicationContext"); + return _databaseContext; + } + internal set { _databaseContext = value; } + } + + /// + /// Gets the current ServiceContext + /// + /// + /// Internal set is generally only used for unit tests + /// + public ServiceContext Services + { + get + { + if (_services == null) + throw new InvalidOperationException("The ServiceContext has not been set on the ApplicationContext"); + return _services; + } + internal set { _services = value; } + } } } diff --git a/src/Umbraco.Core/Auditing/DataAuditWriteProvider.cs b/src/Umbraco.Core/Auditing/DataAuditWriteProvider.cs index d6dc0e1e27..f3df78eedf 100644 --- a/src/Umbraco.Core/Auditing/DataAuditWriteProvider.cs +++ b/src/Umbraco.Core/Auditing/DataAuditWriteProvider.cs @@ -16,7 +16,7 @@ namespace Umbraco.Core.Auditing /// Audit comment public void WriteEntry(int objectId, int userId, DateTime date, string header, string comment) { - DatabaseContext.Current.Database.Insert(new LogDto + ApplicationContext.Current.DatabaseContext.Database.Insert(new LogDto { Comment = comment, Datestamp = date, diff --git a/src/Umbraco.Core/CoreBootManager.cs b/src/Umbraco.Core/CoreBootManager.cs index 5177e79d86..504100013a 100644 --- a/src/Umbraco.Core/CoreBootManager.cs +++ b/src/Umbraco.Core/CoreBootManager.cs @@ -5,7 +5,10 @@ using System.Text; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.UnitOfWork; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Publishing; +using Umbraco.Core.Services; namespace Umbraco.Core { @@ -33,11 +36,15 @@ namespace Umbraco.Core LogHelper.Info("Umbraco application starting"); _timer = DisposableTimer.Start(x => LogHelper.Info("Umbraco application startup complete" + " (took " + x + "ms)")); + //create database and service contexts for the app context + var dbContext = new DatabaseContext(new DefaultDatabaseFactory()); + var serviceContext = new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy()); + //create the ApplicationContext - ApplicationContext = ApplicationContext.Current = new ApplicationContext(); + ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext); //initialize the DatabaseContext - DatabaseContext.Current.Initialize(); + dbContext.Initialize(); InitializeResolvers(); diff --git a/src/Umbraco.Core/DatabaseContext.cs b/src/Umbraco.Core/DatabaseContext.cs index 986ea70baa..674a95867d 100644 --- a/src/Umbraco.Core/DatabaseContext.cs +++ b/src/Umbraco.Core/DatabaseContext.cs @@ -26,30 +26,39 @@ namespace Umbraco.Core private bool _configured; private string _connectionString; private string _providerName; + //private static readonly object Locker = new object(); + //private static DatabaseContext _databaseContext; - #region Singleton + //#region Singleton - private static DatabaseContext _customContext = null; - private static readonly Lazy lazy = new Lazy(() => new DatabaseContext(new DefaultDatabaseFactory())); - - /// - /// Gets the current Database Context. - /// - public static DatabaseContext Current - { - //return the _custom context if it is set, otherwise the automatic lazy instance - get { return _customContext ?? lazy.Value; } - //Allows setting a custom database context for the 'Current', normally used for unit tests or if the - //default IDatabaseFactory is not sufficient. - internal set { _customContext = value; } - } + ///// + ///// Gets the current Database Context. + ///// + //public static DatabaseContext Current + //{ + // get + // { + // if (_databaseContext == null) + // throw new InvalidOperationException("The DatabaseContext hasn't been initialized. Ensure that the CoreBootManager has been used to boot the application"); + // return _databaseContext; + // } + // internal set + // { + // lock(Locker) + // { + // _databaseContext = value; + // } + // } + //} - internal DatabaseContext(IDatabaseFactory factory) + //#endregion + + internal DatabaseContext(IDatabaseFactory factory) { _factory = factory; } - #endregion + /// /// Gets the object for doing CRUD operations diff --git a/src/Umbraco.Core/ObjectResolution/ResolverBase.cs b/src/Umbraco.Core/ObjectResolution/ResolverBase.cs index f0bd5d1f7c..a6578559c4 100644 --- a/src/Umbraco.Core/ObjectResolution/ResolverBase.cs +++ b/src/Umbraco.Core/ObjectResolution/ResolverBase.cs @@ -28,7 +28,7 @@ namespace Umbraco.Core.ObjectResolution using (new ReadLock(ResolversLock)) { if (_resolver == null) - throw new InvalidOperationException("Current has not been initialized. You must initialize Current before trying to read it."); + throw new InvalidOperationException("Current has not been initialized on " + typeof(TResolver) + ". You must initialize Current before trying to read it."); return _resolver; } } diff --git a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs index ef73b39e3c..e154cb3fbc 100644 --- a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs +++ b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs @@ -61,14 +61,14 @@ namespace Umbraco.Core.Persistence var e = new TableCreationEventArgs(); //Turn on identity insert if db provider is not mysql - if (DatabaseContext.Current.ProviderName.Contains("MySql") == false && tableDefinition.IsIdentity) + if (ApplicationContext.Current.DatabaseContext.ProviderName.Contains("MySql") == false && tableDefinition.IsIdentity) db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} ON ", SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName)))); //Call the NewTable-event to trigger the insert of base/default data NewTable(tableName, db, e); //Turn off identity insert if db provider is not mysql - if (DatabaseContext.Current.ProviderName.Contains("MySql") == false && tableDefinition.IsIdentity) + if (ApplicationContext.Current.DatabaseContext.ProviderName.Contains("MySql") == false && tableDefinition.IsIdentity) db.Execute(new Sql(string.Format("SET IDENTITY_INSERT {0} OFF;", SyntaxConfig.SqlSyntaxProvider.GetQuotedTableName(tableName)))); } @@ -85,7 +85,7 @@ namespace Umbraco.Core.Persistence } //Specific to Sql Ce - look for changes to Identity Seed - if (DatabaseContext.Current.ProviderName.Contains("SqlServerCe")) + if (ApplicationContext.Current.DatabaseContext.ProviderName.Contains("SqlServerCe")) { var seedSql = SyntaxConfig.SqlSyntaxProvider.ToAlterIdentitySeedStatements(tableDefinition); foreach (var sql in seedSql) diff --git a/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWorkProvider.cs b/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWorkProvider.cs index 7bae47fe62..071d10dc4c 100644 --- a/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWorkProvider.cs +++ b/src/Umbraco.Core/Persistence/UnitOfWork/PetaPocoUnitOfWorkProvider.cs @@ -47,7 +47,7 @@ namespace Umbraco.Core.Persistence.UnitOfWork /// /// /// Each PetaPoco UOW uses it's own Database object, not the shared Database object that comes from - /// the DatabaseContext.Current.Database. This is because each transaction should use it's own Database + /// the ApplicationContext.Current.DatabaseContext.Database. This is because each transaction should use it's own Database /// and we Dispose of this Database object when the UOW is disposed. /// public IDatabaseUnitOfWork GetUnitOfWork() diff --git a/src/Umbraco.Core/Services/ServiceContext.cs b/src/Umbraco.Core/Services/ServiceContext.cs index 5bb1e096ca..dc52a8ca44 100644 --- a/src/Umbraco.Core/Services/ServiceContext.cs +++ b/src/Umbraco.Core/Services/ServiceContext.cs @@ -22,19 +22,6 @@ namespace Umbraco.Core.Services private FileService _fileService; private LocalizationService _localizationService; - #region Singleton - private static readonly Lazy lazy = new Lazy(() => new ServiceContext()); - - /// - /// Gets the current Database Context. - /// - public static ServiceContext Current { get { return lazy.Value; } } - - private ServiceContext() - { - BuildServiceCache(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy()); - } - /// /// Internal constructor used for unit tests /// @@ -46,8 +33,6 @@ namespace Umbraco.Core.Services BuildServiceCache(dbUnitOfWorkProvider, fileUnitOfWorkProvider, publishingStrategy); } - #endregion - /// /// Builds the various services /// diff --git a/src/Umbraco.Core/Services/ServiceFactory.cs b/src/Umbraco.Core/Services/ServiceFactory.cs index 0d4bbac2e8..af8bf79bee 100644 --- a/src/Umbraco.Core/Services/ServiceFactory.cs +++ b/src/Umbraco.Core/Services/ServiceFactory.cs @@ -1,73 +1,73 @@ namespace Umbraco.Core.Services { - /// - /// Represents the ServiceFactory, which provides access to the various services in - /// a non-singleton way. - /// - public static class ServiceFactory - { - /// - /// Gets the - /// - public static IContentService ContentService - { - get { return ServiceContext.Current.ContentService; } - } + ///// + ///// Represents the ServiceFactory, which provides access to the various services in + ///// a non-singleton way. + ///// + //public static class ServiceFactory + //{ + // /// + // /// Gets the + // /// + // public static IContentService ContentService + // { + // get { return ServiceContext.Current.ContentService; } + // } - /// - /// Gets the - /// - public static IContentTypeService ContentTypeService - { - get { return ServiceContext.Current.ContentTypeService; } - } + // /// + // /// Gets the + // /// + // public static IContentTypeService ContentTypeService + // { + // get { return ServiceContext.Current.ContentTypeService; } + // } - /// - /// Gets the - /// - public static IDataTypeService DataTypeService - { - get { return ServiceContext.Current.DataTypeService; } - } + // /// + // /// Gets the + // /// + // public static IDataTypeService DataTypeService + // { + // get { return ServiceContext.Current.DataTypeService; } + // } - /// - /// Gets the - /// - public static IFileService FileService - { - get { return ServiceContext.Current.FileService; } - } + // /// + // /// Gets the + // /// + // public static IFileService FileService + // { + // get { return ServiceContext.Current.FileService; } + // } - /// - /// Gets the - /// - public static ILocalizationService LocalizationService - { - get { return ServiceContext.Current.LocalizationService; } - } + // /// + // /// Gets the + // /// + // public static ILocalizationService LocalizationService + // { + // get { return ServiceContext.Current.LocalizationService; } + // } - /// - /// Gets the - /// - public static IMediaService MediaService - { - get { return ServiceContext.Current.MediaService; } - } + // /// + // /// Gets the + // /// + // public static IMediaService MediaService + // { + // get { return ServiceContext.Current.MediaService; } + // } - /// - /// Gets the - /// - internal static IMacroService MacroService - { - get { return ServiceContext.Current.MacroService; } - } + // /// + // /// Gets the + // /// + // internal static IMacroService MacroService + // { + // get { return ServiceContext.Current.MacroService; } + // } - /// - /// Gets the - /// - internal static IUserService UserService - { - get { return ServiceContext.Current.UserService; } - } - } + // /// + // /// Gets the + // /// + // internal static IUserService UserService + // { + // get { return ServiceContext.Current.UserService; } + // } + //} } \ No newline at end of file diff --git a/src/Umbraco.Core/Services/UserService.cs b/src/Umbraco.Core/Services/UserService.cs index 16e94d3af2..f4d2154cf6 100644 --- a/src/Umbraco.Core/Services/UserService.cs +++ b/src/Umbraco.Core/Services/UserService.cs @@ -49,7 +49,7 @@ namespace Umbraco.Core.Services if(HttpRuntime.Cache[cacheKey] == null) { userId = - DatabaseContext.Current.Database.ExecuteScalar( + _unitOfWork.Database.ExecuteScalar( "select userID from umbracoUserLogins where contextID = @ContextId", new {ContextId = new Guid(contextId)}); diff --git a/src/Umbraco.Tests/CodeFirst/CodeFirstTests.cs b/src/Umbraco.Tests/CodeFirst/CodeFirstTests.cs index 3d6c3e6a9a..b9cacb3114 100644 --- a/src/Umbraco.Tests/CodeFirst/CodeFirstTests.cs +++ b/src/Umbraco.Tests/CodeFirst/CodeFirstTests.cs @@ -238,8 +238,7 @@ namespace Umbraco.Tests.CodeFirst string path = TestHelper.CurrentAssemblyDirectory; AppDomain.CurrentDomain.SetData("DataDirectory", null); - - ServiceContext = null; + SerializationService = null; UmbracoSettings.ResetSetters(); diff --git a/src/Umbraco.Tests/CodeFirst/Definitions/ContentTypeDefinitionFactory.cs b/src/Umbraco.Tests/CodeFirst/Definitions/ContentTypeDefinitionFactory.cs index 97c138606a..5996ea9e1b 100644 --- a/src/Umbraco.Tests/CodeFirst/Definitions/ContentTypeDefinitionFactory.cs +++ b/src/Umbraco.Tests/CodeFirst/Definitions/ContentTypeDefinitionFactory.cs @@ -31,7 +31,7 @@ namespace Umbraco.Tests.CodeFirst.Definitions var contentTypeAttribute = modelType.FirstAttribute(); var contentTypeAlias = contentTypeAttribute == null ? modelType.Name.ToUmbracoAlias() : contentTypeAttribute.Alias; //Check if ContentType already exists by looking it up by Alias. - var existing = ServiceFactory.ContentTypeService.GetContentType(contentTypeAlias); + var existing = ApplicationContext.Current.Services.ContentTypeService.GetContentType(contentTypeAlias); Lazy contentType = contentTypeAttribute == null ? PlainPocoConvention(modelType, existing) @@ -316,7 +316,7 @@ namespace Umbraco.Tests.CodeFirst.Definitions ? templateName.Replace(".cshtml", "").Replace(".vbhtml", "") : templateName.Replace(".masterpage", ""); - var template = ServiceFactory.FileService.GetTemplateByAlias(@alias); + var template = ApplicationContext.Current.Services.FileService.GetTemplateByAlias(@alias); if(template == null) { var name = engine == RenderingEngine.Mvc @@ -324,7 +324,7 @@ namespace Umbraco.Tests.CodeFirst.Definitions : string.Concat(@alias, ".masterpage"); template = new Template(string.Empty, name, @alias) { CreatorId = 0, Content = string.Empty}; - ServiceFactory.FileService.SaveTemplate(template); + ApplicationContext.Current.Services.FileService.SaveTemplate(template); } templates.Add(template); } diff --git a/src/Umbraco.Tests/CodeFirst/Definitions/Conventions.cs b/src/Umbraco.Tests/CodeFirst/Definitions/Conventions.cs index 5755b38b2b..fde708e85d 100644 --- a/src/Umbraco.Tests/CodeFirst/Definitions/Conventions.cs +++ b/src/Umbraco.Tests/CodeFirst/Definitions/Conventions.cs @@ -33,7 +33,7 @@ namespace Umbraco.Tests.CodeFirst.Definitions DatabaseType = attribute.DatabaseType, Name = dataType.DataTypeName }; - ServiceFactory.DataTypeService.Save(definition, 0); + ApplicationContext.Current.Services.DataTypeService.Save(definition, 0); } return definition; } @@ -71,7 +71,7 @@ namespace Umbraco.Tests.CodeFirst.Definitions /// public static IDataTypeDefinition GetDataTypeByControlId(Guid id) { - var definitions = ServiceFactory.DataTypeService.GetDataTypeDefinitionByControlId(id); + var definitions = ApplicationContext.Current.Services.DataTypeService.GetDataTypeDefinitionByControlId(id); return definitions.FirstOrDefault(); } @@ -91,7 +91,7 @@ namespace Umbraco.Tests.CodeFirst.Definitions DatabaseType = attribute.DatabaseType, Name = dataTypeDefinitionName }; - ServiceFactory.DataTypeService.Save(definition, 0); + ApplicationContext.Current.Services.DataTypeService.Save(definition, 0); return definition; } @@ -112,7 +112,7 @@ namespace Umbraco.Tests.CodeFirst.Definitions Value = value }; - DatabaseContext.Current.Database.Insert(poco); + ApplicationContext.Current.DatabaseContext.Database.Insert(poco); } /// diff --git a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs index c8c318d2d7..e2026e497f 100644 --- a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs +++ b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs @@ -6,6 +6,9 @@ using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Core.Persistence.UnitOfWork; +using Umbraco.Core.Publishing; +using Umbraco.Core.Services; using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.Persistence @@ -13,11 +16,33 @@ namespace Umbraco.Tests.Persistence [TestFixture] public class DatabaseContextTests { + private DatabaseContext _dbContext; + + [SetUp] + public void Setup() + { + _dbContext = new DatabaseContext(new DefaultDatabaseFactory()); + + //unfortunately we have to set this up because the PetaPocoExtensions require singleton access + ApplicationContext.Current = new ApplicationContext + { + DatabaseContext = _dbContext, + IsReady = true + }; + } + + [TearDown] + public void TearDown() + { + _dbContext = null; + ApplicationContext.Current = null; + } + [Test] public void Can_Verify_Single_Database_Instance() { - var db1 = DatabaseContext.Current.Database; - var db2 = DatabaseContext.Current.Database; + var db1 = _dbContext.Database; + var db2 = _dbContext.Database; Assert.AreSame(db1, db2); } @@ -25,7 +50,7 @@ namespace Umbraco.Tests.Persistence [Test] public void Can_Assert_DatabaseProvider() { - var provider = DatabaseContext.Current.DatabaseProvider; + var provider = _dbContext.DatabaseProvider; Assert.AreEqual(DatabaseProviders.SqlServerCE, provider); } @@ -53,11 +78,11 @@ namespace Umbraco.Tests.Persistence SyntaxConfig.SqlSyntaxProvider = SqlCeSyntaxProvider.Instance; //Create the umbraco database - DatabaseContext.Current.Database.CreateDatabaseSchema(); + _dbContext.Database.CreateDatabaseSchema(); - bool umbracoNodeTable = DatabaseContext.Current.Database.TableExist("umbracoNode"); - bool umbracoUserTable = DatabaseContext.Current.Database.TableExist("umbracoUser"); - bool cmsTagsTable = DatabaseContext.Current.Database.TableExist("cmsTags"); + bool umbracoNodeTable = _dbContext.Database.TableExist("umbracoNode"); + bool umbracoUserTable = _dbContext.Database.TableExist("umbracoUser"); + bool cmsTagsTable = _dbContext.Database.TableExist("cmsTags"); Assert.That(umbracoNodeTable, Is.True); Assert.That(umbracoUserTable, Is.True); diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index c113514469..b1269c0596 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -30,6 +30,12 @@ namespace Umbraco.Tests.Services CreateTestData(); } + [TearDown] + public override void TearDown() + { + base.TearDown(); + } + //TODO Add test to verify there is only ONE newest document/content in cmsDocument table after updating. //TODO Add test to delete specific version (with and without deleting prior versions) and versions by date. @@ -693,14 +699,6 @@ namespace Umbraco.Tests.Services Assert.That(c2.Value.ParentId > 0, Is.True); } - [TearDown] - public override void TearDown() - { - base.TearDown(); - - ServiceContext = null; - } - public void CreateTestData() { //NOTE Maybe not the best way to create/save test data as we are using the services, which are being tested. diff --git a/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs b/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs index c4ff52c17c..f137e98cba 100644 --- a/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs +++ b/src/Umbraco.Tests/Services/ThreadSafetyServiceTest.cs @@ -32,16 +32,14 @@ namespace Umbraco.Tests.Services //threading environment, or a single apartment threading environment will not work for this test because //it is multi-threaded. _dbFactory = new PerThreadDatabaseFactory(); - //assign the custom factory to the new context and assign that to 'Current' - DatabaseContext.Current = new DatabaseContext(_dbFactory); //overwrite the local object - DatabaseContext = DatabaseContext.Current; + ApplicationContext.DatabaseContext = new DatabaseContext(_dbFactory); //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); - ServiceContext = new ServiceContext(_uowProvider, new FileUnitOfWorkProvider(), new PublishingStrategy()); + ApplicationContext.Services = new ServiceContext(_uowProvider, new FileUnitOfWorkProvider(), new PublishingStrategy()); CreateTestData(); } @@ -56,8 +54,6 @@ namespace Umbraco.Tests.Services _uowProvider.Dispose(); base.TearDown(); - - ServiceContext = null; } /// diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs index 9926e7d92a..b81675789a 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs @@ -58,10 +58,12 @@ namespace Umbraco.Tests.TestHelpers engine.CreateDatabase(); Resolution.Freeze(); - ApplicationContext = new ApplicationContext() { IsReady = true }; - DatabaseContext = DatabaseContext.Current; - ServiceContext = new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy()); - + ApplicationContext.Current = new ApplicationContext( + //assign the db context + new DatabaseContext(new DefaultDatabaseFactory()), + //assign the service context + new ServiceContext(new PetaPocoUnitOfWorkProvider(), new FileUnitOfWorkProvider(), new PublishingStrategy())) { IsReady = true }; + //Configure the Database and Sql Syntax based on connection string set in config DatabaseContext.Initialize(); //Create the umbraco database and its base data @@ -76,10 +78,9 @@ namespace Umbraco.Tests.TestHelpers TestHelper.CleanContentDirectories(); - //reset the app context - DatabaseContext = null; + //reset the app context + ApplicationContext.ApplicationCache.ClearAllCache(); ApplicationContext.Current = null; - ServiceContext = null; Resolution.IsFrozen = false; RepositoryResolver.Reset(); @@ -94,11 +95,20 @@ namespace Umbraco.Tests.TestHelpers } } - protected ApplicationContext ApplicationContext { get; set; } + protected ApplicationContext ApplicationContext + { + get { return ApplicationContext.Current; } + } - protected ServiceContext ServiceContext { get; set; } + protected ServiceContext ServiceContext + { + get { return ApplicationContext.Services; } + } - protected DatabaseContext DatabaseContext { get; set; } + protected DatabaseContext DatabaseContext + { + get { return ApplicationContext.DatabaseContext; } + } protected UmbracoContext GetUmbracoContext(string url, int templateId, RouteData routeData = null) { diff --git a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs index 59316bf78c..fdbe615af4 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs @@ -7,6 +7,10 @@ using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.IO; using Umbraco.Core.ObjectResolution; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.UnitOfWork; +using Umbraco.Core.Publishing; +using Umbraco.Core.Services; using Umbraco.Tests.Stubs; using Umbraco.Web; using Umbraco.Web.Routing; @@ -32,8 +36,15 @@ namespace Umbraco.Tests.TestHelpers Resolution.Freeze(); - ApplicationContext = new ApplicationContext { IsReady = true }; - DatabaseContext = DatabaseContext.Current; + //NOTE: We are not constructing with the service context here because it is not required for these tests (currently) + // if we do, this means that we have to initialized the RepositoryResolver too. + ApplicationContext.Current = new ApplicationContext + { + IsReady = true, + //assign the db context + DatabaseContext = new DatabaseContext(new DefaultDatabaseFactory()) + }; + } [TearDown] @@ -44,7 +55,6 @@ namespace Umbraco.Tests.TestHelpers //reset the app context ApplicationContext.ApplicationCache.ClearAllCache(); ApplicationContext.Current = null; - DatabaseContext = null; Resolution.IsFrozen = false; if (RequiresDbSetup) @@ -98,9 +108,15 @@ namespace Umbraco.Tests.TestHelpers return factory; } - protected ApplicationContext ApplicationContext { get; private set; } + protected ApplicationContext ApplicationContext + { + get { return ApplicationContext.Current; } + } - protected DatabaseContext DatabaseContext { get; private set; } + protected DatabaseContext DatabaseContext + { + get { return ApplicationContext.DatabaseContext; } + } internal virtual IRoutesCache GetRoutesCache() { diff --git a/src/Umbraco.Web/Strategies/UpdateContentCache.cs b/src/Umbraco.Web/Strategies/UpdateContentCache.cs index 4dc81a5576..c9054391d0 100644 --- a/src/Umbraco.Web/Strategies/UpdateContentCache.cs +++ b/src/Umbraco.Web/Strategies/UpdateContentCache.cs @@ -26,17 +26,17 @@ namespace Umbraco.Web.Strategies public UpdateContentCache() { _httpContext = new HttpContextWrapper(HttpContext.Current); - _serviceContext = ServiceContext.Current; + _serviceContext = ApplicationContext.Current.Services; - PublishingStrategy.Published += PublishingStrategy_Published; + BasePublishingStrategy.Published += PublishingStrategy_Published; } public UpdateContentCache(HttpContextBase httpContext) { _httpContext = httpContext; - _serviceContext = ServiceContext.Current; + _serviceContext = ApplicationContext.Current.Services; - PublishingStrategy.Published += PublishingStrategy_Published; + BasePublishingStrategy.Published += PublishingStrategy_Published; } void PublishingStrategy_Published(object sender, PublishingEventArgs e) @@ -232,7 +232,7 @@ namespace Umbraco.Web.Strategies internal void Unsubscribe() { - PublishingStrategy.Published -= PublishingStrategy_Published; + BasePublishingStrategy.Published -= PublishingStrategy_Published; } } } \ No newline at end of file diff --git a/src/Umbraco.Web/UmbracoContext.cs b/src/Umbraco.Web/UmbracoContext.cs index 7c97ecce6b..ed6855b3e2 100644 --- a/src/Umbraco.Web/UmbracoContext.cs +++ b/src/Umbraco.Web/UmbracoContext.cs @@ -79,7 +79,7 @@ namespace Umbraco.Web return _umbracoContext; } - set + internal set { lock (Locker) { diff --git a/src/Umbraco.Web/umbraco.presentation/install/steps/database.ascx.cs b/src/Umbraco.Web/umbraco.presentation/install/steps/database.ascx.cs index a1049ffa92..eb1c7b2cf2 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/steps/database.ascx.cs +++ b/src/Umbraco.Web/umbraco.presentation/install/steps/database.ascx.cs @@ -131,15 +131,15 @@ namespace umbraco.presentation.install.steps { if (string.IsNullOrEmpty(ConnectionString.Text) == false) { - DatabaseContext.Current.ConfigureDatabaseConnection(ConnectionString.Text); + ApplicationContext.Current.DatabaseContext.ConfigureDatabaseConnection(ConnectionString.Text); } else if (IsEmbeddedDatabase) { - DatabaseContext.Current.ConfigureDatabaseConnection(); + ApplicationContext.Current.DatabaseContext.ConfigureDatabaseConnection(); } else { - DatabaseContext.Current.ConfigureDatabaseConnection(DatabaseServer.Text, DatabaseName.Text, + ApplicationContext.Current.DatabaseContext.ConfigureDatabaseConnection(DatabaseServer.Text, DatabaseName.Text, DatabaseUsername.Text, DatabasePassword.Text, DatabaseType.SelectedValue); } diff --git a/src/Umbraco.Web/umbraco.presentation/install/utills/p.aspx.cs b/src/Umbraco.Web/umbraco.presentation/install/utills/p.aspx.cs index 4a0cf39b6d..16831c8bf9 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/utills/p.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/install/utills/p.aspx.cs @@ -58,7 +58,7 @@ namespace umbraco.presentation.install.utills { LogHelper.Info

("Running 'installOrUpgrade' service"); - var result = DatabaseContext.Current.CreateDatabaseSchemaAndDataOrUpgrade(); + var result = ApplicationContext.Current.DatabaseContext.CreateDatabaseSchemaAndDataOrUpgrade(); var js = new JavaScriptSerializer(); var jsonResult = js.Serialize(result);