Merge remote-tracking branch 'origin/netcore/dev' into netcore/feature/AB4549-Move-models-from-web

This commit is contained in:
Bjarke Berg
2020-01-16 07:20:13 +01:00
21 changed files with 140 additions and 271 deletions

View File

@@ -23,5 +23,8 @@ namespace Umbraco.Core.Hosting
/// Terminates the current application. The application restarts the next time a request is received for it.
/// </summary>
void LazyRestartApplication();
void RegisterObject(IRegisteredObject registeredObject);
void UnregisterObject(IRegisteredObject registeredObject);
}
}

View File

@@ -0,0 +1,7 @@
namespace Umbraco.Core
{
public interface IRegisteredObject
{
void Stop(bool immediate);
}
}

View File

@@ -1,40 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Umbraco.Core")]
[assembly: AssemblyDescription("Umbraco Core")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyProduct("Umbraco CMS")]
[assembly: ComVisible(false)]
[assembly: Guid("130a6b5c-50e7-4df3-a0dd-e9e7eb0b7c5c")]
// Umbraco Cms
[assembly: InternalsVisibleTo("Umbraco.Web")]
[assembly: InternalsVisibleTo("Umbraco.Web.UI")]
[assembly: InternalsVisibleTo("Umbraco.Examine")]
[assembly: InternalsVisibleTo("Umbraco.ModelsBuilder.Embedded")]
[assembly: InternalsVisibleTo("Umbraco.Tests")]
[assembly: InternalsVisibleTo("Umbraco.Tests.Benchmarks")]
// Allow this to be mocked in our unit tests
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
// Umbraco Deploy
[assembly: InternalsVisibleTo("Umbraco.Deploy")]
[assembly: InternalsVisibleTo("Umbraco.Deploy.UI")]
[assembly: InternalsVisibleTo("Umbraco.Deploy.Cloud")]
// Umbraco Forms
[assembly: InternalsVisibleTo("Umbraco.Forms.Core")]
[assembly: InternalsVisibleTo("Umbraco.Forms.Core.Providers")]
[assembly: InternalsVisibleTo("Umbraco.Forms.Web")]
// Umbraco Headless
[assembly: InternalsVisibleTo("Umbraco.Cloud.Headless")]
// code analysis
// IDE1006 is broken, wants _value syntax for consts, etc - and it's even confusing ppl at MS, kill it
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "~_~")]

View File

