mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-14 19:04:51 +08:00
Adding a background task sweep generator. Updated cms page scheduler processing as a background task.
--HG-- extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4042426
This commit is contained in:
@@ -38,7 +38,8 @@ namespace Orchard.Tests.Environment {
|
|||||||
new[] { modelBinderProvider1, modelBinderProvider2 },
|
new[] { modelBinderProvider1, modelBinderProvider2 },
|
||||||
modelBinderPublisher,
|
modelBinderPublisher,
|
||||||
new ViewEngineCollection(),
|
new ViewEngineCollection(),
|
||||||
new Moq.Mock<IPackageManager>().Object);
|
new Moq.Mock<IPackageManager>().Object,
|
||||||
|
Enumerable.Empty<IOrchardShellEvents>());
|
||||||
|
|
||||||
runtime.Activate();
|
runtime.Activate();
|
||||||
|
|
||||||
|
77
src/Orchard.Tests/EventsTests.cs
Normal file
77
src/Orchard.Tests/EventsTests.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using Orchard.Logging;
|
||||||
|
|
||||||
|
namespace Orchard.Tests {
|
||||||
|
[TestFixture]
|
||||||
|
public class EventsTests {
|
||||||
|
[Test]
|
||||||
|
public void AllEventsAreCalled() {
|
||||||
|
var events = new ITestEvents[] { new FooSink(), new BarSink() };
|
||||||
|
|
||||||
|
events.Invoke(x => x.Hello("world"), NullLogger.Instance);
|
||||||
|
|
||||||
|
Assert.That(events.OfType<FooSink>().Single().Name, Is.EqualTo("world"));
|
||||||
|
Assert.That(events.OfType<BarSink>().Single().Name, Is.EqualTo("world"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void AnExceptionShouldBeLoggedAndOtherEventsWillBeFired() {
|
||||||
|
var events = new ITestEvents[] { new FooSink(), new CrashSink(), new BarSink() };
|
||||||
|
|
||||||
|
var logger = new TestLogger();
|
||||||
|
|
||||||
|
events.Invoke(x => x.Hello("world"), logger);
|
||||||
|
|
||||||
|
Assert.That(events.OfType<FooSink>().Single().Name, Is.EqualTo("world"));
|
||||||
|
Assert.That(events.OfType<BarSink>().Single().Name, Is.EqualTo("world"));
|
||||||
|
Assert.That(logger.LogException, Is.TypeOf<ApplicationException>());
|
||||||
|
Assert.That(logger.LogException, Has.Property("Message").EqualTo("Illegal name 'world'"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestLogger : ILogger {
|
||||||
|
public bool IsEnabled(LogLevel level) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(LogLevel level, Exception exception, string format, params object[] args) {
|
||||||
|
LogException = exception;
|
||||||
|
LogFormat = format;
|
||||||
|
LogArgs = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Exception LogException { get; set; }
|
||||||
|
public string LogFormat { get; set; }
|
||||||
|
public object[] LogArgs { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface ITestEvents : IEvents {
|
||||||
|
void Hello(string name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FooSink : ITestEvents {
|
||||||
|
void ITestEvents.Hello(string name) {
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarSink : ITestEvents {
|
||||||
|
void ITestEvents.Hello(string name) {
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class CrashSink : ITestEvents {
|
||||||
|
void ITestEvents.Hello(string name) {
|
||||||
|
throw new ApplicationException("Illegal name '" + name + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -104,6 +104,7 @@
|
|||||||
<Compile Include="Environment\DefaultOrchardHostTests.cs" />
|
<Compile Include="Environment\DefaultOrchardHostTests.cs" />
|
||||||
<Compile Include="Environment\DefaultOrchardShellTests.cs" />
|
<Compile Include="Environment\DefaultOrchardShellTests.cs" />
|
||||||
<Compile Include="Environment\OrchardStarterTests.cs" />
|
<Compile Include="Environment\OrchardStarterTests.cs" />
|
||||||
|
<Compile Include="EventsTests.cs" />
|
||||||
<Compile Include="Localization\NullLocalizerTests.cs" />
|
<Compile Include="Localization\NullLocalizerTests.cs" />
|
||||||
<Compile Include="Logging\LoggingModuleTests.cs" />
|
<Compile Include="Logging\LoggingModuleTests.cs" />
|
||||||
<Compile Include="Models\ContentQueryTests.cs" />
|
<Compile Include="Models\ContentQueryTests.cs" />
|
||||||
@@ -127,6 +128,7 @@
|
|||||||
<Compile Include="Mvc\OrchardControllerIdentificationStrategyTests.cs" />
|
<Compile Include="Mvc\OrchardControllerIdentificationStrategyTests.cs" />
|
||||||
<Compile Include="Mvc\RouteCollectionPublisherTests.cs" />
|
<Compile Include="Mvc\RouteCollectionPublisherTests.cs" />
|
||||||
<Compile Include="Mvc\Routes\StandardPackageRouteProviderTests.cs" />
|
<Compile Include="Mvc\Routes\StandardPackageRouteProviderTests.cs" />
|
||||||
|
<Compile Include="Tasks\SweepGeneratorTests.cs" />
|
||||||
<Compile Include="UI\Notify\NotifierTests.cs" />
|
<Compile Include="UI\Notify\NotifierTests.cs" />
|
||||||
<Compile Include="UI\Notify\NotifyFilterTests.cs" />
|
<Compile Include="UI\Notify\NotifyFilterTests.cs" />
|
||||||
<Compile Include="Packages\PackageFoldersTests.cs" />
|
<Compile Include="Packages\PackageFoldersTests.cs" />
|
||||||
|
43
src/Orchard.Tests/Tasks/SweepGeneratorTests.cs
Normal file
43
src/Orchard.Tests/Tasks/SweepGeneratorTests.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
using Autofac.Builder;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using Orchard.Tasks;
|
||||||
|
|
||||||
|
namespace Orchard.Tests.Tasks {
|
||||||
|
[TestFixture]
|
||||||
|
public class SweepGeneratorTests {
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void DoWorkShouldSendHeartbeatToTaskManager() {
|
||||||
|
var taskManager = new Mock<IBackgroundService>();
|
||||||
|
|
||||||
|
var builder = new ContainerBuilder();
|
||||||
|
builder.Register(taskManager.Object);
|
||||||
|
var container = builder.Build();
|
||||||
|
|
||||||
|
var heartbeatSource = new SweepGenerator(container);
|
||||||
|
heartbeatSource.DoWork();
|
||||||
|
taskManager.Verify(x => x.Sweep(), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ActivatedEventShouldStartTimer() {
|
||||||
|
var taskManager = new Mock<IBackgroundService>();
|
||||||
|
|
||||||
|
var builder = new ContainerBuilder();
|
||||||
|
builder.Register(taskManager.Object);
|
||||||
|
var container = builder.Build();
|
||||||
|
|
||||||
|
var heartbeatSource = new SweepGenerator(container) {
|
||||||
|
Interval = TimeSpan.FromMilliseconds(25)
|
||||||
|
};
|
||||||
|
|
||||||
|
taskManager.Verify(x => x.Sweep(), Times.Never());
|
||||||
|
heartbeatSource.Activated();
|
||||||
|
System.Threading.Thread.Sleep(TimeSpan.FromMilliseconds(80));
|
||||||
|
heartbeatSource.Terminating();
|
||||||
|
taskManager.Verify(x => x.Sweep(), Times.AtLeastOnce());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -6,11 +6,11 @@ using JetBrains.Annotations;
|
|||||||
using Orchard.CmsPages.Models;
|
using Orchard.CmsPages.Models;
|
||||||
using Orchard.Data;
|
using Orchard.Data;
|
||||||
using Orchard.Services;
|
using Orchard.Services;
|
||||||
|
using Orchard.Tasks;
|
||||||
|
|
||||||
namespace Orchard.CmsPages.Services {
|
namespace Orchard.CmsPages.Services {
|
||||||
public interface IPageScheduler : IDependency {
|
public interface IPageScheduler : IBackgroundTask {
|
||||||
void AddPublishTask(PageRevision revision, DateTime moment);
|
void AddPublishTask(PageRevision revision, DateTime moment);
|
||||||
void Sweep();
|
|
||||||
void ClearTasks(Page page);
|
void ClearTasks(Page page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
|
using System.Web.Hosting;
|
||||||
using FluentNHibernate.Automapping;
|
using FluentNHibernate.Automapping;
|
||||||
using FluentNHibernate.Automapping.Alterations;
|
using FluentNHibernate.Automapping.Alterations;
|
||||||
using FluentNHibernate.Cfg;
|
using FluentNHibernate.Cfg;
|
||||||
@@ -29,8 +30,9 @@ namespace Orchard.Data {
|
|||||||
// that would eventually imply the need for configuration against one or more actual sources
|
// that would eventually imply the need for configuration against one or more actual sources
|
||||||
// and a means to enlist record types from active packages into correct session factory
|
// and a means to enlist record types from active packages into correct session factory
|
||||||
|
|
||||||
var database =
|
var hackPath = HostingEnvironment.MapPath("~/App_Data/hack.db");
|
||||||
SQLiteConfiguration.Standard.UsingFile(HttpContext.Current.Server.MapPath("~/App_Data/hack.db"));
|
|
||||||
|
var database = SQLiteConfiguration.Standard.UsingFile(hackPath);
|
||||||
|
|
||||||
var recordTypes = _compositionStrategy.GetRecordTypes();
|
var recordTypes = _compositionStrategy.GetRecordTypes();
|
||||||
|
|
||||||
|
@@ -3,9 +3,11 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
|
using Orchard.Logging;
|
||||||
using Orchard.Mvc.ModelBinders;
|
using Orchard.Mvc.ModelBinders;
|
||||||
using Orchard.Mvc.Routes;
|
using Orchard.Mvc.Routes;
|
||||||
using Orchard.Packages;
|
using Orchard.Packages;
|
||||||
|
using Orchard.Tasks;
|
||||||
|
|
||||||
namespace Orchard.Environment {
|
namespace Orchard.Environment {
|
||||||
public class DefaultOrchardShell : IOrchardShell {
|
public class DefaultOrchardShell : IOrchardShell {
|
||||||
@@ -15,6 +17,7 @@ namespace Orchard.Environment {
|
|||||||
private readonly IModelBinderPublisher _modelBinderPublisher;
|
private readonly IModelBinderPublisher _modelBinderPublisher;
|
||||||
private readonly ViewEngineCollection _viewEngines;
|
private readonly ViewEngineCollection _viewEngines;
|
||||||
private readonly IPackageManager _packageManager;
|
private readonly IPackageManager _packageManager;
|
||||||
|
private readonly IEnumerable<IOrchardShellEvents> _events;
|
||||||
|
|
||||||
public DefaultOrchardShell(
|
public DefaultOrchardShell(
|
||||||
IEnumerable<IRouteProvider> routeProviders,
|
IEnumerable<IRouteProvider> routeProviders,
|
||||||
@@ -22,15 +25,21 @@ namespace Orchard.Environment {
|
|||||||
IEnumerable<IModelBinderProvider> modelBinderProviders,
|
IEnumerable<IModelBinderProvider> modelBinderProviders,
|
||||||
IModelBinderPublisher modelBinderPublisher,
|
IModelBinderPublisher modelBinderPublisher,
|
||||||
ViewEngineCollection viewEngines,
|
ViewEngineCollection viewEngines,
|
||||||
IPackageManager packageManager) {
|
IPackageManager packageManager,
|
||||||
|
IEnumerable<IOrchardShellEvents> events) {
|
||||||
_routeProviders = routeProviders;
|
_routeProviders = routeProviders;
|
||||||
_routePublisher = routePublisher;
|
_routePublisher = routePublisher;
|
||||||
_modelBinderProviders = modelBinderProviders;
|
_modelBinderProviders = modelBinderProviders;
|
||||||
_modelBinderPublisher = modelBinderPublisher;
|
_modelBinderPublisher = modelBinderPublisher;
|
||||||
_viewEngines = viewEngines;
|
_viewEngines = viewEngines;
|
||||||
_packageManager = packageManager;
|
_packageManager = packageManager;
|
||||||
|
_events = events;
|
||||||
|
|
||||||
|
Logger = NullLogger.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
|
|
||||||
static IEnumerable<string> OrchardLocationFormats() {
|
static IEnumerable<string> OrchardLocationFormats() {
|
||||||
return new[] {
|
return new[] {
|
||||||
@@ -50,7 +59,7 @@ namespace Orchard.Environment {
|
|||||||
_modelBinderPublisher.Publish(_modelBinderProviders.SelectMany(provider => provider.GetModelBinders()));
|
_modelBinderPublisher.Publish(_modelBinderProviders.SelectMany(provider => provider.GetModelBinders()));
|
||||||
|
|
||||||
|
|
||||||
var viewEngine = ViewEngines.Engines.OfType<VirtualPathProviderViewEngine>().Single();
|
var viewEngine = _viewEngines.OfType<VirtualPathProviderViewEngine>().Single();
|
||||||
viewEngine.AreaViewLocationFormats = OrchardLocationFormats()
|
viewEngine.AreaViewLocationFormats = OrchardLocationFormats()
|
||||||
.Concat(viewEngine.AreaViewLocationFormats)
|
.Concat(viewEngine.AreaViewLocationFormats)
|
||||||
.Distinct()
|
.Distinct()
|
||||||
@@ -66,8 +75,16 @@ namespace Orchard.Environment {
|
|||||||
.Concat(viewEngine.PartialViewLocationFormats)
|
.Concat(viewEngine.PartialViewLocationFormats)
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
|
_events.Invoke(x => x.Activated(), Logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Terminate() {
|
||||||
|
_events.Invoke(x => x.Terminating(), Logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static string ModelsLocationFormat(PackageDescriptor descriptor) {
|
private static string ModelsLocationFormat(PackageDescriptor descriptor) {
|
||||||
return Path.Combine(Path.Combine(descriptor.Location, descriptor.Name), "Views/Models/{0}.ascx");
|
return Path.Combine(Path.Combine(descriptor.Location, descriptor.Name), "Views/Models/{0}.ascx");
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
namespace Orchard.Environment {
|
namespace Orchard.Environment {
|
||||||
public interface IOrchardShell {
|
public interface IOrchardShell {
|
||||||
void Activate();
|
void Activate();
|
||||||
|
void Terminate();
|
||||||
}
|
}
|
||||||
}
|
}
|
6
src/Orchard/Environment/IOrchardShellEvents.cs
Normal file
6
src/Orchard/Environment/IOrchardShellEvents.cs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Orchard.Environment {
|
||||||
|
public interface IOrchardShellEvents : IEvents {
|
||||||
|
void Activated();
|
||||||
|
void Terminating();
|
||||||
|
}
|
||||||
|
}
|
24
src/Orchard/IEvents.cs
Normal file
24
src/Orchard/IEvents.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Orchard.Logging;
|
||||||
|
|
||||||
|
namespace Orchard {
|
||||||
|
public interface IEvents : IDependency {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class EventsExtensions {
|
||||||
|
public static void Invoke<TEvents>(this IEnumerable<TEvents> events, Action<TEvents> dispatch, ILogger logger) where TEvents : IEvents {
|
||||||
|
foreach (var sink in events) {
|
||||||
|
try {
|
||||||
|
dispatch(sink);
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
logger.Error(ex, "{2} thrown from {0} by {1}",
|
||||||
|
typeof(TEvents).Name,
|
||||||
|
sink.GetType().FullName,
|
||||||
|
ex.GetType().Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -118,6 +118,8 @@
|
|||||||
<Compile Include="Controllers\HomeController.cs" />
|
<Compile Include="Controllers\HomeController.cs" />
|
||||||
<Compile Include="Data\Conventions\AttributeCollectionConvention.cs" />
|
<Compile Include="Data\Conventions\AttributeCollectionConvention.cs" />
|
||||||
<Compile Include="Data\Conventions\CascadeAllDeleteOrphanAttribute.cs" />
|
<Compile Include="Data\Conventions\CascadeAllDeleteOrphanAttribute.cs" />
|
||||||
|
<Compile Include="Environment\IOrchardShellEvents.cs" />
|
||||||
|
<Compile Include="IEvents.cs" />
|
||||||
<Compile Include="Localization\IText.cs" />
|
<Compile Include="Localization\IText.cs" />
|
||||||
<Compile Include="Localization\LocalizationModule.cs" />
|
<Compile Include="Localization\LocalizationModule.cs" />
|
||||||
<Compile Include="Localization\LocalizationUtilities.cs" />
|
<Compile Include="Localization\LocalizationUtilities.cs" />
|
||||||
@@ -194,6 +196,9 @@
|
|||||||
<Compile Include="Settings\ISite.cs" />
|
<Compile Include="Settings\ISite.cs" />
|
||||||
<Compile Include="Settings\ISiteService.cs" />
|
<Compile Include="Settings\ISiteService.cs" />
|
||||||
<Compile Include="Settings\SettingsModule.cs" />
|
<Compile Include="Settings\SettingsModule.cs" />
|
||||||
|
<Compile Include="Tasks\BackgroundService.cs" />
|
||||||
|
<Compile Include="Tasks\IBackgroundTask.cs" />
|
||||||
|
<Compile Include="Tasks\SweepGenerator.cs" />
|
||||||
<Compile Include="UI\Menus\AdminMenuFilter.cs" />
|
<Compile Include="UI\Menus\AdminMenuFilter.cs" />
|
||||||
<Compile Include="UI\Models\ModelTemplate.cs" />
|
<Compile Include="UI\Models\ModelTemplate.cs" />
|
||||||
<Compile Include="UI\Navigation\NavigationBuilder.cs" />
|
<Compile Include="UI\Navigation\NavigationBuilder.cs" />
|
||||||
|
25
src/Orchard/Tasks/BackgroundService.cs
Normal file
25
src/Orchard/Tasks/BackgroundService.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Orchard.Logging;
|
||||||
|
|
||||||
|
namespace Orchard.Tasks {
|
||||||
|
|
||||||
|
public interface IBackgroundService : IDependency {
|
||||||
|
void Sweep();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BackgroundService : IBackgroundService {
|
||||||
|
private readonly IEnumerable<IBackgroundTask> _tasks;
|
||||||
|
|
||||||
|
public BackgroundService(IEnumerable<IBackgroundTask> tasks) {
|
||||||
|
_tasks = tasks;
|
||||||
|
Logger = NullLogger.Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
|
public void Sweep() {
|
||||||
|
_tasks.Invoke(task => task.Sweep(), Logger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
5
src/Orchard/Tasks/IBackgroundTask.cs
Normal file
5
src/Orchard/Tasks/IBackgroundTask.cs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
namespace Orchard.Tasks {
|
||||||
|
public interface IBackgroundTask : IEvents {
|
||||||
|
void Sweep();
|
||||||
|
}
|
||||||
|
}
|
97
src/Orchard/Tasks/SweepGenerator.cs
Normal file
97
src/Orchard/Tasks/SweepGenerator.cs
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
using System;
|
||||||
|
using System.Timers;
|
||||||
|
using Autofac;
|
||||||
|
using Autofac.Integration.Web;
|
||||||
|
using Orchard.Environment;
|
||||||
|
using Orchard.Logging;
|
||||||
|
|
||||||
|
namespace Orchard.Tasks {
|
||||||
|
public class SweepGenerator : IOrchardShellEvents {
|
||||||
|
private readonly IContainer _container;
|
||||||
|
private Timer _timer;
|
||||||
|
|
||||||
|
public SweepGenerator(IContainer container) {
|
||||||
|
_container = container;
|
||||||
|
_timer = new Timer();
|
||||||
|
_timer.Elapsed += Elapsed;
|
||||||
|
Logger = NullLogger.Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
|
public TimeSpan Interval {
|
||||||
|
get { return TimeSpan.FromMilliseconds(_timer.Interval); }
|
||||||
|
set { _timer.Interval = value.Milliseconds; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Activated() {
|
||||||
|
lock (_timer) {
|
||||||
|
_timer.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Terminating() {
|
||||||
|
lock (_timer) {
|
||||||
|
_timer.Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Elapsed(object sender, ElapsedEventArgs e) {
|
||||||
|
// current implementation disallows re-entrancy
|
||||||
|
if (!System.Threading.Monitor.TryEnter(_timer))
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (_timer.Enabled) {
|
||||||
|
DoWork();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
Logger.Warning(ex, "Problem in background tasks");
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
System.Threading.Monitor.Exit(_timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DoWork() {
|
||||||
|
// makes an inner container, similar to the per-request container
|
||||||
|
|
||||||
|
var containerProvider = new ContainerProvider(_container);
|
||||||
|
try {
|
||||||
|
var requestContainer = containerProvider.RequestContainer;
|
||||||
|
|
||||||
|
// also inject this instance in case anyone asks for the container provider
|
||||||
|
requestContainer.Build(builder => builder.Register(containerProvider).As<IContainerProvider>());
|
||||||
|
|
||||||
|
// resolve the manager and invoke it
|
||||||
|
var manager = requestContainer.Resolve<IBackgroundService>();
|
||||||
|
manager.Sweep();
|
||||||
|
}
|
||||||
|
finally{
|
||||||
|
// shut everything down again
|
||||||
|
containerProvider.DisposeRequestContainer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ContainerProvider : IContainerProvider {
|
||||||
|
public ContainerProvider(IContainer applicationContainer) {
|
||||||
|
// explicitly create a request container for the life of this object
|
||||||
|
ApplicationContainer = applicationContainer;
|
||||||
|
RequestContainer = applicationContainer.CreateInnerContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DisposeRequestContainer() {
|
||||||
|
var disposeContainer = RequestContainer;
|
||||||
|
RequestContainer = null;
|
||||||
|
|
||||||
|
if (disposeContainer != null)
|
||||||
|
disposeContainer.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IContainer ApplicationContainer { get; private set; }
|
||||||
|
|
||||||
|
public IContainer RequestContainer { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user