Skip to content

Commit e1138fb

Browse files
committed
Fixed issue with db bootstrapping and added a sample project.
1 parent 9f41d89 commit e1138fb

22 files changed

+433
-12
lines changed

src/Cofoundry.Plugins.BackgroundTasks.Hangfire.sln

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 15
44
VisualStudioVersion = 15.0.26430.13
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cofoundry.Plugins.BackgroundTasks.Hangfire", "Cofoundry.Plugins.BackgroundTasks.Hangfire\Cofoundry.Plugins.BackgroundTasks.Hangfire.csproj", "{962BB845-1E06-4775-9C29-32E11B257603}"
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cofoundry.Plugins.BackgroundTasks.Hangfire", "Cofoundry.Plugins.BackgroundTasks.Hangfire\Cofoundry.Plugins.BackgroundTasks.Hangfire.csproj", "{962BB845-1E06-4775-9C29-32E11B257603}"
7+
EndProject
8+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{D4929788-4924-4E4A-927B-1E914C835AF1}"
9+
EndProject
10+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HangfireSample", "HangfireSample\HangfireSample.csproj", "{0661510F-9EB5-4688-9934-DA72F90791A6}"
711
EndProject
812
Global
913
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -15,8 +19,18 @@ Global
1519
{962BB845-1E06-4775-9C29-32E11B257603}.Debug|Any CPU.Build.0 = Debug|Any CPU
1620
{962BB845-1E06-4775-9C29-32E11B257603}.Release|Any CPU.ActiveCfg = Release|Any CPU
1721
{962BB845-1E06-4775-9C29-32E11B257603}.Release|Any CPU.Build.0 = Release|Any CPU
22+
{0661510F-9EB5-4688-9934-DA72F90791A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23+
{0661510F-9EB5-4688-9934-DA72F90791A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
24+
{0661510F-9EB5-4688-9934-DA72F90791A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
25+
{0661510F-9EB5-4688-9934-DA72F90791A6}.Release|Any CPU.Build.0 = Release|Any CPU
1826
EndGlobalSection
1927
GlobalSection(SolutionProperties) = preSolution
2028
HideSolutionNode = FALSE
2129
EndGlobalSection
30+
GlobalSection(NestedProjects) = preSolution
31+
{0661510F-9EB5-4688-9934-DA72F90791A6} = {D4929788-4924-4E4A-927B-1E914C835AF1}
32+
EndGlobalSection
33+
GlobalSection(ExtensibilityGlobals) = postSolution
34+
SolutionGuid = {F641408F-3FD6-4BA4-A1F2-2369F8D81358}
35+
EndGlobalSection
2236
EndGlobal
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using Microsoft.AspNetCore.Http;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using Microsoft.Extensions.DependencyInjection;
7+
8+
namespace Cofoundry.Plugins.BackgroundTasks.Hangfire
9+
{
10+
public class HangfireInitializationMiddleware
11+
{
12+
private static bool isInitialized = false;
13+
private static object _isInitializedLock = new object();
14+
private readonly RequestDelegate _next;
15+
16+
public HangfireInitializationMiddleware(
17+
RequestDelegate next
18+
)
19+
{
20+
_next = next;
21+
}
22+
23+
public async Task Invoke(HttpContext cx)
24+
{
25+
bool runInitialize = false;
26+
27+
if (!isInitialized)
28+
{
29+
lock (_isInitializedLock)
30+
{
31+
if (!isInitialized)
32+
{
33+
isInitialized = true;
34+
runInitialize = true;
35+
}
36+
}
37+
38+
if (runInitialize)
39+
{
40+
try
41+
{
42+
var initializer = cx.RequestServices.GetService<IHangfireBackgroundTaskInitializer>();
43+
initializer.Initialize();
44+
}
45+
catch (Exception ex)
46+
{
47+
isInitialized = false;
48+
throw;
49+
}
50+
}
51+
}
52+
53+
await _next.Invoke(cx);
54+
}
55+
}
56+
}

src/Cofoundry.Plugins.BackgroundTasks.Hangfire/Startup/HangfireStartupConfigurationTask.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ namespace Cofoundry.Plugins.BackgroundTasks.Hangfire
1313
/// To customize the startup process you can override IHangfireBackgroundTaskInitializer
1414
/// and IHangfireServerInitializer implementations, or just create your own plugin.
1515
/// </remarks>
16-
public class HangfireStartupConfigurationTask : IRunBeforeStartupConfigurationTask
16+
public class HangfireStartupConfigurationTask
17+
: IRunBeforeStartupConfigurationTask
18+
, IRunAfterStartupConfigurationTask
1719
{
1820
private readonly IHangfireBackgroundTaskInitializer _hangfireBackgroundTaskInitializer;
1921
private readonly IHangfireServerInitializer _hangfireServerInitializer;
@@ -27,17 +29,16 @@ IHangfireServerInitializer hangfireServerInitializer
2729
_hangfireServerInitializer = hangfireServerInitializer;
2830
}
2931

30-
public int Ordering
31-
{
32-
get { return (int)StartupTaskOrdering.Normal; }
33-
}
32+
public int Ordering { get; } = (int)StartupTaskOrdering.Normal;
3433

3534
public ICollection<Type> RunBefore { get; } = new Type[] { typeof(MvcStartupConfigurationTask) };
3635

36+
public ICollection<Type> RunAfter { get; } = new Type[] { typeof(AutoUpdateMiddlewareStartupConfigurationTask) };
37+
3738
public void Configure(IApplicationBuilder app)
3839
{
3940
_hangfireServerInitializer.Initialize(app);
40-
_hangfireBackgroundTaskInitializer.Initialize();
41+
app.UseMiddleware<HangfireInitializationMiddleware>();
4142
}
4243
}
4344
}

src/Cofoundry.Plugins.BackgroundTasks.Hangfire/Startup/HangfireStartupServiceConfigurationTask.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public void ConfigureServices(IMvcBuilder mvcBuilder)
4040
.AddHangfire(configuration => configuration
4141
.UseSqlServerStorage(connectionString, new SqlServerStorageOptions()
4242
{
43-
PrepareSchemaIfNecessary = isDbLocked
43+
PrepareSchemaIfNecessary = !isDbLocked
4444
})
4545
.UseFilter(new AutomaticRetryAttribute { Attempts = 0 })
4646
);

src/Cofoundry.Plugins.BackgroundTasks.Hangfire/Startup/IHangfireBackgroundTaskInitializer.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ namespace Cofoundry.Plugins.BackgroundTasks.Hangfire
1212
/// </summary>
1313
public interface IHangfireBackgroundTaskInitializer
1414
{
15-
#region public methods
16-
1715
void Initialize();
18-
19-
#endregion
2016
}
2117
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Cofoundry.Core.BackgroundTasks;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
7+
namespace HangfireSample.Cofoundry.BackgroundTasks
8+
{
9+
public class BackgroundTaskRegistration : IBackgroundTaskRegistration
10+
{
11+
public void Register(IBackgroundTaskScheduler scheduler)
12+
{
13+
scheduler.RegisterAsyncRecurringTask<ProductAddingBackgroundTask>(1);
14+
}
15+
}
16+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using Cofoundry.Core.BackgroundTasks;
2+
using Cofoundry.Domain;
3+
using Cofoundry.Domain.CQS;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using System.Threading.Tasks;
8+
9+
namespace HangfireSample.Cofoundry.BackgroundTasks
10+
{
11+
public class ProductAddingBackgroundTask : IAsyncRecurringBackgroundTask
12+
{
13+
private readonly ICommandExecutor _commandExecutor;
14+
private readonly IExecutionContextFactory _executionContextFactory;
15+
16+
public ProductAddingBackgroundTask(
17+
ICommandExecutor commandExecutor,
18+
IExecutionContextFactory executionContextFactory
19+
)
20+
{
21+
_commandExecutor = commandExecutor;
22+
_executionContextFactory = executionContextFactory;
23+
}
24+
25+
public async Task ExecuteAsync()
26+
{
27+
var title = Guid.NewGuid();
28+
var command = new AddCustomEntityCommand()
29+
{
30+
CustomEntityDefinitionCode = ProductCustomEntityDefinition.DefinitionCode,
31+
Title = title.ToString(),
32+
Model = new ProductDataModel() { Description = "Description of " + title },
33+
Publish = true
34+
};
35+
36+
var elevatedExecutionContext = await _executionContextFactory.CreateSystemUserExecutionContextAsync();
37+
38+
await _commandExecutor.ExecuteAsync(command, elevatedExecutionContext);
39+
}
40+
}
41+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Cofoundry.Domain;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
7+
namespace HangfireSample
8+
{
9+
public class ProductCustomEntityDefinition : ICustomEntityDefinition<ProductDataModel>
10+
{
11+
public const string DefinitionCode = "SPLPRD";
12+
13+
public string CustomEntityDefinitionCode => DefinitionCode;
14+
15+
public string Name => "Product";
16+
17+
public string NamePlural => "Products";
18+
19+
public string Description => "Example description";
20+
21+
public bool ForceUrlSlugUniqueness => false;
22+
23+
public bool HasLocale => false;
24+
25+
public bool AutoGenerateUrlSlug => true;
26+
27+
public bool AutoPublish => true;
28+
}
29+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Cofoundry.Domain;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.ComponentModel.DataAnnotations;
5+
using System.Linq;
6+
using System.Threading.Tasks;
7+
8+
namespace HangfireSample
9+
{
10+
public class ProductDataModel : ICustomEntityDataModel
11+
{
12+
[Required]
13+
public string Description { get; set; }
14+
}
15+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using Cofoundry.Domain;
2+
using Cofoundry.Domain.CQS;
3+
using Microsoft.AspNetCore.Mvc;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using System.Threading.Tasks;
8+
9+
namespace HangfireSample.Controllers
10+
{
11+
public class HomeController : Controller
12+
{
13+
private readonly IQueryExecutor _queryExecutor;
14+
15+
public HomeController(
16+
IQueryExecutor queryExecutor
17+
)
18+
{
19+
_queryExecutor = queryExecutor;
20+
}
21+
22+
[Route("")]
23+
public async Task<IActionResult> Index()
24+
{
25+
var query = new SearchCustomEntityRenderSummariesQuery()
26+
{
27+
CustomEntityDefinitionCode = ProductCustomEntityDefinition.DefinitionCode,
28+
PageSize = 10
29+
};
30+
31+
var result = await _queryExecutor.ExecuteAsync(query);
32+
return View(result);
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)