@@ -1,145 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<ProjectGuid>{31785BC3-256C-4613-B2F5-A1B0BDDED8C1}</ProjectGuid>
<OutputType>Library</OutputType>
<AssemblyName>Umbraco.Core</AssemblyName>
<RootNamespace>Umbraco.Core</RootNamespace>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<TargetFrameworkProfile />
<AdditionalFileItemNames>$(AdditionalFileItemNames);Content</AdditionalFileItemNames>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>portable</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>portable</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Umbraco.Core.xml</DocumentationFile>
<Prefer32Bit>false</Prefer32Bit>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data.Entity" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Runtime.Caching" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Transactions" />
<Reference Include="System.Web" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<!-- note: NuGet deals with transitive references now -->
<PackageReference Include="Microsoft.SourceLink.GitHub">
<Version>1.0.0-beta2-19324-01</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="SecurityCodeScan">
<Version>3.3.0</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Serilog.Sinks.Async">
<Version>1.4.0</Version>
</PackageReference>
<PackageReference Include="Serilog.Sinks.Map">
<Version>1.0.0</Version>
</PackageReference>
<PackageReference Include="System.ComponentModel.Annotations">
<Version>4.6.0</Version>
</PackageReference>
<PackageReference Include="Umbraco.Code">
<Version>1.0.5</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="LightInject" Version="5.4.0" />
<PackageReference Include="LightInject.Annotation" Version="1.1.0" />
<PackageReference Include="LightInject.Web" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNet.Identity.Core">
<Version>2.2.2</Version>
</PackageReference>
<PackageReference Include="Microsoft.AspNet.WebApi.Client">
<Version>5.2.7</Version>
</PackageReference>
<PackageReference Include="Microsoft.Owin">
<Version>4.0.1</Version>
</PackageReference>
<PackageReference Include="MiniProfiler" Version="4.0.138" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="NPoco" Version="4.0.2" />
<PackageReference Include="Serilog">
<Version>2.9.0</Version>
</PackageReference>
<PackageReference Include="Serilog.Enrichers.Process">
<Version>2.0.1</Version>
</PackageReference>
<PackageReference Include="Serilog.Enrichers.Thread">
<Version>3.1.0</Version>
</PackageReference>
<PackageReference Include="Serilog.Filters.Expressions">
<Version>2.0.0</Version>
</PackageReference>
<PackageReference Include="Serilog.Formatting.Compact">
<Version>1.1.0</Version>
</PackageReference>
<PackageReference Include="Serilog.Formatting.Compact.Reader">
<Version>1.0.3</Version>
</PackageReference>
<PackageReference Include="Serilog.Settings.AppSettings">
<Version>2.2.2</Version>
</PackageReference>
<PackageReference Include="Serilog.Sinks.File">
<Version>4.1.0</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<!--
this does not fully work - breaks intellisense
Exclude="Constants-*.cs"
<Compile Include="Constants-*.cs">
<DependentUpon>Constants.cs</DependentUpon>
</Compile>
-->
<Compile Include="MainDom.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="..\SolutionInfo.cs">
<Link>Properties\SolutionInfo.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Umbraco.Abstractions\Umbraco.Abstractions.csproj">
<Project>{29aa69d9-b597-4395-8d42-43b1263c240a}</Project>
<Name>Umbraco.Abstractions</Name>
</ProjectReference>
<ProjectReference Include="..\Umbraco.Infrastructure\Umbraco.Infrastructure.csproj">
<Project>{3ae7bf57-966b-45a5-910a-954d7c554441}</Project>
<Name>Umbraco.Infrastructure</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -110,10 +110,6 @@
<Project>{29aa69d9-b597-4395-8d42-43b1263c240a}</Project>
<Name>Umbraco.Abstractions</Name>
</ProjectReference>
<ProjectReference Include="..\Umbraco.Core\Umbraco.Core.csproj">
<Project>{31785bc3-256c-4613-b2f5-a1b0bdded8c1}</Project>
<Name>Umbraco.Core</Name>
</ProjectReference>
<ProjectReference Include="..\Umbraco.Infrastructure\Umbraco.Infrastructure.csproj">
<Project>{3ae7bf57-966b-45a5-910a-954d7c554441}</Project>
<Name>Umbraco.Infrastructure</Name>

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Threading;
using System.Web.Hosting;
using Umbraco.Core.Hosting;
using Umbraco.Core.Logging;
@@ -16,11 +15,12 @@ namespace Umbraco.Core
/// <para>When an AppDomain starts, it tries to acquire the main domain status.</para>
/// <para>When an AppDomain stops (eg the application is restarting) it should release the main domain status.</para>
/// </remarks>
internal class MainDom : IMainDom, IRegisteredObject, IDisposable
public class MainDom : IMainDom, IRegisteredObject, IDisposable
{
#region Vars
private readonly ILogger _logger;
private readonly IHostingEnvironment _hostingEnvironment;
// our own lock for local consistency
private object _locko = new object();
@@ -50,9 +50,11 @@ namespace Umbraco.Core
// initializes a new instance of MainDom
public MainDom(ILogger logger, IHostingEnvironment hostingEnvironment)
{
HostingEnvironment.RegisterObject(this);
hostingEnvironment.RegisterObject(this);
_logger = logger;
_hostingEnvironment = hostingEnvironment;
// HostingEnvironment.ApplicationID is null in unit tests, making ReplaceNonAlphanumericChars fail
var appId = hostingEnvironment.ApplicationId?.ReplaceNonAlphanumericChars(string.Empty);
@@ -216,7 +218,7 @@ namespace Umbraco.Core
// The web app is stopping, need to wind down
Dispose(true);
HostingEnvironment.UnregisterObject(this);
_hostingEnvironment.UnregisterObject(this);
}
#region IDisposable Support

View File

@@ -10,9 +10,9 @@ using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
using System.Web.Compilation;
using System.Web.Hosting;
using System.Web.WebPages.Razor;
using Umbraco.Core;
using Umbraco.Core.Hosting;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.ModelsBuilder.Embedded.Building;
@@ -41,20 +41,22 @@ namespace Umbraco.ModelsBuilder.Embedded
private static readonly string[] OurFiles = { "models.hash", "models.generated.cs", "all.generated.cs", "all.dll.path", "models.err" };
private readonly IModelsBuilderConfig _config;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly ModelsGenerationError _errors;
public PureLiveModelFactory(Lazy<UmbracoServices> umbracoServices, IProfilingLogger logger, IModelsBuilderConfig config)
public PureLiveModelFactory(Lazy<UmbracoServices> umbracoServices, IProfilingLogger logger, IModelsBuilderConfig config, IHostingEnvironment hostingEnvironment)
{
_umbracoServices = umbracoServices;
_logger = logger;
_config = config;
_hostingEnvironment = hostingEnvironment;
_errors = new ModelsGenerationError(config);
_ver = 1; // zero is for when we had no version
_skipver = -1; // nothing to skip
RazorBuildProvider.CodeGenerationStarted += RazorBuildProvider_CodeGenerationStarted;
if (!HostingEnvironment.IsHosted) return;
if (!_hostingEnvironment.IsHosted) return;
var modelsDirectory = _config.ModelsDirectory;
if (!Directory.Exists(modelsDirectory))
@@ -63,7 +65,7 @@ namespace Umbraco.ModelsBuilder.Embedded
// BEWARE! if the watcher is not properly released then for some reason the
// BuildManager will start confusing types - using a 'registered object' here
// though we should probably plug into Umbraco's MainDom - which is internal
HostingEnvironment.RegisterObject(this);
_hostingEnvironment.RegisterObject(this);
_watcher = new FileSystemWatcher(modelsDirectory);
_watcher.Changed += WatcherOnChanged;
_watcher.EnableRaisingEvents = true;
@@ -667,7 +669,7 @@ namespace Umbraco.ModelsBuilder.Embedded
{
_watcher.EnableRaisingEvents = false;
_watcher.Dispose();
HostingEnvironment.UnregisterObject(this);
_hostingEnvironment.UnregisterObject(this);
}
#endregion

View File

@@ -105,10 +105,6 @@
<Project>{29aa69d9-b597-4395-8d42-43b1263c240a}</Project>
<Name>Umbraco.Abstractions</Name>
</ProjectReference>
<ProjectReference Include="..\Umbraco.Core\Umbraco.Core.csproj">
<Project>{31785BC3-256C-4613-B2F5-A1B0BDDED8C1}</Project>
<Name>Umbraco.Core</Name>
</ProjectReference>
<ProjectReference Include="..\Umbraco.Infrastructure\Umbraco.Infrastructure.csproj">
<Project>{3ae7bf57-966b-45a5-910a-954d7c554441}</Project>
<Name>Umbraco.Infrastructure</Name>

View File

@@ -148,7 +148,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
LongRunning = true,
KeepAlive = true,
Hosted = false // main domain will take care of stopping the runner (see below)
}, logger);
}, logger, _hostingEnvironment);
// create (and add to runner)
_persisterTask = new XmlStoreFilePersister(runner, this, logger);

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Web.Hosting;
using Examine;
using Moq;
using NUnit.Framework;

