Skip to content

Commit

Permalink
Add As/Put method to ISite to allow caching (#14372)
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeAlhayek authored Nov 24, 2023
1 parent aa1e1bd commit 3f0242f
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Microsoft.Extensions.Options;
using OrchardCore.Entities;
using OrchardCore.Settings;

namespace OrchardCore.Media.Processing
Expand Down
23 changes: 23 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.Settings/SiteSettings.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
using System.Collections.Concurrent;
using Microsoft.AspNetCore.Routing;
using OrchardCore.Documents;
using OrchardCore.Entities;

namespace OrchardCore.Settings
{
// When updating class also update SiteSettingsDeploymentSource and SettingsStep.
public class SiteSettings : DocumentEntity, ISite
{
private readonly ConcurrentDictionary<string, object> _cache = new();

public string BaseUrl { get; set; }
public string Calendar { get; set; }
public int MaxPagedCount { get; set; }
Expand All @@ -22,5 +26,24 @@ public class SiteSettings : DocumentEntity, ISite
public RouteValueDictionary HomeRoute { get; set; } = new RouteValueDictionary();
public bool AppendVersion { get; set; } = true;
public CacheMode CacheMode { get; set; }

public T As<T>() where T : new()
{
var name = typeof(T).Name;
if (!IsReadOnly)
{
return this.As<T>(name);
}

if (_cache.TryGetValue(name, out var obj) && obj is T value)
{
return value;
}

var settings = this.As<T>(name);
_cache[name] = settings;

return settings;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Newtonsoft.Json;

namespace OrchardCore.Data.Documents
{
public class Document : IDocument
Expand All @@ -6,5 +8,11 @@ public class Document : IDocument
/// The <see cref="IDocument.Identifier"/>.
/// </summary>
public string Identifier { get; set; }

/// <summary>
/// Whether the document is immutable or not.
/// </summary>
[JsonIgnore]
public bool IsReadOnly { get; set; } = true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,10 @@ public interface IDocument
/// The unique identifier of the document.
/// </summary>
string Identifier { get; set; }

/// <summary>
/// Whether the document was loaded for updating.
/// </summary>
bool IsReadOnly { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ namespace OrchardCore.Documents
/// </summary>
public class DocumentEntity : Document, IDocumentEntity
{
public JObject Properties { get; set; } = new JObject();
public JObject Properties { get; set; } = new();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ namespace OrchardCore.Entities
{
public class Entity : IEntity
{
public JObject Properties { get; set; } = new JObject();
public JObject Properties { get; set; } = new();
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,41 @@
using Microsoft.AspNetCore.Routing;
using OrchardCore.Entities;

namespace OrchardCore.Settings
namespace OrchardCore.Settings;

public interface ISite : IEntity
{
public interface ISite : IEntity
{
string SiteName { get; set; }
string PageTitleFormat { get; set; }
string SiteSalt { get; set; }
string SuperUser { get; set; }
string Calendar { get; set; }
string TimeZoneId { get; set; }
ResourceDebugMode ResourceDebugMode { get; set; }
bool UseCdn { get; set; }
string CdnBaseUrl { get; set; }
int PageSize { get; set; }
int MaxPageSize { get; set; }
int MaxPagedCount { get; set; }
string BaseUrl { get; set; }
RouteValueDictionary HomeRoute { get; set; }
bool AppendVersion { get; set; }
CacheMode CacheMode { get; set; }
}
string SiteName { get; set; }

string PageTitleFormat { get; set; }

string SiteSalt { get; set; }

string SuperUser { get; set; }

string Calendar { get; set; }

string TimeZoneId { get; set; }

ResourceDebugMode ResourceDebugMode { get; set; }

bool UseCdn { get; set; }

string CdnBaseUrl { get; set; }

int PageSize { get; set; }

int MaxPageSize { get; set; }

int MaxPagedCount { get; set; }

string BaseUrl { get; set; }

RouteValueDictionary HomeRoute { get; set; }

bool AppendVersion { get; set; }

CacheMode CacheMode { get; set; }

T As<T>() where T : new();
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public async Task<TDocument> GetOrCreateMutableAsync(Func<Task<TDocument>> facto
}

document.Identifier = IdGenerator.GenerateId();
document.IsReadOnly = false;

return document;
}
Expand Down Expand Up @@ -306,6 +307,8 @@ private async Task<TDocument> GetInternalAsync(bool failover = false)

protected async Task SetInternalAsync(TDocument document, bool failover = false)
{
document.IsReadOnly = true;

if (!failover)
{
await UpdateDistributedCacheAsync(document);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using OrchardCore.Media;
using OrchardCore.Media.Processing;
using OrchardCore.Settings;
using OrchardCore.Tests.Utilities;
using SixLabors.ImageSharp.Web.Processors;

namespace OrchardCore.Tests.Modules.OrchardCore.Media
Expand Down Expand Up @@ -71,15 +72,13 @@ private IServiceProvider CreateServiceProvider()
{
var services = new ServiceCollection();

var mockSiteService = Mock.Of<ISiteService>(ss =>
ss.GetSiteSettingsAsync() == Task.FromResult(
Mock.Of<ISite>(s => s.Properties == JObject.FromObject(new { MediaTokenSettings = _mediaTokenSettings }))
)
);
var mockSite = SiteMockHelper.GetSite(_mediaTokenSettings);

var mockSiteService = Mock.Of<ISiteService>(ss => ss.GetSiteSettingsAsync() == Task.FromResult(mockSite.Object));

services.AddMemoryCache();

services.AddSingleton<ISiteService>(mockSiteService);
services.AddSingleton(mockSiteService);
services.AddSingleton<IImageWebProcessor, TokenCommandProcessor>();
services.AddSingleton<IImageWebProcessor, TokenCommandProcessor>();
services.AddSingleton<IImageWebProcessor, ResizeWebProcessor>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using OrchardCore.DisplayManagement.Notify;
using OrchardCore.Email;
using OrchardCore.Settings;
using OrchardCore.Tests.Utilities;
using OrchardCore.Users;
using OrchardCore.Users.Controllers;
using OrchardCore.Users.Events;
Expand Down Expand Up @@ -133,15 +134,12 @@ private static RegistrationController SetupRegistrationController(RegistrationSe
.Returns<string>(e =>
{
var user = users.SingleOrDefault(u => (u as User).Email == e);
return Task.FromResult(user);
});

var mockSiteService = Mock.Of<ISiteService>(ss =>
ss.GetSiteSettingsAsync() == Task.FromResult(
Mock.Of<ISite>(s => s.Properties == JObject.FromObject(new { RegistrationSettings = registrationSettings }))
)
);
var mockSite = SiteMockHelper.GetSite(registrationSettings);

var mockSiteService = Mock.Of<ISiteService>(ss => ss.GetSiteSettingsAsync() == Task.FromResult(mockSite.Object));
var mockSmtpService = Mock.Of<ISmtpService>(x => x.SendAsync(It.IsAny<MailMessage>()) == Task.FromResult(SmtpResult.Success));
var mockStringLocalizer = new Mock<IStringLocalizer<RegistrationController>>();
mockStringLocalizer.Setup(l => l[It.IsAny<string>()])
Expand Down
23 changes: 23 additions & 0 deletions test/OrchardCore.Tests/Utilities/SiteMockHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using OrchardCore.Settings;

namespace OrchardCore.Tests.Utilities;

public class SiteMockHelper
{
public static Mock<ISite> GetSite<T>(T obj) where T : new()
{
var properties = new JObject
{
[obj.GetType().Name] = JObject.FromObject(obj)
};

var mockSite = new Mock<ISite>();
mockSite.Setup(x => x.Properties)
.Returns(properties);

mockSite.Setup(x => x.As<T>())
.Returns(obj);

return mockSite;
}
}

0 comments on commit 3f0242f

Please sign in to comment.