View File

@@ -6,6 +6,7 @@ using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Hosting;
using Umbraco.Core.Logging;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web.Scheduling;
@@ -18,17 +19,19 @@ namespace Umbraco.Tests.Scheduling
public class BackgroundTaskRunnerTests
{
private ILogger _logger;
private IHostingEnvironment _hostingEnvironment;
[OneTimeSetUp]
public void InitializeFixture()
{
_logger = new ConsoleLogger(new MessageTemplates());
_hostingEnvironment = TestHelper.GetHostingEnvironment();
}
[Test]
public async Task ShutdownWhenRunningWithWait()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
var stopped = false;
runner.Stopped += (sender, args) => { stopped = true; };
@@ -51,7 +54,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task ShutdownWhenRunningWithoutWait()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
var stopped = false;
runner.Stopped += (sender, args) => { stopped = true; };
@@ -78,7 +81,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task ShutdownCompletesTheRunner()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
Assert.IsFalse(runner.IsRunning); // because AutoStart is false
@@ -101,7 +104,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task ShutdownFlushesTheQueue()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
MyTask t1, t2, t3;
@@ -123,7 +126,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task ShutdownForceTruncatesTheQueue()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
MyTask t1, t2, t3;
@@ -150,7 +153,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task ShutdownThenForce()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
Assert.IsFalse(runner.IsRunning); // because AutoStart is false
@@ -185,7 +188,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task HostingStopNonImmediate()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
MyTask t;
@@ -219,7 +222,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task HostingStopImmediate()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
MyTask t;
@@ -254,7 +257,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public void Create_IsNotRunning()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
Assert.IsFalse(runner.IsRunning);
}
@@ -268,7 +271,7 @@ namespace Umbraco.Tests.Scheduling
{
AutoStart = true,
KeepAlive = true // else stops!
}, _logger))
}, _logger, _hostingEnvironment))
{
Assert.IsTrue(runner.IsRunning); // because AutoStart is true
await runner.StopInternal(false); // keepalive = must be stopped
@@ -278,7 +281,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public void Create_AutoStartAndKeepAlive_IsRunning()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { AutoStart = true, KeepAlive = true }, _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { AutoStart = true, KeepAlive = true }, _logger, _hostingEnvironment))
{
Assert.IsTrue(runner.IsRunning); // because AutoStart is true
Thread.Sleep(800); // for long
@@ -291,7 +294,7 @@ namespace Umbraco.Tests.Scheduling
public async Task Dispose_IsRunning()
{
BackgroundTaskRunner<IBackgroundTask> runner;
using (runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { AutoStart = true, KeepAlive = true }, _logger))
using (runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { AutoStart = true, KeepAlive = true }, _logger, _hostingEnvironment))
{
Assert.IsTrue(runner.IsRunning);
// dispose will stop it
@@ -315,7 +318,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public void Startup_KeepAlive_IsRunning()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { KeepAlive = true }, _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { KeepAlive = true }, _logger, _hostingEnvironment))
{
Assert.IsFalse(runner.IsRunning);
runner.StartUp();
@@ -327,7 +330,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task Create_AddTask_IsRunning()
{
using (var runner = new BackgroundTaskRunner<BaseTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<BaseTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
var waitHandle = new ManualResetEvent(false);
runner.TaskCompleted += (sender, args) =>
@@ -345,7 +348,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public void Create_KeepAliveAndAddTask_IsRunning()
{
using (var runner = new BackgroundTaskRunner<BaseTask>(new BackgroundTaskRunnerOptions { KeepAlive = true }, _logger))
using (var runner = new BackgroundTaskRunner<BaseTask>(new BackgroundTaskRunnerOptions { KeepAlive = true }, _logger, _hostingEnvironment))
{
var waitHandle = new ManualResetEvent(false);
runner.TaskCompleted += (sender, args) =>
@@ -363,7 +366,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task WaitOnRunner_OneTask()
{
using (var runner = new BackgroundTaskRunner<BaseTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<BaseTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
var task = new MyTask();
Assert.IsTrue(task.Ended == default(DateTime));
@@ -382,7 +385,7 @@ namespace Umbraco.Tests.Scheduling
for (var i = 0; i < 10; i++)
tasks.Add(new MyTask());
using (var runner = new BackgroundTaskRunner<BaseTask>(new BackgroundTaskRunnerOptions { KeepAlive = false, LongRunning = true, PreserveRunningTask = true }, _logger))
using (var runner = new BackgroundTaskRunner<BaseTask>(new BackgroundTaskRunnerOptions { KeepAlive = false, LongRunning = true, PreserveRunningTask = true }, _logger, _hostingEnvironment))
{
tasks.ForEach(runner.Add);
@@ -400,7 +403,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task WaitOnTask()
{
using (var runner = new BackgroundTaskRunner<BaseTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<BaseTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
var task = new MyTask();
var waitHandle = new ManualResetEvent(false);
@@ -420,7 +423,7 @@ namespace Umbraco.Tests.Scheduling
for (var i = 0; i < 10; i++)
tasks.Add(new MyTask(), new ManualResetEvent(false));
using (var runner = new BackgroundTaskRunner<BaseTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<BaseTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
runner.TaskCompleted += (sender, task) => tasks[task.Task].Set();
foreach (var t in tasks) runner.Add(t.Key);
@@ -449,7 +452,7 @@ namespace Umbraco.Tests.Scheduling
IDictionary<BaseTask, ManualResetEvent> tasks = getTasks();
BackgroundTaskRunner<BaseTask> tManager;
using (tManager = new BackgroundTaskRunner<BaseTask>(new BackgroundTaskRunnerOptions { LongRunning = true, KeepAlive = true }, _logger))
using (tManager = new BackgroundTaskRunner<BaseTask>(new BackgroundTaskRunnerOptions { LongRunning = true, KeepAlive = true }, _logger, _hostingEnvironment))
{
tManager.TaskCompleted += (sender, task) => tasks[task.Task].Set();
@@ -495,7 +498,7 @@ namespace Umbraco.Tests.Scheduling
List<BaseTask> tasks = getTasks();
using (var tManager = new BackgroundTaskRunner<BaseTask>(new BackgroundTaskRunnerOptions { LongRunning = true, PreserveRunningTask = true }, _logger))
using (var tManager = new BackgroundTaskRunner<BaseTask>(new BackgroundTaskRunnerOptions { LongRunning = true, PreserveRunningTask = true }, _logger, _hostingEnvironment))
{
tasks.ForEach(tManager.Add);
@@ -537,7 +540,7 @@ namespace Umbraco.Tests.Scheduling
{
var runCount = 0;
var waitHandle = new ManualResetEvent(false);
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
runner.TaskCompleted += (sender, args) =>
{
@@ -568,7 +571,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task LatchedTaskRuns()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
var task = new MyLatchedTask(200, false);
runner.Add(task);
@@ -588,7 +591,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task LatchedTaskStops_Runs_On_Shutdown()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
var task = new MyLatchedTask(200, true);
runner.Add(task);
@@ -608,7 +611,7 @@ namespace Umbraco.Tests.Scheduling
{
var runCount = 0;
var waitHandle = new ManualResetEvent(false);
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
runner.TaskCompleted += (sender, args) =>
{
@@ -635,7 +638,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task FailingTaskSync()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
var exceptions = new ConcurrentQueue<Exception>();
runner.TaskError += (sender, args) => exceptions.Enqueue(args.Exception);
@@ -652,7 +655,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task FailingTaskDisposing()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
var exceptions = new ConcurrentQueue<Exception>();
runner.TaskError += (sender, args) => exceptions.Enqueue(args.Exception);
@@ -669,7 +672,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task FailingTaskAsync()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
var exceptions = new ConcurrentQueue<Exception>();
runner.TaskError += (sender, args) => exceptions.Enqueue(args.Exception);
@@ -685,7 +688,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task FailingTaskDisposingAsync()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
var exceptions = new ConcurrentQueue<Exception>();
runner.TaskError += (sender, args) => exceptions.Enqueue(args.Exception);
@@ -702,7 +705,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task CancelAsyncTask()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
var task = new MyAsyncTask(4000);
runner.Add(task);
@@ -718,7 +721,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public async Task CancelLatchedTask()
{
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger))
using (var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions(), _logger, _hostingEnvironment))
{
var task = new MyLatchedTask(4000, false);
runner.Add(task);
@@ -931,7 +934,7 @@ namespace Umbraco.Tests.Scheduling
[Test]
public void SourceTaskTest()
{
var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, _logger);
var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, _logger, TestHelper.GetHostingEnvironment());
var task = new SourceTask();
runner.Add(task);

View File

@@ -22,7 +22,7 @@ namespace Umbraco.Tests.Scheduling
public async Task ThreadResumeIssue()
{
var logger = new DebugDiagnosticsLogger(new MessageTemplates());
var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, logger);
var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, logger, TestHelper.GetHostingEnvironment());
var work = new ThreadResumeIssueWorkItem();
runner.Add(work);
@@ -77,7 +77,7 @@ namespace Umbraco.Tests.Scheduling
public async Task DebuggerInterferenceIssue()
{
var logger = new DebugDiagnosticsLogger(new MessageTemplates());
var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, logger);
var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, logger, TestHelper.GetHostingEnvironment());
var taskCompleted = false;
runner.TaskCompleted += (sender, args) =>
{

View File

@@ -352,7 +352,7 @@ namespace Umbraco.Tests.Testing
{
return new TypeLoader(ioHelper, typeFinder, runtimeCache, new DirectoryInfo(hostingEnvironment.LocalTempPath), logger, false, new[]
{
Assembly.Load("Umbraco.Core"),
Assembly.Load("Umbraco.Abstractions"),
Assembly.Load("Umbraco.Web"),
Assembly.Load("Umbraco.Tests"),
Assembly.Load("Umbraco.Infrastructure")

View File

@@ -17,7 +17,7 @@
<!-- Default JSON log file -->
<!-- This is used by the default log viewer in the Umbraco backoffice -->
<add key="serilog:using:File" value="Umbraco.Core" />
<add key="serilog:using:File" value="Umbraco.Infrastructure" />
<add key="serilog:write-to:File.formatter" value="Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact" />
<add key="serilog:write-to:File.path" value="%BASEDIR%\App_Data\Logs\UmbracoTraceLog.%MACHINENAME%..json" />
<add key="serilog:write-to:File.restrictedToMinimumLevel" value="Debug" />

View File

@@ -2,6 +2,7 @@
using System.Threading;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Hosting;
using Umbraco.Core.Logging;
using Umbraco.Core.Services;
using Umbraco.Core.Services.Changes;
@@ -92,7 +93,7 @@ namespace Umbraco.Web.Compose
private IBackgroundTask[] _tasks;
private IndexRebuilder _indexRebuilder;
public DatabaseServerRegistrarAndMessengerComponent(IRuntimeState runtime, IServerRegistrar serverRegistrar, IServerMessenger serverMessenger, IServerRegistrationService registrationService, ILogger logger, IndexRebuilder indexRebuilder)
public DatabaseServerRegistrarAndMessengerComponent(IRuntimeState runtime, IServerRegistrar serverRegistrar, IServerMessenger serverMessenger, IServerRegistrationService registrationService, ILogger logger, IHostingEnvironment hostingEnvironment, IndexRebuilder indexRebuilder)
{
_runtime = runtime;
_logger = logger;
@@ -104,7 +105,7 @@ namespace Umbraco.Web.Compose
if (_registrar != null)
{
_touchTaskRunner = new BackgroundTaskRunner<IBackgroundTask>("ServerRegistration",
new BackgroundTaskRunnerOptions { AutoStart = true }, logger);
new BackgroundTaskRunnerOptions { AutoStart = true }, logger, hostingEnvironment);
}
// create task runner for BatchedDatabaseServerMessenger
@@ -112,7 +113,7 @@ namespace Umbraco.Web.Compose
if (_messenger != null)
{
_processTaskRunner = new BackgroundTaskRunner<IBackgroundTask>("ServerInstProcess",
new BackgroundTaskRunnerOptions { AutoStart = true }, logger);
new BackgroundTaskRunnerOptions { AutoStart = true }, logger, hostingEnvironment);
}
}

View File

@@ -1,15 +1,21 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Web;
using System.Web.Hosting;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Hosting;
using Umbraco.Core.IO;
using IRegisteredObject = Umbraco.Core.IRegisteredObject;
namespace Umbraco.Web.Hosting
{
public class AspNetHostingEnvironment : IHostingEnvironment
{
private readonly ConcurrentDictionary<IRegisteredObject, RegisteredObjectWrapper> _registeredObjects =
new ConcurrentDictionary<IRegisteredObject, RegisteredObjectWrapper>();
private readonly IHostingSettings _hostingSettings;
private string _localTempPath;
@@ -44,6 +50,23 @@ namespace Umbraco.Web.Hosting
HttpRuntime.UnloadAppDomain();
}
public void RegisterObject(IRegisteredObject registeredObject)
{
var wrapped = new RegisteredObjectWrapper(registeredObject);
if (!_registeredObjects.TryAdd(registeredObject, wrapped))
{
throw new InvalidOperationException("Could not register object");
}
HostingEnvironment.RegisterObject(wrapped);
}
public void UnregisterObject(IRegisteredObject registeredObject)
{
if (_registeredObjects.TryGetValue(registeredObject, out var wrapped))
{
HostingEnvironment.UnregisterObject(wrapped);
}
}
public string LocalTempPath
{
@@ -82,6 +105,21 @@ namespace Umbraco.Web.Hosting
}
}
}
private class RegisteredObjectWrapper : System.Web.Hosting.IRegisteredObject
{
private readonly IRegisteredObject _inner;
public RegisteredObjectWrapper(IRegisteredObject inner)
{
_inner = inner;
}
public void Stop(bool immediate)
{
_inner.Stop(immediate);
}
}
}
}

View File

@@ -5,6 +5,7 @@ using System.Threading.Tasks.Dataflow;
using System.Web.Hosting;
using Umbraco.Core;
using Umbraco.Core.Events;
using Umbraco.Core.Hosting;
using Umbraco.Core.Logging;
namespace Umbraco.Web.Scheduling
@@ -81,6 +82,7 @@ namespace Umbraco.Web.Scheduling
private readonly string _logPrefix;
private readonly BackgroundTaskRunnerOptions _options;
private readonly ILogger _logger;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly object _locker = new object();
private readonly BufferBlock<T> _tasks = new BufferBlock<T>(new DataflowBlockOptions());
@@ -102,9 +104,10 @@ namespace Umbraco.Web.Scheduling
/// Initializes a new instance of the <see cref="BackgroundTaskRunner{T}"/> class.
/// </summary>
/// <param name="logger">A logger.</param>
/// <param name="hostingEnvironment">The hosting environment</param>
/// <param name="hook">An optional main domain hook.</param>
public BackgroundTaskRunner(ILogger logger, MainDomHook hook = null)
: this(typeof(T).FullName, new BackgroundTaskRunnerOptions(), logger, hook)
public BackgroundTaskRunner(ILogger logger, IHostingEnvironment hostingEnvironment, MainDomHook hook = null)
: this(typeof(T).FullName, new BackgroundTaskRunnerOptions(), logger, hostingEnvironment, hook)
{ }
/// <summary>
@@ -112,9 +115,10 @@ namespace Umbraco.Web.Scheduling
/// </summary>
/// <param name="name">The name of the runner.</param>
/// <param name="logger">A logger.</param>
/// <param name="hostingEnvironment">The hosting environment</param>
/// <param name="hook">An optional main domain hook.</param>
public BackgroundTaskRunner(string name, ILogger logger, MainDomHook hook = null)
: this(name, new BackgroundTaskRunnerOptions(), logger, hook)
public BackgroundTaskRunner(string name, ILogger logger, IHostingEnvironment hostingEnvironment, MainDomHook hook = null)
: this(name, new BackgroundTaskRunnerOptions(), logger, hostingEnvironment, hook)
{ }
/// <summary>
@@ -122,9 +126,10 @@ namespace Umbraco.Web.Scheduling
/// </summary>
/// <param name="options">The set of options.</param>
/// <param name="logger">A logger.</param>
/// <param name="hostingEnvironment">The hosting environment</param>
/// <param name="hook">An optional main domain hook.</param>
public BackgroundTaskRunner(BackgroundTaskRunnerOptions options, ILogger logger, MainDomHook hook = null)
: this(typeof(T).FullName, options, logger, hook)
public BackgroundTaskRunner(BackgroundTaskRunnerOptions options, ILogger logger, IHostingEnvironment hostingEnvironment, MainDomHook hook = null)
: this(typeof(T).FullName, options, logger, hostingEnvironment, hook)
{ }
/// <summary>
@@ -133,15 +138,17 @@ namespace Umbraco.Web.Scheduling
/// <param name="name">The name of the runner.</param>
/// <param name="options">The set of options.</param>
/// <param name="logger">A logger.</param>
/// <param name="hostingEnvironment">The hosting environment</param>
/// <param name="hook">An optional main domain hook.</param>
public BackgroundTaskRunner(string name, BackgroundTaskRunnerOptions options, ILogger logger, MainDomHook hook = null)
public BackgroundTaskRunner(string name, BackgroundTaskRunnerOptions options, ILogger logger, IHostingEnvironment hostingEnvironment, MainDomHook hook = null)
{
_options = options ?? throw new ArgumentNullException(nameof(options));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_hostingEnvironment = hostingEnvironment;
_logPrefix = "[" + name + "] ";
if (options.Hosted)
HostingEnvironment.RegisterObject(this);
_hostingEnvironment.RegisterObject(this);
if (hook != null)
_completed = _terminated = hook.Register() == false;
@@ -212,7 +219,7 @@ namespace Umbraco.Web.Scheduling
/// <remarks>
/// <para>Used to wait until the runner has terminated.</para>
/// <para>
/// The only time the runner will be terminated is by the Hosting Environment when the application is being shutdown.
/// The only time the runner will be terminated is by the Hosting Environment when the application is being shutdown.
/// </para>
/// </remarks>
internal ThreadingTaskImmutable TerminatedAwaitable
@@ -350,14 +357,14 @@ namespace Umbraco.Web.Scheduling
if (force)
{
// we must bring everything down, now
// we must bring everything down, now
lock (_locker)
{
// was Complete() enough?
// if _tasks.Complete() ended up triggering code to stop the runner and reset
// the _isRunning flag, then there's no need to initiate a cancel on the cancelation token.
if (_isRunning == false)
return;
return;
}
// try to cancel running async tasks (cannot do much about sync tasks)
@@ -805,7 +812,7 @@ namespace Umbraco.Web.Scheduling
if (immediate)
{
//only unregister when it's the final call, else we won't be notified of the final call
HostingEnvironment.UnregisterObject(this);
_hostingEnvironment.UnregisterObject(this);
}
if (_terminated) return; // already taken care of

View File

@@ -1,5 +1,5 @@
using System;
using System.Web.Hosting;
using Umbraco.Core;
namespace Umbraco.Web.Scheduling
{

View File

@@ -6,6 +6,7 @@ using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration.HealthChecks;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Hosting;
using Umbraco.Core.Logging;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
@@ -26,6 +27,7 @@ namespace Umbraco.Web.Scheduling
private readonly IContentService _contentService;
private readonly IAuditService _auditService;
private readonly IProfilingLogger _logger;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly IScopeProvider _scopeProvider;
private readonly HealthCheckCollection _healthChecks;
private readonly HealthCheckNotificationMethodCollection _notifications;
@@ -45,13 +47,14 @@ namespace Umbraco.Web.Scheduling
public SchedulerComponent(IRuntimeState runtime,
IContentService contentService, IAuditService auditService,
HealthCheckCollection healthChecks, HealthCheckNotificationMethodCollection notifications,
IScopeProvider scopeProvider, IUmbracoContextFactory umbracoContextFactory, IProfilingLogger logger)
IScopeProvider scopeProvider, IUmbracoContextFactory umbracoContextFactory, IProfilingLogger logger, IHostingEnvironment hostingEnvironment)
{
_runtime = runtime;
_contentService = contentService;
_auditService = auditService;
_scopeProvider = scopeProvider;
_logger = logger;
_hostingEnvironment = hostingEnvironment;
_umbracoContextFactory = umbracoContextFactory;
_healthChecks = healthChecks;
@@ -61,12 +64,12 @@ namespace Umbraco.Web.Scheduling
public void Initialize()
{
// backgrounds runners are web aware, if the app domain dies, these tasks will wind down correctly
_keepAliveRunner = new BackgroundTaskRunner<IBackgroundTask>("KeepAlive", _logger);
_publishingRunner = new BackgroundTaskRunner<IBackgroundTask>("ScheduledPublishing", _logger);
_tasksRunner = new BackgroundTaskRunner<IBackgroundTask>("ScheduledTasks", _logger);
_scrubberRunner = new BackgroundTaskRunner<IBackgroundTask>("LogScrubber", _logger);
_fileCleanupRunner = new BackgroundTaskRunner<IBackgroundTask>("TempFileCleanup", _logger);
_healthCheckRunner = new BackgroundTaskRunner<IBackgroundTask>("HealthCheckNotifier", _logger);
_keepAliveRunner = new BackgroundTaskRunner<IBackgroundTask>("KeepAlive", _logger, _hostingEnvironment);
_publishingRunner = new BackgroundTaskRunner<IBackgroundTask>("ScheduledPublishing", _logger, _hostingEnvironment);
_tasksRunner = new BackgroundTaskRunner<IBackgroundTask>("ScheduledTasks", _logger, _hostingEnvironment);
_scrubberRunner = new BackgroundTaskRunner<IBackgroundTask>("LogScrubber", _logger, _hostingEnvironment);
_fileCleanupRunner = new BackgroundTaskRunner<IBackgroundTask>("TempFileCleanup", _logger, _hostingEnvironment);
_healthCheckRunner = new BackgroundTaskRunner<IBackgroundTask>("HealthCheckNotifier", _logger, _hostingEnvironment);
// we will start the whole process when a successful request is made
UmbracoModule.RouteAttempt += RegisterBackgroundTasksOnce;

View File

@@ -4,6 +4,7 @@ using Umbraco.Core.Logging;
using Umbraco.Examine;
using System.Threading.Tasks;
using Umbraco.Core;
using Umbraco.Core.Hosting;
using Umbraco.Web.Scheduling;
namespace Umbraco.Web.Search
@@ -17,12 +18,14 @@ namespace Umbraco.Web.Search
private readonly IndexRebuilder _indexRebuilder;
private readonly IMainDom _mainDom;
private readonly IProfilingLogger _logger;
private readonly IHostingEnvironment _hostingEnvironment;
private static BackgroundTaskRunner<IBackgroundTask> _rebuildOnStartupRunner;
public BackgroundIndexRebuilder(IMainDom mainDom, IProfilingLogger logger, IndexRebuilder indexRebuilder)
public BackgroundIndexRebuilder(IMainDom mainDom, IProfilingLogger logger, IHostingEnvironment hostingEnvironment, IndexRebuilder indexRebuilder)
{
_mainDom = mainDom;
_logger = logger;
_hostingEnvironment = hostingEnvironment;
_indexRebuilder = indexRebuilder;
}
@@ -51,7 +54,7 @@ namespace Umbraco.Web.Search
_rebuildOnStartupRunner = new BackgroundTaskRunner<IBackgroundTask>(
"RebuildIndexesOnStartup",
_logger);
_logger, _hostingEnvironment);
_rebuildOnStartupRunner.TryAdd(task);
}

View File

@@ -60,8 +60,6 @@ Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Umbraco.Web.UI.Client", "ht
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Web", "Umbraco.Web\Umbraco.Web.csproj", "{651E1350-91B6-44B7-BD60-7207006D7003}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Core", "Umbraco.Core\Umbraco.Core.csproj", "{31785BC3-256C-4613-B2F5-A1B0BDDED8C1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Tests", "Umbraco.Tests\Umbraco.Tests.csproj", "{5D3B8245-ADA6-453F-A008-50ED04BFE770}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Examine", "Umbraco.Examine\Umbraco.Examine.csproj", "{07FBC26B-2927-4A22-8D96-D644C667FECC}"
@@ -128,10 +126,6 @@ Global
{651E1350-91B6-44B7-BD60-7207006D7003}.Debug|Any CPU.Build.0 = Debug|Any CPU
{651E1350-91B6-44B7-BD60-7207006D7003}.Release|Any CPU.ActiveCfg = Release|Any CPU
{651E1350-91B6-44B7-BD60-7207006D7003}.Release|Any CPU.Build.0 = Release|Any CPU
{31785BC3-256C-4613-B2F5-A1B0BDDED8C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{31785BC3-256C-4613-B2F5-A1B0BDDED8C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{31785BC3-256C-4613-B2F5-A1B0BDDED8C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31785BC3-256C-4613-B2F5-A1B0BDDED8C1}.Release|Any CPU.Build.0 = Release|Any CPU
{5D3B8245-ADA6-453F-A008-50ED04BFE770}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D3B8245-ADA6-453F-A008-50ED04BFE770}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5D3B8245-ADA6-453F-A008-50ED04BFE770}.Release|Any CPU.ActiveCfg = Release|Any CPU