diff --git a/.editorconfig b/.editorconfig index 6d658b72d..4236cc56a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -248,6 +248,9 @@ dotnet_diagnostic.CA2246.severity = warning # CA2249: Use string.Contains instead of string.IndexOf to improve readability. dotnet_diagnostic.CA2249.severity = warning +# CS1591: Missing XML comment for publicly visible type or member +dotnet_diagnostic.CS1591.severity = suggestion + # IDE0005: Remove unnecessary usings dotnet_diagnostic.IDE0005.severity = warning @@ -298,6 +301,9 @@ dotnet_diagnostic.IDE0060.severity = warning # IDE0062: Make local function static dotnet_diagnostic.IDE0062.severity = warning +# IDE0130: Namespace does not match folder structure +dotnet_diagnostic.IDE0130.severity = none + # IDE0161: Convert to file-scoped namespace dotnet_diagnostic.IDE0161.severity = warning diff --git a/Cofoundry.sln b/Cofoundry.sln index 9b9a297bb..a5f3808ed 100644 --- a/Cofoundry.sln +++ b/Cofoundry.sln @@ -6,6 +6,7 @@ MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4996A61A-00E1-4363-9BC7-1F877E4AD933}" ProjectSection(SolutionItems) = preProject src\Directory.Build.props = src\Directory.Build.props + README.md = README.md EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{8FCDFF68-9BCF-499B-8E2D-7E08E824F40A}" diff --git a/docs/user-docs/Framework/Background Tasks.md b/docs/user-docs/Framework/Background Tasks.md index 552edef96..e632d3a9a 100644 --- a/docs/user-docs/Framework/Background Tasks.md +++ b/docs/user-docs/Framework/Background Tasks.md @@ -13,9 +13,7 @@ public class ImportDataBackgroundTask : IAsyncRecurringBackgroundTask { private readonly IDomainRepository _domainRepository; - public ImportDataBackgroundTask( - IDomainRepository domainRepository - ) + public ImportDataBackgroundTask(IDomainRepository domainRepository) { _domainRepository = domainRepository; } @@ -37,8 +35,7 @@ public class BackgroundTaskRegistration : IBackgroundTaskRegistration { public void Register(IBackgroundTaskScheduler scheduler) { - scheduler - .RegisterRecurringTask(1, 6, 5); + scheduler.RegisterRecurringTask(1, 6, 5); } } ``` diff --git a/docs/user-docs/Framework/Caching.md b/docs/user-docs/Framework/Caching.md index aa078c1e0..c5ed70e8b 100644 --- a/docs/user-docs/Framework/Caching.md +++ b/docs/user-docs/Framework/Caching.md @@ -50,9 +50,7 @@ public class ImageAssetCache private const string IMAGE_ASSET_RENDER_DETAILS_CACHEKEY = "ImageAssetRenderDetails:"; private readonly IObjectCache _cache; - public ImageAssetCache( - IObjectCacheFactory cacheFactory - ) + public ImageAssetCache(IObjectCacheFactory cacheFactory) { _cache = cacheFactory.Get("COF_ImageAssets"); } diff --git a/docs/user-docs/Framework/Configuration Settings.md b/docs/user-docs/Framework/Configuration Settings.md index 935c74ce7..aa9a13ecb 100644 --- a/docs/user-docs/Framework/Configuration Settings.md +++ b/docs/user-docs/Framework/Configuration Settings.md @@ -47,9 +47,7 @@ public class ContactController : Controller { private readonly ContactFormSettings _simpleTestSiteSettings; - public ContactController( - ContactFormSettings simpleTestSiteSettings - ) + public ContactController(ContactFormSettings simpleTestSiteSettings) { _simpleTestSiteSettings = simpleTestSiteSettings; } diff --git a/docs/user-docs/Framework/Data Access/Entity Framework & DbContext Tools.md b/docs/user-docs/Framework/Data Access/Entity Framework & DbContext Tools.md index e0540ac06..cad009e68 100644 --- a/docs/user-docs/Framework/Data Access/Entity Framework & DbContext Tools.md +++ b/docs/user-docs/Framework/Data Access/Entity Framework & DbContext Tools.md @@ -113,8 +113,7 @@ public class SetCatFavoriteCommandHandler new SqlParameter("@CatId", command.CatId), new SqlParameter("@UserId", executionContext.UserContext.UserId), new SqlParameter("@IsLiked", command.IsFavorite), - new SqlParameter("@CreateDate", executionContext.ExecutionDate) - ); + new SqlParameter("@CreateDate", executionContext.ExecutionDate)); } } ``` diff --git a/docs/user-docs/Framework/Data Access/Transactions.md b/docs/user-docs/Framework/Data Access/Transactions.md index 74114f8c8..08a5fee41 100644 --- a/docs/user-docs/Framework/Data Access/Transactions.md +++ b/docs/user-docs/Framework/Data Access/Transactions.md @@ -15,8 +15,7 @@ public class AddProductHandler public AddProductHandler( MyDbContext myDbContext, ITransactionScopeManager transactionScopeManager, - ICommandExecutor commandExecutor - ) + ICommandExecutor commandExecutor) { _myDbContext = myDbContext; _transactionScopeManager = transactionScopeManager; @@ -57,9 +56,7 @@ public class TransactionExample { private readonly IAdvancedContentRepository _contentRepository; - public TransactionExample( - IAdvancedContentRepository contentRepository - ) + public TransactionExample(IAdvancedContentRepository contentRepository) { _contentRepository = contentRepository; } @@ -166,9 +163,7 @@ public class TransactionExample { private readonly IAdvancedContentRepository _contentRepository; - public TransactionExample( - IAdvancedContentRepository contentRepository - ) + public TransactionExample(IAdvancedContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/docs/user-docs/Framework/Dependency Injection.md b/docs/user-docs/Framework/Dependency Injection.md index dc565caae..14535f0bd 100644 --- a/docs/user-docs/Framework/Dependency Injection.md +++ b/docs/user-docs/Framework/Dependency Injection.md @@ -91,8 +91,7 @@ public class MyAssemblyDiscoveryRule : IAssemblyDiscoveryRule { public bool CanInclude( RuntimeLibrary libraryToCheck, - IAssemblyDiscoveryRuleContext context - ) + IAssemblyDiscoveryRuleContext context) { return libraryToCheck.Name.StartsWith("MyNamespace."); } @@ -106,8 +105,8 @@ public class MyAssemblyDiscoveryRule : IAssemblyDiscoveryRule builder .Services .AddMvc() - .AddCofoundry(builder.Configuration, c => + .AddCofoundry(builder.Configuration, config => { - c.AssemblyDiscoveryRules.Add(new MyAssemblyDiscoveryRule()); + config.AssemblyDiscoveryRules.Add(new MyAssemblyDiscoveryRule()); }); ``` \ No newline at end of file diff --git a/docs/user-docs/Framework/JSON Configuration.md b/docs/user-docs/Framework/JSON Configuration.md index 3e7d1bdab..e42e7bb98 100644 --- a/docs/user-docs/Framework/JSON Configuration.md +++ b/docs/user-docs/Framework/JSON Configuration.md @@ -25,11 +25,11 @@ This can be done in your `Program.cs` file by re-applying the `AddNewtonsoftJson builder.Services .AddMvc() .AddCofoundry(builder.Configuration) - .AddNewtonsoftJson(o => + .AddNewtonsoftJson(options => { // e.g. reset the contract resolver to use PascalCase. - o.SerializerSettings.ContractResolver = new DefaultContractResolver(); - JsonConvert.DefaultSettings = () => o.SerializerSettings; + options.SerializerSettings.ContractResolver = new DefaultContractResolver(); + JsonConvert.DefaultSettings = () => options.SerializerSettings; }); ``` diff --git a/docs/user-docs/Framework/Message Aggregator.md b/docs/user-docs/Framework/Message Aggregator.md index 85af4b211..2d718eac0 100644 --- a/docs/user-docs/Framework/Message Aggregator.md +++ b/docs/user-docs/Framework/Message Aggregator.md @@ -17,9 +17,7 @@ public class BlogPostDeletedMessageHandler : IMessageHandler GetEmbeddedResourcePaths() { - var path = new EmbeddedResourcePath( - GetType().Assembly, - "/MyAssemblyStaticFiles" - ); + var path = new EmbeddedResourcePath(GetType().Assembly, "/MyAssemblyStaticFiles"); yield return path; } diff --git a/docs/user-docs/Framework/Website Startup.md b/docs/user-docs/Framework/Website Startup.md index 87f66ff12..f4341165f 100644 --- a/docs/user-docs/Framework/Website Startup.md +++ b/docs/user-docs/Framework/Website Startup.md @@ -70,11 +70,11 @@ As a last resort we also provide a configuration option that lets you filter the ```csharp // ..other app builder code ommited -app.UseCofoundry(c => +app.UseCofoundry(config => { - c.StartupTaskFilter = startupTasks => + config.StartupTaskFilter = startupTasks => { - return startupTasks.Where(t => t is not JsonConverterStartupConfigurationTask); + return startupTasks.Where(task => task is not JsonConverterStartupConfigurationTask); }; }); ``` @@ -111,8 +111,8 @@ public class ExampleAssemblyDiscoveryRule : IAssemblyDiscoveryRule builder.Services .AddMvc() - .AddCofoundry(builder.Configuration, c => + .AddCofoundry(builder.Configuration, config => { - c.AssemblyDiscoveryRules.Add(new ExampleAssemblyDiscoveryRule()); + config.AssemblyDiscoveryRules.Add(new ExampleAssemblyDiscoveryRule()); }); ``` diff --git a/docs/user-docs/Getting Started/Installing.md b/docs/user-docs/Getting Started/Installing.md index 5c55e1747..1a7bb3537 100644 --- a/docs/user-docs/Getting Started/Installing.md +++ b/docs/user-docs/Getting Started/Installing.md @@ -1,6 +1,6 @@ ## Requirements -- .NET 8 +- .NET 10 - SqlServer (Express) 2019 or later, or Azure SQL ## Creating a new project using the .NET CLI @@ -33,13 +33,13 @@ This is just an example of how you'd typically create a new site, but you can qu ### Creating the site -1. Open Visual Studio 2022 and select **Create a new project** +1. Open Visual Studio 2026 and select **Create a new project** 2. Select the "ASP.NET Core Web App (Model-View-Controller)" template and press **Next** 3. Fill in the project name, select a location and press **Next** -4. Ensure ".NET 8.0 (Long-term support)" is selected as the framework and "None" is selected as the authentication type, then press *Create* +4. Ensure ".NET 10.0 (Long-term support)" is selected as the framework and "None" is selected as the authentication type, then press *Create* 5. Create an empty database in SQL Server. @@ -89,11 +89,11 @@ app.Run(); - net8.0 + net10.0 enable enable - false - false + false + false diff --git a/docs/user-docs/Getting Started/Overview.md b/docs/user-docs/Getting Started/Overview.md index 087f662d4..bb16840b7 100644 --- a/docs/user-docs/Getting Started/Overview.md +++ b/docs/user-docs/Getting Started/Overview.md @@ -1,4 +1,4 @@ -Cofoundry is an open source .NET application framework and content management platform. Whilst content management and website tools are a large part of Cofoundry, the functionality is entirely optional and our base framework is available to you to use in any application that references .NET 6. +Cofoundry is an open source .NET application framework and content management platform. Whilst content management and website tools are a large part of Cofoundry, the functionality is entirely optional and our base framework is available to you to use in any .NET 10 application. We see the role of developing an application as very separate from managing content and so we don't squeeze everything into the same management GUI, instead we focus on modular and extensible code-first tools for building sites and a simple, clean interface for managing them. diff --git a/docs/user-docs/Getting Started/Publishing & Deployment.md b/docs/user-docs/Getting Started/Publishing & Deployment.md index 026f9729c..fde52e242 100644 --- a/docs/user-docs/Getting Started/Publishing & Deployment.md +++ b/docs/user-docs/Getting Started/Publishing & Deployment.md @@ -15,11 +15,11 @@ To work around this issue you'll need to add two settings to your .csproj projec - net8.0 + net10.0 enable enable - false - false + false + false diff --git a/docs/user-docs/User Areas/Configuration/Password Policies.md b/docs/user-docs/User Areas/Configuration/Password Policies.md index 0f4a76f49..40057b799 100644 --- a/docs/user-docs/User Areas/Configuration/Password Policies.md +++ b/docs/user-docs/User Areas/Configuration/Password Policies.md @@ -89,8 +89,7 @@ public class AdminPasswordPolicyConfiguration : IPasswordPolicyConfiguration - net8.0 + net10.0 enable enable false diff --git a/eng/Cofoundry.Build/Cofoundry.Build.csproj b/eng/Cofoundry.Build/Cofoundry.Build.csproj index 3bce73f4f..8fd110d88 100644 --- a/eng/Cofoundry.Build/Cofoundry.Build.csproj +++ b/eng/Cofoundry.Build/Cofoundry.Build.csproj @@ -4,7 +4,7 @@ - + diff --git a/eng/Cofoundry.DocGenerator/Cofoundry.DocGenerator.csproj b/eng/Cofoundry.DocGenerator/Cofoundry.DocGenerator.csproj index 2b4151e8c..e531964b9 100644 --- a/eng/Cofoundry.DocGenerator/Cofoundry.DocGenerator.csproj +++ b/eng/Cofoundry.DocGenerator/Cofoundry.DocGenerator.csproj @@ -5,8 +5,8 @@ - - + + diff --git a/eng/Cofoundry.SamplesGenerator/Cofoundry.SamplesGenerator.csproj b/eng/Cofoundry.SamplesGenerator/Cofoundry.SamplesGenerator.csproj index 0b8346438..cf1ec4319 100644 --- a/eng/Cofoundry.SamplesGenerator/Cofoundry.SamplesGenerator.csproj +++ b/eng/Cofoundry.SamplesGenerator/Cofoundry.SamplesGenerator.csproj @@ -5,7 +5,7 @@ - + diff --git a/samples/src/Dev/Dev.Sandbox/Cofoundry/CustomEntities/BlogPosts/BlogPostDisplayModelMapper.cs b/samples/src/Dev/Dev.Sandbox/Cofoundry/CustomEntities/BlogPosts/BlogPostDisplayModelMapper.cs index 350f7f2df..e2e262d57 100644 --- a/samples/src/Dev/Dev.Sandbox/Cofoundry/CustomEntities/BlogPosts/BlogPostDisplayModelMapper.cs +++ b/samples/src/Dev/Dev.Sandbox/Cofoundry/CustomEntities/BlogPosts/BlogPostDisplayModelMapper.cs @@ -11,9 +11,7 @@ public class BlogPostDisplayModelMapper { private readonly IContentRepository _contentRepository; - public BlogPostDisplayModelMapper( - IContentRepository contentRepository - ) + public BlogPostDisplayModelMapper(IContentRepository contentRepository) { _contentRepository = contentRepository; } @@ -37,8 +35,7 @@ IContentRepository contentRepository public async Task MapDisplayModelAsync( CustomEntityRenderDetails renderDetails, BlogPostDataModel dataModel, - PublishStatusQuery publishStatusQuery - ) + PublishStatusQuery publishStatusQuery) { var categories = await MapCategories(dataModel, publishStatusQuery); var author = await MapAuthor(dataModel, publishStatusQuery); @@ -59,8 +56,7 @@ PublishStatusQuery publishStatusQuery private async Task> MapCategories( BlogPostDataModel dataModel, - PublishStatusQuery publishStatusQuery - ) + PublishStatusQuery publishStatusQuery) { if (EnumerableHelper.IsNullOrEmpty(dataModel.CategoryIds)) { @@ -100,8 +96,7 @@ private CategorySummary MapCategory(CustomEntityRenderSummary renderSummary) private async Task MapAuthor( BlogPostDataModel dataModel, - PublishStatusQuery publishStatusQuery - ) + PublishStatusQuery publishStatusQuery) { if (dataModel.AuthorId < 1) { diff --git a/samples/src/Dev/Dev.Sandbox/Cofoundry/NewBaseModels/ExampleDependencyRegistration.cs b/samples/src/Dev/Dev.Sandbox/Cofoundry/NewBaseModels/ExampleDependencyRegistration.cs index 685ebd9e9..609d20d89 100644 --- a/samples/src/Dev/Dev.Sandbox/Cofoundry/NewBaseModels/ExampleDependencyRegistration.cs +++ b/samples/src/Dev/Dev.Sandbox/Cofoundry/NewBaseModels/ExampleDependencyRegistration.cs @@ -10,7 +10,6 @@ public void Register(IContainerRegister container) container .Register(overrideOptions) - .Register(overrideOptions) - ; + .Register(overrideOptions); } } diff --git a/samples/src/Dev/Dev.Sandbox/Cofoundry/NewBaseModels/ExamplePageViewModelBuilder.cs b/samples/src/Dev/Dev.Sandbox/Cofoundry/NewBaseModels/ExamplePageViewModelBuilder.cs index a77af3fef..38dfc48a9 100644 --- a/samples/src/Dev/Dev.Sandbox/Cofoundry/NewBaseModels/ExamplePageViewModelBuilder.cs +++ b/samples/src/Dev/Dev.Sandbox/Cofoundry/NewBaseModels/ExamplePageViewModelBuilder.cs @@ -7,8 +7,7 @@ public class ExamplePageViewModelBuilder : IPageViewModelBuilder public ExamplePageViewModelBuilder( IPageViewModelFactory pageViewModelFactory, - IPageViewModelMapper pageViewModelMapper - ) + IPageViewModelMapper pageViewModelMapper) { // Constructor injection is supported // Here we make use of the same helpers used in the base class diff --git a/samples/src/Dev/Dev.Sandbox/Cofoundry/PageBlockTypes/ContentSection/ContentSectionDataModel.cs b/samples/src/Dev/Dev.Sandbox/Cofoundry/PageBlockTypes/ContentSection/ContentSectionDataModel.cs index c41c1c6cc..59cd08e4b 100644 --- a/samples/src/Dev/Dev.Sandbox/Cofoundry/PageBlockTypes/ContentSection/ContentSectionDataModel.cs +++ b/samples/src/Dev/Dev.Sandbox/Cofoundry/PageBlockTypes/ContentSection/ContentSectionDataModel.cs @@ -27,5 +27,5 @@ public class ContentSectionDataModel : IPageBlockTypeDataModel CategoryCustomEntityDefinition.DefinitionCode, BlogPostCustomEntityDefinition.DefinitionCode, IsOrderable = true)] - public IReadOnlyCollection Entities { get; set; } = Array.Empty(); + public IReadOnlyCollection Entities { get; set; } = []; } diff --git a/samples/src/Dev/Dev.Sandbox/Cofoundry/PageBlockTypes/ContentSection/ContentSectionDisplayModelMapper.cs b/samples/src/Dev/Dev.Sandbox/Cofoundry/PageBlockTypes/ContentSection/ContentSectionDisplayModelMapper.cs index 9cd7763ae..bf340ff82 100644 --- a/samples/src/Dev/Dev.Sandbox/Cofoundry/PageBlockTypes/ContentSection/ContentSectionDisplayModelMapper.cs +++ b/samples/src/Dev/Dev.Sandbox/Cofoundry/PageBlockTypes/ContentSection/ContentSectionDisplayModelMapper.cs @@ -15,8 +15,7 @@ public class ContentSectionDisplayModelMapper : IPageBlockTypeDisplayModelMapper /// public Task MapAsync( PageBlockTypeDisplayModelMapperContext context, - PageBlockTypeDisplayModelMapperResult result - ) + PageBlockTypeDisplayModelMapperResult result) { foreach (var input in context.Items) { diff --git a/samples/src/Dev/Dev.Sandbox/Cofoundry/PageBlockTypes/ContentSplitSection/ContentSplitSectionDisplayModelMapper.cs b/samples/src/Dev/Dev.Sandbox/Cofoundry/PageBlockTypes/ContentSplitSection/ContentSplitSectionDisplayModelMapper.cs index a7dcbc361..4c7a781bd 100644 --- a/samples/src/Dev/Dev.Sandbox/Cofoundry/PageBlockTypes/ContentSplitSection/ContentSplitSectionDisplayModelMapper.cs +++ b/samples/src/Dev/Dev.Sandbox/Cofoundry/PageBlockTypes/ContentSplitSection/ContentSplitSectionDisplayModelMapper.cs @@ -6,17 +6,14 @@ public class ContentSplitSectionDisplayModelMapper : IPageBlockTypeDisplayModelM { private readonly IContentRepository _contentRepository; - public ContentSplitSectionDisplayModelMapper( - IContentRepository contentRepository - ) + public ContentSplitSectionDisplayModelMapper(IContentRepository contentRepository) { _contentRepository = contentRepository; } public async Task MapAsync( PageBlockTypeDisplayModelMapperContext context, - PageBlockTypeDisplayModelMapperResult result - ) + PageBlockTypeDisplayModelMapperResult result) { var imageAssetIds = context.Items.SelectDistinctModelValuesWithoutEmpty(i => i.ImageAssetId); var imageAssets = await _contentRepository diff --git a/samples/src/Dev/Dev.Sandbox/Cofoundry/PageBlockTypes/PageList/PageListDisplayModelMapper.cs b/samples/src/Dev/Dev.Sandbox/Cofoundry/PageBlockTypes/PageList/PageListDisplayModelMapper.cs index e921bfa28..1dcc390f3 100644 --- a/samples/src/Dev/Dev.Sandbox/Cofoundry/PageBlockTypes/PageList/PageListDisplayModelMapper.cs +++ b/samples/src/Dev/Dev.Sandbox/Cofoundry/PageBlockTypes/PageList/PageListDisplayModelMapper.cs @@ -16,9 +16,7 @@ public class PageListDisplayModelMapper : IPageBlockTypeDisplayModelMapper p.ExceptEntityPermissions()) .Include() .IncludeAllRead() - .ExcludeUserInAllUserAreas() - ; + .ExcludeUserInAllUserAreas(); } } diff --git a/samples/src/Dev/Dev.Sandbox/ViewComponents/BlogPostListViewComponent.cs b/samples/src/Dev/Dev.Sandbox/ViewComponents/BlogPostListViewComponent.cs index 19081edc4..d3ad9ddc2 100644 --- a/samples/src/Dev/Dev.Sandbox/ViewComponents/BlogPostListViewComponent.cs +++ b/samples/src/Dev/Dev.Sandbox/ViewComponents/BlogPostListViewComponent.cs @@ -9,8 +9,7 @@ public class BlogPostListViewComponent : ViewComponent public BlogPostListViewComponent( IContentRepository contentRepository, - IVisualEditorStateService visualEditorStateService - ) + IVisualEditorStateService visualEditorStateService) { _contentRepository = contentRepository; _visualEditorStateService = visualEditorStateService; diff --git a/samples/src/Dev/Dev.Sandbox/ViewComponents/ContactRequestFormViewComponent.cs b/samples/src/Dev/Dev.Sandbox/ViewComponents/ContactRequestFormViewComponent.cs index 0b9f5c3cf..97492a020 100644 --- a/samples/src/Dev/Dev.Sandbox/ViewComponents/ContactRequestFormViewComponent.cs +++ b/samples/src/Dev/Dev.Sandbox/ViewComponents/ContactRequestFormViewComponent.cs @@ -10,8 +10,7 @@ public class ContactRequestFormViewComponent : ViewComponent public ContactRequestFormViewComponent( IMailService mailService, - SandboxSiteSettings simpleTestSiteSettings - ) + SandboxSiteSettings simpleTestSiteSettings) { _mailService = mailService; _simpleTestSiteSettings = simpleTestSiteSettings; diff --git a/samples/src/Dev/Dev.Sandbox/ViewComponents/HomepageBlogPostsViewComponent.cs b/samples/src/Dev/Dev.Sandbox/ViewComponents/HomepageBlogPostsViewComponent.cs index 2926b4496..762f1b736 100644 --- a/samples/src/Dev/Dev.Sandbox/ViewComponents/HomepageBlogPostsViewComponent.cs +++ b/samples/src/Dev/Dev.Sandbox/ViewComponents/HomepageBlogPostsViewComponent.cs @@ -9,8 +9,7 @@ public class HomepageBlogPostsViewComponent : ViewComponent public HomepageBlogPostsViewComponent( IContentRepository contentRepository, - IVisualEditorStateService visualEditorStateService - ) + IVisualEditorStateService visualEditorStateService) { _contentRepository = contentRepository; _visualEditorStateService = visualEditorStateService; @@ -52,8 +51,7 @@ public async Task InvokeAsync() /// private async Task> MapBlogPostsAsync( PagedQueryResult customEntityResult, - PublishStatusQuery ambientEntityPublishStatusQuery - ) + PublishStatusQuery ambientEntityPublishStatusQuery) { var blogPosts = new List(customEntityResult.Items.Count); diff --git a/samples/src/Dev/Dev.Sandbox/ViewComponents/SidebarCategoriesViewComponent.cs b/samples/src/Dev/Dev.Sandbox/ViewComponents/SidebarCategoriesViewComponent.cs index 3d4392c98..28fb06116 100644 --- a/samples/src/Dev/Dev.Sandbox/ViewComponents/SidebarCategoriesViewComponent.cs +++ b/samples/src/Dev/Dev.Sandbox/ViewComponents/SidebarCategoriesViewComponent.cs @@ -6,9 +6,7 @@ public class SidebarCategoriesViewComponent : ViewComponent { private readonly IContentRepository _contentRepository; - public SidebarCategoriesViewComponent( - IContentRepository contentRepository - ) + public SidebarCategoriesViewComponent(IContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/Mail/MailSample/Cofoundry/MailTemplates/Admin/AdminMailTemplateBuilder.cs b/samples/src/Mail/MailSample/Cofoundry/MailTemplates/Admin/AdminMailTemplateBuilder.cs index 6dfa43bc7..184fc0a1b 100644 --- a/samples/src/Mail/MailSample/Cofoundry/MailTemplates/Admin/AdminMailTemplateBuilder.cs +++ b/samples/src/Mail/MailSample/Cofoundry/MailTemplates/Admin/AdminMailTemplateBuilder.cs @@ -18,9 +18,7 @@ public class AdminMailTemplateBuilder : IUserMailTemplateBuilder - net8.0 + net10.0 enable enable false diff --git a/samples/src/Menus/MenuSample/MenuSample.csproj b/samples/src/Menus/MenuSample/MenuSample.csproj index a8fc63f5d..7ad2d561f 100644 --- a/samples/src/Menus/MenuSample/MenuSample.csproj +++ b/samples/src/Menus/MenuSample/MenuSample.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable enable false diff --git a/samples/src/Menus/MenuSample/TagHelpers/ActiveLinkTagHelper.cs b/samples/src/Menus/MenuSample/TagHelpers/ActiveLinkTagHelper.cs index 953bb9819..688caed41 100644 --- a/samples/src/Menus/MenuSample/TagHelpers/ActiveLinkTagHelper.cs +++ b/samples/src/Menus/MenuSample/TagHelpers/ActiveLinkTagHelper.cs @@ -60,7 +60,7 @@ public override void Process(TagHelperContext context, TagHelperOutput output) base.Process(context, output); } - private string? ParseHref(TagHelperOutput output) + private static string? ParseHref(TagHelperOutput output) { var href = output .Attributes diff --git a/samples/src/Menus/MenuSample/ViewComponents/MultiLevelMenu/MultiLevelMenuViewComponent.cs b/samples/src/Menus/MenuSample/ViewComponents/MultiLevelMenu/MultiLevelMenuViewComponent.cs index afb8f076b..baf9d495a 100644 --- a/samples/src/Menus/MenuSample/ViewComponents/MultiLevelMenu/MultiLevelMenuViewComponent.cs +++ b/samples/src/Menus/MenuSample/ViewComponents/MultiLevelMenu/MultiLevelMenuViewComponent.cs @@ -11,9 +11,7 @@ public class MultiLevelMenuViewComponent : ViewComponent { private readonly IContentRepository _contentRepository; - public MultiLevelMenuViewComponent( - IContentRepository contentRepository - ) + public MultiLevelMenuViewComponent(IContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/Menus/MenuSample/ViewComponents/NestedMenu/NestedMenuViewComponent.cs b/samples/src/Menus/MenuSample/ViewComponents/NestedMenu/NestedMenuViewComponent.cs index 091d6159c..094d43ed1 100644 --- a/samples/src/Menus/MenuSample/ViewComponents/NestedMenu/NestedMenuViewComponent.cs +++ b/samples/src/Menus/MenuSample/ViewComponents/NestedMenu/NestedMenuViewComponent.cs @@ -11,9 +11,7 @@ public class NestedMenuViewComponent : ViewComponent { private readonly IContentRepository _contentRepository; - public NestedMenuViewComponent( - IContentRepository contentRepository - ) + public NestedMenuViewComponent(IContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/Menus/MenuSample/ViewComponents/SimpleMenu/SimpleMenuViewComponent.cs b/samples/src/Menus/MenuSample/ViewComponents/SimpleMenu/SimpleMenuViewComponent.cs index 696879660..4368a6d90 100644 --- a/samples/src/Menus/MenuSample/ViewComponents/SimpleMenu/SimpleMenuViewComponent.cs +++ b/samples/src/Menus/MenuSample/ViewComponents/SimpleMenu/SimpleMenuViewComponent.cs @@ -20,9 +20,7 @@ public class SimpleMenuViewComponent : ViewComponent { private readonly IContentRepository _contentRepository; - public SimpleMenuViewComponent( - IContentRepository contentRepository - ) + public SimpleMenuViewComponent(IContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/PageBlockTypes/PageBlockTypeSample.SharedProject/PageBlockTypeSample.SharedProject.csproj b/samples/src/PageBlockTypes/PageBlockTypeSample.SharedProject/PageBlockTypeSample.SharedProject.csproj index 695ee2e14..4a4b543ea 100644 --- a/samples/src/PageBlockTypes/PageBlockTypeSample.SharedProject/PageBlockTypeSample.SharedProject.csproj +++ b/samples/src/PageBlockTypes/PageBlockTypeSample.SharedProject/PageBlockTypeSample.SharedProject.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable enable diff --git a/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/Carousel/CarouselDisplayModelMapper.cs b/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/Carousel/CarouselDisplayModelMapper.cs index d21988c1a..fafeae291 100644 --- a/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/Carousel/CarouselDisplayModelMapper.cs +++ b/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/Carousel/CarouselDisplayModelMapper.cs @@ -6,17 +6,14 @@ public class CarouselDisplayModelMapper : IPageBlockTypeDisplayModelMapper context, - PageBlockTypeDisplayModelMapperResult result - ) + PageBlockTypeDisplayModelMapperResult result) { // Find all the image ids to load var allImageAssetIds = context @@ -52,7 +49,9 @@ PageBlockTypeDisplayModelMapperResult result } } - private static CarouselSlideDisplayModel? MapSlide(CarouselSlideDataModel dataModel, IReadOnlyDictionary allImages) + private static CarouselSlideDisplayModel? MapSlide( + CarouselSlideDataModel dataModel, + IReadOnlyDictionary allImages) { var image = allImages.GetValueOrDefault(dataModel.ImageId); diff --git a/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/DirectoryList/DirectoryListDisplayModelMapper.cs b/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/DirectoryList/DirectoryListDisplayModelMapper.cs index 1ebccac7a..e7e630253 100644 --- a/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/DirectoryList/DirectoryListDisplayModelMapper.cs +++ b/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/DirectoryList/DirectoryListDisplayModelMapper.cs @@ -4,9 +4,7 @@ public class DirectoryListDisplayModelMapper : IPageBlockTypeDisplayModelMapper< { private readonly IContentRepository _contentRepository; - public DirectoryListDisplayModelMapper( - IContentRepository contentRepository - ) + public DirectoryListDisplayModelMapper(IContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/PageList/PageListDisplayModelMapper.cs b/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/PageList/PageListDisplayModelMapper.cs index 2087f92f4..a0636115f 100644 --- a/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/PageList/PageListDisplayModelMapper.cs +++ b/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/PageList/PageListDisplayModelMapper.cs @@ -6,17 +6,14 @@ public class PageListDisplayModelMapper : IPageBlockTypeDisplayModelMapper context, - PageBlockTypeDisplayModelMapperResult result - ) + PageBlockTypeDisplayModelMapperResult result) { var allPageIds = context.Items.SelectManyDistinctModelValues(m => m.PageIds); diff --git a/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/PageSnippet/PageSnippetDisplayModelMapper.cs b/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/PageSnippet/PageSnippetDisplayModelMapper.cs index 552ef8306..203f1d320 100644 --- a/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/PageSnippet/PageSnippetDisplayModelMapper.cs +++ b/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/PageSnippet/PageSnippetDisplayModelMapper.cs @@ -10,8 +10,7 @@ public class PageSnippetDisplayModelMapper : IPageBlockTypeDisplayModelMapper context, - PageBlockTypeDisplayModelMapperResult result - ) + PageBlockTypeDisplayModelMapperResult result) { var allPageIds = context.Items.SelectDistinctModelValuesWithoutEmpty(m => m.PageId); diff --git a/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/Quotation/QuotationDisplayModelMapper.cs b/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/Quotation/QuotationDisplayModelMapper.cs index 3fc8d4718..5b8eb9703 100644 --- a/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/Quotation/QuotationDisplayModelMapper.cs +++ b/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/Quotation/QuotationDisplayModelMapper.cs @@ -7,8 +7,7 @@ public class QuotationDisplayModelMapper : IPageBlockTypeDisplayModelMapper context, - PageBlockTypeDisplayModelMapperResult result - ) + PageBlockTypeDisplayModelMapperResult result) { foreach (var item in context.Items) { diff --git a/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/SocialProfiles/SocialProfilesDataModel.cs b/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/SocialProfiles/SocialProfilesDataModel.cs index 106708f0b..e53225400 100644 --- a/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/SocialProfiles/SocialProfilesDataModel.cs +++ b/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/SocialProfiles/SocialProfilesDataModel.cs @@ -17,5 +17,5 @@ public class SocialProfilesDataModel : IPageBlockTypeDataModel, IPageBlockTypeDi MaxItems = 10, TitleColumnHeader = "Profile" )] - public IReadOnlyCollection SocialProfiles { get; set; } = Array.Empty(); + public IReadOnlyCollection SocialProfiles { get; set; } = []; } diff --git a/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/TextList/TextListDisplayModelMapper.cs b/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/TextList/TextListDisplayModelMapper.cs index 336270dda..0b3344c3f 100644 --- a/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/TextList/TextListDisplayModelMapper.cs +++ b/samples/src/PageBlockTypes/PageBlockTypeSample/Cofoundry/PageBlockTypes/TextList/TextListDisplayModelMapper.cs @@ -6,8 +6,7 @@ public class TextListDisplayModelMapper : IPageBlockTypeDisplayModelMapper context, - PageBlockTypeDisplayModelMapperResult result - ) + PageBlockTypeDisplayModelMapperResult result) { foreach (var item in context.Items) { diff --git a/samples/src/PageBlockTypes/PageBlockTypeSample/PageBlockTypeSample.csproj b/samples/src/PageBlockTypes/PageBlockTypeSample/PageBlockTypeSample.csproj index a6d7fdabf..6421e5619 100644 --- a/samples/src/PageBlockTypes/PageBlockTypeSample/PageBlockTypeSample.csproj +++ b/samples/src/PageBlockTypes/PageBlockTypeSample/PageBlockTypeSample.csproj @@ -1,7 +1,7 @@ - + - net8.0 + net10.0 enable enable false diff --git a/samples/src/Plugins/ImageSharpSample/Pages/Index.cshtml.cs b/samples/src/Plugins/ImageSharpSample/Pages/Index.cshtml.cs index 49606e82b..0140316e9 100644 --- a/samples/src/Plugins/ImageSharpSample/Pages/Index.cshtml.cs +++ b/samples/src/Plugins/ImageSharpSample/Pages/Index.cshtml.cs @@ -8,9 +8,7 @@ public class IndexModel : PageModel { private readonly IContentRepository _contentRepository; - public IndexModel( - IContentRepository contentRepository - ) + public IndexModel(IContentRepository contentRepository) { ImageAssetId = 1; Width = 600; diff --git a/samples/src/Plugins/SkiaSharpSample/Pages/Index.cshtml.cs b/samples/src/Plugins/SkiaSharpSample/Pages/Index.cshtml.cs index 5324dc950..4cf5737a4 100644 --- a/samples/src/Plugins/SkiaSharpSample/Pages/Index.cshtml.cs +++ b/samples/src/Plugins/SkiaSharpSample/Pages/Index.cshtml.cs @@ -8,9 +8,7 @@ public class IndexModel : PageModel { private readonly IContentRepository _contentRepository; - public IndexModel( - IContentRepository contentRepository - ) + public IndexModel(IContentRepository contentRepository) { ImageAssetId = 1; Width = 600; diff --git a/samples/src/SPASite/SPASite.Domain/Domain/Breeds/Queries/GetAllBreedsQueryHandler.cs b/samples/src/SPASite/SPASite.Domain/Domain/Breeds/Queries/GetAllBreedsQueryHandler.cs index 343860981..b831c840c 100644 --- a/samples/src/SPASite/SPASite.Domain/Domain/Breeds/Queries/GetAllBreedsQueryHandler.cs +++ b/samples/src/SPASite/SPASite.Domain/Domain/Breeds/Queries/GetAllBreedsQueryHandler.cs @@ -10,9 +10,7 @@ public class GetAllBreedsQueryHandler { private readonly IContentRepository _contentRepository; - public GetAllBreedsQueryHandler( - IContentRepository contentRepository - ) + public GetAllBreedsQueryHandler(IContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/SPASite/SPASite.Domain/Domain/Breeds/Queries/GetBreedByIdQueryHandler.cs b/samples/src/SPASite/SPASite.Domain/Domain/Breeds/Queries/GetBreedByIdQueryHandler.cs index 26375fb02..8c85dda9c 100644 --- a/samples/src/SPASite/SPASite.Domain/Domain/Breeds/Queries/GetBreedByIdQueryHandler.cs +++ b/samples/src/SPASite/SPASite.Domain/Domain/Breeds/Queries/GetBreedByIdQueryHandler.cs @@ -6,9 +6,7 @@ public class GetBreedByIdQueryHandler { private readonly IContentRepository _contentRepository; - public GetBreedByIdQueryHandler( - IContentRepository contentRepository - ) + public GetBreedByIdQueryHandler(IContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/SPASite/SPASite.Domain/Domain/Cats/Commands/SetCatLikedCommandHandler.cs b/samples/src/SPASite/SPASite.Domain/Domain/Cats/Commands/SetCatLikedCommandHandler.cs index 0a0103737..8212bd7c7 100644 --- a/samples/src/SPASite/SPASite.Domain/Domain/Cats/Commands/SetCatLikedCommandHandler.cs +++ b/samples/src/SPASite/SPASite.Domain/Domain/Cats/Commands/SetCatLikedCommandHandler.cs @@ -1,6 +1,6 @@ using Cofoundry.Core.EntityFramework; -using SPASite.Data; using Microsoft.Data.SqlClient; +using SPASite.Data; namespace SPASite.Domain; @@ -23,8 +23,7 @@ public class SetCatLikedCommandHandler public SetCatLikedCommandHandler( IEntityFrameworkSqlExecutor entityFrameworkSqlExecutor, - SPASiteDbContext spaSiteDbContext - ) + SPASiteDbContext spaSiteDbContext) { _entityFrameworkSqlExecutor = entityFrameworkSqlExecutor; _spaSiteDbContext = spaSiteDbContext; @@ -37,14 +36,13 @@ public Task ExecuteAsync(SetCatLikedCommand command, IExecutionContext execution // you could also use EF directly, Dapper or mix in any other data access approach. // For more info see https://www.cofoundry.org/docs/framework/entity-framework-and-dbcontext-tools#executing-stored-procedures--raw-sql - return _entityFrameworkSqlExecutor - .ExecuteCommandAsync(_spaSiteDbContext, - "app.CatLike_SetLiked", - new SqlParameter("@CatId", command.CatId), - new SqlParameter("@UserId", executionContext.UserContext.UserId), - new SqlParameter("@IsLiked", command.IsLiked), - new SqlParameter("@CreateDate", executionContext.ExecutionDate) - ); + return _entityFrameworkSqlExecutor.ExecuteCommandAsync( + _spaSiteDbContext, + "app.CatLike_SetLiked", + new SqlParameter("@CatId", command.CatId), + new SqlParameter("@UserId", executionContext.UserContext.UserId), + new SqlParameter("@IsLiked", command.IsLiked), + new SqlParameter("@CreateDate", executionContext.ExecutionDate)); } } diff --git a/samples/src/SPASite/SPASite.Domain/Domain/Cats/Queries/GetCatDetailsByIdQueryHandler.cs b/samples/src/SPASite/SPASite.Domain/Domain/Cats/Queries/GetCatDetailsByIdQueryHandler.cs index 723aa74b8..11d0a504a 100644 --- a/samples/src/SPASite/SPASite.Domain/Domain/Cats/Queries/GetCatDetailsByIdQueryHandler.cs +++ b/samples/src/SPASite/SPASite.Domain/Domain/Cats/Queries/GetCatDetailsByIdQueryHandler.cs @@ -11,8 +11,7 @@ public class GetCatDetailsByIdQueryHandler public GetCatDetailsByIdQueryHandler( IContentRepository contentRepository, - SPASiteDbContext dbContext - ) + SPASiteDbContext dbContext) { _contentRepository = contentRepository; _dbContext = dbContext; diff --git a/samples/src/SPASite/SPASite.Domain/Domain/Cats/Queries/GetCatSummariesByMemberLikedQueryHandler.cs b/samples/src/SPASite/SPASite.Domain/Domain/Cats/Queries/GetCatSummariesByMemberLikedQueryHandler.cs index 6bcec6448..60e13cebb 100644 --- a/samples/src/SPASite/SPASite.Domain/Domain/Cats/Queries/GetCatSummariesByMemberLikedQueryHandler.cs +++ b/samples/src/SPASite/SPASite.Domain/Domain/Cats/Queries/GetCatSummariesByMemberLikedQueryHandler.cs @@ -11,8 +11,7 @@ public class GetCatSummariesByMemberLikedQueryHandler public GetCatSummariesByMemberLikedQueryHandler( IContentRepository contentRepository, - SPASiteDbContext dbContext - ) + SPASiteDbContext dbContext) { _contentRepository = contentRepository; _dbContext = dbContext; @@ -78,8 +77,7 @@ private Task> GetLikeCounts(IReadOnlyCollection MapCats( IReadOnlyCollection customEntities, IReadOnlyDictionary images, - IReadOnlyDictionary allLikeCounts - ) + IReadOnlyDictionary allLikeCounts) { var cats = new List(customEntities.Count); diff --git a/samples/src/SPASite/SPASite.Domain/Domain/Cats/Queries/SearchCatSummariesQueryHandler.cs b/samples/src/SPASite/SPASite.Domain/Domain/Cats/Queries/SearchCatSummariesQueryHandler.cs index 82832dc60..c71877a92 100644 --- a/samples/src/SPASite/SPASite.Domain/Domain/Cats/Queries/SearchCatSummariesQueryHandler.cs +++ b/samples/src/SPASite/SPASite.Domain/Domain/Cats/Queries/SearchCatSummariesQueryHandler.cs @@ -11,8 +11,7 @@ public class SearchCatSummariesQueryHandler public SearchCatSummariesQueryHandler( SPASiteDbContext dbContext, - IContentRepository contentRepository - ) + IContentRepository contentRepository) { _dbContext = dbContext; _contentRepository = contentRepository; @@ -75,8 +74,7 @@ private Task> GetLikeCounts(PagedQueryResult MapCats( PagedQueryResult customEntityResult, IReadOnlyDictionary images, - IReadOnlyDictionary allLikeCounts - ) + IReadOnlyDictionary allLikeCounts) { var cats = new List(customEntityResult.Items.Count); diff --git a/samples/src/SPASite/SPASite.Domain/Domain/Features/Queries/GetAllFeaturesQueryHandler.cs b/samples/src/SPASite/SPASite.Domain/Domain/Features/Queries/GetAllFeaturesQueryHandler.cs index 8ba38660d..07b27741e 100644 --- a/samples/src/SPASite/SPASite.Domain/Domain/Features/Queries/GetAllFeaturesQueryHandler.cs +++ b/samples/src/SPASite/SPASite.Domain/Domain/Features/Queries/GetAllFeaturesQueryHandler.cs @@ -6,9 +6,7 @@ public class GetAllFeaturesQueryHandler { private readonly IContentRepository _contentRepository; - public GetAllFeaturesQueryHandler( - IContentRepository contentRepository - ) + public GetAllFeaturesQueryHandler(IContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/SPASite/SPASite.Domain/Domain/Features/Queries/GetFeaturesByIdRangeQuery.cs b/samples/src/SPASite/SPASite.Domain/Domain/Features/Queries/GetFeaturesByIdRangeQuery.cs index 0acc6aa8f..ebd2f1448 100644 --- a/samples/src/SPASite/SPASite.Domain/Domain/Features/Queries/GetFeaturesByIdRangeQuery.cs +++ b/samples/src/SPASite/SPASite.Domain/Domain/Features/Queries/GetFeaturesByIdRangeQuery.cs @@ -4,7 +4,7 @@ public class GetFeaturesByIdRangeQuery : IQuery(); + FeatureIds = []; } public GetFeaturesByIdRangeQuery(IReadOnlyCollection ids) diff --git a/samples/src/SPASite/SPASite.Domain/Domain/Features/Queries/GetFeaturesByIdRangeQueryHandler.cs b/samples/src/SPASite/SPASite.Domain/Domain/Features/Queries/GetFeaturesByIdRangeQueryHandler.cs index c3f403334..aefcf274e 100644 --- a/samples/src/SPASite/SPASite.Domain/Domain/Features/Queries/GetFeaturesByIdRangeQueryHandler.cs +++ b/samples/src/SPASite/SPASite.Domain/Domain/Features/Queries/GetFeaturesByIdRangeQueryHandler.cs @@ -6,9 +6,7 @@ public class GetFeaturesByIdRangeQueryHandler { private readonly IContentRepository _contentRepository; - public GetFeaturesByIdRangeQueryHandler( - IContentRepository contentRepository - ) + public GetFeaturesByIdRangeQueryHandler(IContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/SPASite/SPASite.Domain/Domain/Members/Commands/RegisterMemberAndSignInCommandHandler.cs b/samples/src/SPASite/SPASite.Domain/Domain/Members/Commands/RegisterMemberAndSignInCommandHandler.cs index 170d8cf95..8b0ec34f6 100644 --- a/samples/src/SPASite/SPASite.Domain/Domain/Members/Commands/RegisterMemberAndSignInCommandHandler.cs +++ b/samples/src/SPASite/SPASite.Domain/Domain/Members/Commands/RegisterMemberAndSignInCommandHandler.cs @@ -16,8 +16,7 @@ public class RegisterMemberAndSignInCommandHandler public RegisterMemberAndSignInCommandHandler( IAdvancedContentRepository contentRepository, - IMailService mailService - ) + IMailService mailService) { _contentRepository = contentRepository; _mailService = mailService; @@ -79,6 +78,7 @@ private async Task SendWelcomeNotification(RegisterMemberAndSignInCommand comman { Name = command.DisplayName }; + await _mailService.SendAsync(command.Email, welcomeEmailTemplate); } } diff --git a/samples/src/SPASite/SPASite.Domain/Domain/Members/Commands/SignMemberInCommandHandler.cs b/samples/src/SPASite/SPASite.Domain/Domain/Members/Commands/SignMemberInCommandHandler.cs index a4f371962..f390ea2ce 100644 --- a/samples/src/SPASite/SPASite.Domain/Domain/Members/Commands/SignMemberInCommandHandler.cs +++ b/samples/src/SPASite/SPASite.Domain/Domain/Members/Commands/SignMemberInCommandHandler.cs @@ -13,9 +13,7 @@ public class SignMemberInCommandHandler { private readonly IAdvancedContentRepository _contentRepository; - public SignMemberInCommandHandler( - IAdvancedContentRepository contentRepository - ) + public SignMemberInCommandHandler(IAdvancedContentRepository contentRepository) { _contentRepository = contentRepository; } @@ -33,4 +31,4 @@ public Task ExecuteAsync(SignMemberInCommand command, IExecutionContext executio RememberUser = true }); } -} \ No newline at end of file +} diff --git a/samples/src/SPASite/SPASite.Domain/Domain/Members/Commands/SignMemberOutCommandHandler.cs b/samples/src/SPASite/SPASite.Domain/Domain/Members/Commands/SignMemberOutCommandHandler.cs index aa60aaf48..a5f3914c5 100644 --- a/samples/src/SPASite/SPASite.Domain/Domain/Members/Commands/SignMemberOutCommandHandler.cs +++ b/samples/src/SPASite/SPASite.Domain/Domain/Members/Commands/SignMemberOutCommandHandler.cs @@ -11,9 +11,7 @@ public class SignMemberOutCommandHandler { private readonly IAdvancedContentRepository _contentRepository; - public SignMemberOutCommandHandler( - IAdvancedContentRepository contentRepository - ) + public SignMemberOutCommandHandler(IAdvancedContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/SPASite/SPASite.Domain/Domain/Members/Queries/GetCurrentMemberSummaryQueryHandler.cs b/samples/src/SPASite/SPASite.Domain/Domain/Members/Queries/GetCurrentMemberSummaryQueryHandler.cs index 234da3f9a..5c8667763 100644 --- a/samples/src/SPASite/SPASite.Domain/Domain/Members/Queries/GetCurrentMemberSummaryQueryHandler.cs +++ b/samples/src/SPASite/SPASite.Domain/Domain/Members/Queries/GetCurrentMemberSummaryQueryHandler.cs @@ -11,9 +11,7 @@ public class GetCurrentMemberSummaryQueryHandler { private readonly IContentRepository _contentRepository; - public GetCurrentMemberSummaryQueryHandler( - IContentRepository contentRepository - ) + public GetCurrentMemberSummaryQueryHandler(IContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/SPASite/SPASite.Domain/SPASite.Domain.csproj b/samples/src/SPASite/SPASite.Domain/SPASite.Domain.csproj index db390b169..5cf38e691 100644 --- a/samples/src/SPASite/SPASite.Domain/SPASite.Domain.csproj +++ b/samples/src/SPASite/SPASite.Domain/SPASite.Domain.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable enable diff --git a/samples/src/SPASite/SPASite/Api/AuthApiController.cs b/samples/src/SPASite/SPASite/Api/AuthApiController.cs index d56be9ef7..4fc682af8 100644 --- a/samples/src/SPASite/SPASite/Api/AuthApiController.cs +++ b/samples/src/SPASite/SPASite/Api/AuthApiController.cs @@ -13,8 +13,7 @@ public class AuthApiController : ControllerBase public AuthApiController( IApiResponseHelper apiResponseHelper, IAntiforgery antiforgery, - IDomainRepository domainRepository - ) + IDomainRepository domainRepository) { _apiResponseHelper = apiResponseHelper; _antiforgery = antiforgery; diff --git a/samples/src/SPASite/SPASite/Api/BreedsApiController.cs b/samples/src/SPASite/SPASite/Api/BreedsApiController.cs index d62df646f..28523228a 100644 --- a/samples/src/SPASite/SPASite/Api/BreedsApiController.cs +++ b/samples/src/SPASite/SPASite/Api/BreedsApiController.cs @@ -5,9 +5,7 @@ public class BreedsApiController : ControllerBase { private readonly IApiResponseHelper _apiResponseHelper; - public BreedsApiController( - IApiResponseHelper apiResponseHelper - ) + public BreedsApiController(IApiResponseHelper apiResponseHelper) { _apiResponseHelper = apiResponseHelper; } @@ -27,4 +25,4 @@ public async Task Get(int breedId) return await _apiResponseHelper.RunQueryAsync(query); } -} \ No newline at end of file +} diff --git a/samples/src/SPASite/SPASite/Api/CatsApiController.cs b/samples/src/SPASite/SPASite/Api/CatsApiController.cs index a089190c7..4f4cef883 100644 --- a/samples/src/SPASite/SPASite/Api/CatsApiController.cs +++ b/samples/src/SPASite/SPASite/Api/CatsApiController.cs @@ -6,9 +6,7 @@ public class CatsApiController : ControllerBase { private readonly IApiResponseHelper _apiResponseHelper; - public CatsApiController( - IApiResponseHelper apiResponseHelper - ) + public CatsApiController(IApiResponseHelper apiResponseHelper) { _apiResponseHelper = apiResponseHelper; } diff --git a/samples/src/SPASite/SPASite/Api/CurrentUserApiController.cs b/samples/src/SPASite/SPASite/Api/CurrentUserApiController.cs index bc10af0a4..650223229 100644 --- a/samples/src/SPASite/SPASite/Api/CurrentUserApiController.cs +++ b/samples/src/SPASite/SPASite/Api/CurrentUserApiController.cs @@ -9,8 +9,7 @@ public class CurrentMemberApiController : ControllerBase public CurrentMemberApiController( IContentRepository contentRepository, - IApiResponseHelper apiResponseHelper - ) + IApiResponseHelper apiResponseHelper) { _contentRepository = contentRepository; _apiResponseHelper = apiResponseHelper; diff --git a/samples/src/SPASite/SPASite/Api/FeaturesApiController.cs b/samples/src/SPASite/SPASite/Api/FeaturesApiController.cs index 36b8c25ba..f2b15e330 100644 --- a/samples/src/SPASite/SPASite/Api/FeaturesApiController.cs +++ b/samples/src/SPASite/SPASite/Api/FeaturesApiController.cs @@ -5,9 +5,7 @@ public class FeaturesApiController : ControllerBase { private readonly IApiResponseHelper _apiResponseHelper; - public FeaturesApiController( - IApiResponseHelper apiResponseHelper - ) + public FeaturesApiController(IApiResponseHelper apiResponseHelper) { _apiResponseHelper = apiResponseHelper; } @@ -19,4 +17,4 @@ public async Task Get() return await _apiResponseHelper.RunQueryAsync(query); } -} \ No newline at end of file +} diff --git a/samples/src/SPASite/SPASite/SPASite.csproj b/samples/src/SPASite/SPASite/SPASite.csproj index 0856bce45..e3f28c222 100644 --- a/samples/src/SPASite/SPASite/SPASite.csproj +++ b/samples/src/SPASite/SPASite/SPASite.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable enable false @@ -9,7 +9,7 @@ - + diff --git a/samples/src/SimpleSite/SimpleSite/Cofoundry/CustomEntities/BlogPosts/BlogPostDisplayModelMapper.cs b/samples/src/SimpleSite/SimpleSite/Cofoundry/CustomEntities/BlogPosts/BlogPostDisplayModelMapper.cs index f0000e845..7b5448924 100644 --- a/samples/src/SimpleSite/SimpleSite/Cofoundry/CustomEntities/BlogPosts/BlogPostDisplayModelMapper.cs +++ b/samples/src/SimpleSite/SimpleSite/Cofoundry/CustomEntities/BlogPosts/BlogPostDisplayModelMapper.cs @@ -11,9 +11,7 @@ public class BlogPostDisplayModelMapper { private readonly IContentRepository _contentRepository; - public BlogPostDisplayModelMapper( - IContentRepository contentRepository - ) + public BlogPostDisplayModelMapper(IContentRepository contentRepository) { _contentRepository = contentRepository; } @@ -37,8 +35,7 @@ IContentRepository contentRepository public async Task MapDisplayModelAsync( CustomEntityRenderDetails renderDetails, BlogPostDataModel dataModel, - PublishStatusQuery publishStatusQuery - ) + PublishStatusQuery publishStatusQuery) { var categories = await MapCategories(dataModel, publishStatusQuery); var author = await MapAuthor(dataModel, publishStatusQuery); @@ -59,8 +56,7 @@ PublishStatusQuery publishStatusQuery private async Task> MapCategories( BlogPostDataModel dataModel, - PublishStatusQuery publishStatusQuery - ) + PublishStatusQuery publishStatusQuery) { if (EnumerableHelper.IsNullOrEmpty(dataModel.CategoryIds)) { @@ -100,8 +96,7 @@ private CategorySummary MapCategory(CustomEntityRenderSummary renderSummary) private async Task MapAuthor( BlogPostDataModel dataModel, - PublishStatusQuery publishStatusQuery - ) + PublishStatusQuery publishStatusQuery) { if (dataModel.AuthorId < 1) { diff --git a/samples/src/SimpleSite/SimpleSite/Cofoundry/PageBlockTypes/ContentSection/ContentSectionDisplayModelMapper.cs b/samples/src/SimpleSite/SimpleSite/Cofoundry/PageBlockTypes/ContentSection/ContentSectionDisplayModelMapper.cs index b73cef7f7..b83617b71 100644 --- a/samples/src/SimpleSite/SimpleSite/Cofoundry/PageBlockTypes/ContentSection/ContentSectionDisplayModelMapper.cs +++ b/samples/src/SimpleSite/SimpleSite/Cofoundry/PageBlockTypes/ContentSection/ContentSectionDisplayModelMapper.cs @@ -24,8 +24,7 @@ public class ContentSectionDisplayModelMapper : IPageBlockTypeDisplayModelMapper /// public Task MapAsync( PageBlockTypeDisplayModelMapperContext context, - PageBlockTypeDisplayModelMapperResult result - ) + PageBlockTypeDisplayModelMapperResult result) { foreach (var input in context.Items) { @@ -40,4 +39,4 @@ PageBlockTypeDisplayModelMapperResult result return Task.CompletedTask; } -} \ No newline at end of file +} diff --git a/samples/src/SimpleSite/SimpleSite/Cofoundry/PageBlockTypes/ContentSplitSection/ContentSplitSectionDisplayModelMapper.cs b/samples/src/SimpleSite/SimpleSite/Cofoundry/PageBlockTypes/ContentSplitSection/ContentSplitSectionDisplayModelMapper.cs index 3bf2ae1da..8c346c1c6 100644 --- a/samples/src/SimpleSite/SimpleSite/Cofoundry/PageBlockTypes/ContentSplitSection/ContentSplitSectionDisplayModelMapper.cs +++ b/samples/src/SimpleSite/SimpleSite/Cofoundry/PageBlockTypes/ContentSplitSection/ContentSplitSectionDisplayModelMapper.cs @@ -15,9 +15,7 @@ public class ContentSplitSectionDisplayModelMapper : IPageBlockTypeDisplayModelM { private readonly IContentRepository _contentRepository; - public ContentSplitSectionDisplayModelMapper( - IContentRepository contentRepository - ) + public ContentSplitSectionDisplayModelMapper(IContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/SimpleSite/SimpleSite/SimpleSite.csproj b/samples/src/SimpleSite/SimpleSite/SimpleSite.csproj index bc4ceb020..d27e990a6 100644 --- a/samples/src/SimpleSite/SimpleSite/SimpleSite.csproj +++ b/samples/src/SimpleSite/SimpleSite/SimpleSite.csproj @@ -1,7 +1,7 @@ - + - net8.0 + net10.0 enable enable false diff --git a/samples/src/SimpleSite/SimpleSite/ViewComponents/BlogPostListViewComponent.cs b/samples/src/SimpleSite/SimpleSite/ViewComponents/BlogPostListViewComponent.cs index 4bc0740dc..c42ff5e1f 100644 --- a/samples/src/SimpleSite/SimpleSite/ViewComponents/BlogPostListViewComponent.cs +++ b/samples/src/SimpleSite/SimpleSite/ViewComponents/BlogPostListViewComponent.cs @@ -9,8 +9,7 @@ public class BlogPostListViewComponent : ViewComponent public BlogPostListViewComponent( IContentRepository contentRepository, - IVisualEditorStateService visualEditorStateService - ) + IVisualEditorStateService visualEditorStateService) { _contentRepository = contentRepository; _visualEditorStateService = visualEditorStateService; @@ -76,8 +75,7 @@ private SearchBlogPostsQuery ModelBind() /// private async Task> MapBlogPostsAsync( PagedQueryResult customEntityResult, - PublishStatusQuery ambientEntityPublishStatusQuery - ) + PublishStatusQuery ambientEntityPublishStatusQuery) { var blogPosts = new List(customEntityResult.Items.Count); diff --git a/samples/src/SimpleSite/SimpleSite/ViewComponents/ContactRequestFormViewComponent.cs b/samples/src/SimpleSite/SimpleSite/ViewComponents/ContactRequestFormViewComponent.cs index 659d9ca68..257230236 100644 --- a/samples/src/SimpleSite/SimpleSite/ViewComponents/ContactRequestFormViewComponent.cs +++ b/samples/src/SimpleSite/SimpleSite/ViewComponents/ContactRequestFormViewComponent.cs @@ -13,8 +13,7 @@ public class ContactRequestFormViewComponent : ViewComponent public ContactRequestFormViewComponent( IMailService mailService, IModelValidationService modelValidationService, - SimpleSiteSettings simpleTestSiteSettings - ) + SimpleSiteSettings simpleTestSiteSettings) { _mailService = mailService; _modelValidationService = modelValidationService; diff --git a/samples/src/SimpleSite/SimpleSite/ViewComponents/HomepageBlogPostsViewComponent.cs b/samples/src/SimpleSite/SimpleSite/ViewComponents/HomepageBlogPostsViewComponent.cs index 42cb90678..86e1038a5 100644 --- a/samples/src/SimpleSite/SimpleSite/ViewComponents/HomepageBlogPostsViewComponent.cs +++ b/samples/src/SimpleSite/SimpleSite/ViewComponents/HomepageBlogPostsViewComponent.cs @@ -9,8 +9,7 @@ public class HomepageBlogPostsViewComponent : ViewComponent public HomepageBlogPostsViewComponent( IContentRepository contentRepository, - IVisualEditorStateService visualEditorStateService - ) + IVisualEditorStateService visualEditorStateService) { _contentRepository = contentRepository; _visualEditorStateService = visualEditorStateService; diff --git a/samples/src/SimpleSite/SimpleSite/ViewComponents/SidebarCategoriesViewComponent.cs b/samples/src/SimpleSite/SimpleSite/ViewComponents/SidebarCategoriesViewComponent.cs index 0f051dcf9..a9a7af7f6 100644 --- a/samples/src/SimpleSite/SimpleSite/ViewComponents/SidebarCategoriesViewComponent.cs +++ b/samples/src/SimpleSite/SimpleSite/ViewComponents/SidebarCategoriesViewComponent.cs @@ -9,8 +9,7 @@ public class SidebarCategoriesViewComponent : ViewComponent public SidebarCategoriesViewComponent( IContentRepository contentRepository, - IVisualEditorStateService visualEditorStateService - ) + IVisualEditorStateService visualEditorStateService) { _contentRepository = contentRepository; _visualEditorStateService = visualEditorStateService; diff --git a/samples/src/UserAreas/AuthenticationSample/AuthenticationSample.csproj b/samples/src/UserAreas/AuthenticationSample/AuthenticationSample.csproj index 4b88f9bec..f40c7b9f5 100644 --- a/samples/src/UserAreas/AuthenticationSample/AuthenticationSample.csproj +++ b/samples/src/UserAreas/AuthenticationSample/AuthenticationSample.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable enable false diff --git a/samples/src/UserAreas/AuthenticationSample/Pages/Members/ForgotPassword.cshtml.cs b/samples/src/UserAreas/AuthenticationSample/Pages/Members/ForgotPassword.cshtml.cs index f51cf0621..14cca2e29 100644 --- a/samples/src/UserAreas/AuthenticationSample/Pages/Members/ForgotPassword.cshtml.cs +++ b/samples/src/UserAreas/AuthenticationSample/Pages/Members/ForgotPassword.cshtml.cs @@ -8,9 +8,7 @@ public class ForgotPasswordModel : PageModel { private readonly IAdvancedContentRepository _contentRepository; - public ForgotPasswordModel( - IAdvancedContentRepository contentRepository - ) + public ForgotPasswordModel(IAdvancedContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/UserAreas/AuthenticationSample/Pages/Members/Index.cshtml.cs b/samples/src/UserAreas/AuthenticationSample/Pages/Members/Index.cshtml.cs index 28e8bda5f..198224d13 100644 --- a/samples/src/UserAreas/AuthenticationSample/Pages/Members/Index.cshtml.cs +++ b/samples/src/UserAreas/AuthenticationSample/Pages/Members/Index.cshtml.cs @@ -7,9 +7,7 @@ public class IndexModel : PageModel { private readonly IAdvancedContentRepository _contentRepository; - public IndexModel( - IAdvancedContentRepository contentRepository - ) + public IndexModel(IAdvancedContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/UserAreas/AuthenticationSample/Pages/Members/MyAccount/DeleteAccount.cshtml.cs b/samples/src/UserAreas/AuthenticationSample/Pages/Members/MyAccount/DeleteAccount.cshtml.cs index 77a26c245..fd367a383 100644 --- a/samples/src/UserAreas/AuthenticationSample/Pages/Members/MyAccount/DeleteAccount.cshtml.cs +++ b/samples/src/UserAreas/AuthenticationSample/Pages/Members/MyAccount/DeleteAccount.cshtml.cs @@ -7,9 +7,7 @@ public class DeleteAccountModel : PageModel { private readonly IAdvancedContentRepository _contentRepository; - public DeleteAccountModel( - IAdvancedContentRepository contentRepository - ) + public DeleteAccountModel(IAdvancedContentRepository contentRepository) { _contentRepository = contentRepository; } @@ -30,4 +28,4 @@ await _contentRepository IsSuccess = ModelState.IsValid; } -} \ No newline at end of file +} diff --git a/samples/src/UserAreas/AuthenticationSample/Pages/Members/MyAccount/Index.cshtml.cs b/samples/src/UserAreas/AuthenticationSample/Pages/Members/MyAccount/Index.cshtml.cs index 44f7fbe6e..782f49439 100644 --- a/samples/src/UserAreas/AuthenticationSample/Pages/Members/MyAccount/Index.cshtml.cs +++ b/samples/src/UserAreas/AuthenticationSample/Pages/Members/MyAccount/Index.cshtml.cs @@ -9,9 +9,7 @@ public class IndexModel : PageModel { private readonly IAdvancedContentRepository _contentRepository; - public IndexModel( - IAdvancedContentRepository contentRepository - ) + public IndexModel(IAdvancedContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/UserAreas/AuthenticationSample/Pages/Members/MyAccount/UpdatePassword.cshtml.cs b/samples/src/UserAreas/AuthenticationSample/Pages/Members/MyAccount/UpdatePassword.cshtml.cs index 1a0356ca7..34fd4f1fa 100644 --- a/samples/src/UserAreas/AuthenticationSample/Pages/Members/MyAccount/UpdatePassword.cshtml.cs +++ b/samples/src/UserAreas/AuthenticationSample/Pages/Members/MyAccount/UpdatePassword.cshtml.cs @@ -9,9 +9,7 @@ public class UpdatePasswordModel : PageModel { private readonly IAdvancedContentRepository _contentRepository; - public UpdatePasswordModel( - IAdvancedContentRepository contentRepository - ) + public UpdatePasswordModel(IAdvancedContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/UserAreas/AuthenticationSample/Pages/Members/PasswordChangeRequired.cshtml.cs b/samples/src/UserAreas/AuthenticationSample/Pages/Members/PasswordChangeRequired.cshtml.cs index 98957a0ce..f64d19e14 100644 --- a/samples/src/UserAreas/AuthenticationSample/Pages/Members/PasswordChangeRequired.cshtml.cs +++ b/samples/src/UserAreas/AuthenticationSample/Pages/Members/PasswordChangeRequired.cshtml.cs @@ -8,9 +8,7 @@ public class PasswordChangeRequiredModel : PageModel { private readonly IAdvancedContentRepository _contentRepository; - public PasswordChangeRequiredModel( - IAdvancedContentRepository contentRepository - ) + public PasswordChangeRequiredModel(IAdvancedContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/UserAreas/AuthenticationSample/Pages/Members/ResetPassword.cshtml.cs b/samples/src/UserAreas/AuthenticationSample/Pages/Members/ResetPassword.cshtml.cs index 1c6032b6d..f49f00a79 100644 --- a/samples/src/UserAreas/AuthenticationSample/Pages/Members/ResetPassword.cshtml.cs +++ b/samples/src/UserAreas/AuthenticationSample/Pages/Members/ResetPassword.cshtml.cs @@ -8,9 +8,7 @@ public class ResetPasswordModel : PageModel { private readonly IAdvancedContentRepository _contentRepository; - public ResetPasswordModel( - IAdvancedContentRepository contentRepository - ) + public ResetPasswordModel(IAdvancedContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/UserAreas/AuthenticationSample/Pages/Members/SignIn.cshtml.cs b/samples/src/UserAreas/AuthenticationSample/Pages/Members/SignIn.cshtml.cs index 548cf38bb..3366c8a6d 100644 --- a/samples/src/UserAreas/AuthenticationSample/Pages/Members/SignIn.cshtml.cs +++ b/samples/src/UserAreas/AuthenticationSample/Pages/Members/SignIn.cshtml.cs @@ -8,9 +8,7 @@ public class SignInModel : PageModel { private readonly IAdvancedContentRepository _contentRepository; - public SignInModel( - IAdvancedContentRepository contentRepository - ) + public SignInModel(IAdvancedContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/UserAreas/AuthenticationSample/Pages/Members/SignOut.cshtml.cs b/samples/src/UserAreas/AuthenticationSample/Pages/Members/SignOut.cshtml.cs index 0f9ab35b7..a791ac46a 100644 --- a/samples/src/UserAreas/AuthenticationSample/Pages/Members/SignOut.cshtml.cs +++ b/samples/src/UserAreas/AuthenticationSample/Pages/Members/SignOut.cshtml.cs @@ -7,9 +7,7 @@ public class SignOutModel : PageModel { private readonly IAdvancedContentRepository _contentRepository; - public SignOutModel( - IAdvancedContentRepository contentRepository - ) + public SignOutModel(IAdvancedContentRepository contentRepository) { _contentRepository = contentRepository; } diff --git a/samples/src/UserAreas/RegistrationAndVerificationSample/Controllers/MembersAuthController.cs b/samples/src/UserAreas/RegistrationAndVerificationSample/Controllers/MembersAuthController.cs index ee158e912..de0ad1346 100644 --- a/samples/src/UserAreas/RegistrationAndVerificationSample/Controllers/MembersAuthController.cs +++ b/samples/src/UserAreas/RegistrationAndVerificationSample/Controllers/MembersAuthController.cs @@ -8,9 +8,7 @@ public class MembersAuthController : Controller { private readonly IAdvancedContentRepository _contentRepository; - public MembersAuthController( - IAdvancedContentRepository contentRepository - ) + public MembersAuthController(IAdvancedContentRepository contentRepository) { _contentRepository = contentRepository; } @@ -30,6 +28,7 @@ public async Task Index() } var viewModel = new SignInViewModel(); + return View(viewModel); } diff --git a/samples/src/UserAreas/RegistrationAndVerificationSample/Controllers/MembersController.cs b/samples/src/UserAreas/RegistrationAndVerificationSample/Controllers/MembersController.cs index 4430c4a2e..db291063f 100644 --- a/samples/src/UserAreas/RegistrationAndVerificationSample/Controllers/MembersController.cs +++ b/samples/src/UserAreas/RegistrationAndVerificationSample/Controllers/MembersController.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; namespace RegistrationAndVerificationSample.Controllers; @@ -8,9 +8,7 @@ public class MembersController : Controller { private readonly IAdvancedContentRepository _contentRepository; - public MembersController( - IAdvancedContentRepository contentRepository - ) + public MembersController(IAdvancedContentRepository contentRepository) { _contentRepository = contentRepository; } @@ -27,4 +25,4 @@ public async Task Index() return View(member); } -} \ No newline at end of file +} diff --git a/samples/src/UserAreas/RegistrationAndVerificationSample/Controllers/MembersRegistrationController.cs b/samples/src/UserAreas/RegistrationAndVerificationSample/Controllers/MembersRegistrationController.cs index a77fdcbba..2a4d00d46 100644 --- a/samples/src/UserAreas/RegistrationAndVerificationSample/Controllers/MembersRegistrationController.cs +++ b/samples/src/UserAreas/RegistrationAndVerificationSample/Controllers/MembersRegistrationController.cs @@ -8,9 +8,7 @@ public class MembersRegistrationController : Controller { private readonly IAdvancedContentRepository _contentRepository; - public MembersRegistrationController( - IAdvancedContentRepository contentRepository - ) + public MembersRegistrationController(IAdvancedContentRepository contentRepository) { _contentRepository = contentRepository; } @@ -30,6 +28,7 @@ public async Task Index() } var viewModel = new RegisterViewModel(); + return View(viewModel); } diff --git a/samples/src/UserAreas/RegistrationAndVerificationSample/RegistrationAndVerificationSample.csproj b/samples/src/UserAreas/RegistrationAndVerificationSample/RegistrationAndVerificationSample.csproj index 7f774e685..6508d4bf0 100644 --- a/samples/src/UserAreas/RegistrationAndVerificationSample/RegistrationAndVerificationSample.csproj +++ b/samples/src/UserAreas/RegistrationAndVerificationSample/RegistrationAndVerificationSample.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable enable false diff --git a/src/Cofoundry.Core/Caching/InMemoryObjectCache/ClearableMemoryCache.cs b/src/Cofoundry.Core/Caching/InMemoryObjectCache/ClearableMemoryCache.cs index f66680b47..39a046a53 100644 --- a/src/Cofoundry.Core/Caching/InMemoryObjectCache/ClearableMemoryCache.cs +++ b/src/Cofoundry.Core/Caching/InMemoryObjectCache/ClearableMemoryCache.cs @@ -17,24 +17,30 @@ public class ClearableMemoryCache : IDisposable { private readonly MemoryCache _memoryCache; private readonly HashSet _keys = []; - private readonly object _lock = new(); + private readonly Lock _lock = new(); - public ClearableMemoryCache( - IOptions optionsAccessor - ) + /// + /// DI constructor. + /// + public ClearableMemoryCache(IOptions optionsAccessor) { _memoryCache = new MemoryCache(optionsAccessor); } - public T? Get(string key) + /// + /// Gets the value associated with this key if present. + /// + /// The type of the object to get. + /// The key of the value to get. + public TItem? Get(string key) { - var entry = _memoryCache.Get(key); + var entry = _memoryCache.Get(key); return entry; } - public T? GetOrAdd(string key, Func getter, DateTimeOffset? expiry = null) + public TItem? GetOrAdd(string key, Func getter, DateTimeOffset? expiry = null) { - if (_memoryCache.TryGetValue(key, out T? entry)) + if (_memoryCache.TryGetValue(key, out TItem? entry)) { return entry; } @@ -57,15 +63,15 @@ IOptions optionsAccessor } } - public Task GetOrAddAsync(string key, Func> getter, DateTimeOffset? expiry = null) + public Task GetOrAddAsync(string key, Func> getter, DateTimeOffset? expiry = null) { - if (_memoryCache.TryGetValue(key, out T? existingEntry)) + if (_memoryCache.TryGetValue(key, out TItem? existingEntry)) { return Task.FromResult(existingEntry); } else { - Task newEntry; + Task newEntry; lock (_lock) { @@ -104,6 +110,10 @@ public void ClearAll(string? cacheNamespace = null) } } + /// + /// Removes the object from the the cache with the associated . + /// + /// The key of the object to remove. public void ClearEntry(string key) { lock (_lock) @@ -113,6 +123,7 @@ public void ClearEntry(string key) } } + /// public void Dispose() { _memoryCache?.Dispose(); diff --git a/src/Cofoundry.Core/Cofoundry.Core.csproj b/src/Cofoundry.Core/Cofoundry.Core.csproj index 04b99d555..31bc21656 100644 --- a/src/Cofoundry.Core/Cofoundry.Core.csproj +++ b/src/Cofoundry.Core/Cofoundry.Core.csproj @@ -8,11 +8,11 @@ - + - + diff --git a/src/Cofoundry.Core/Core/Extensions/ICollectionExtensions.cs b/src/Cofoundry.Core/Core/Extensions/ICollectionExtensions.cs deleted file mode 100644 index eb87a926a..000000000 --- a/src/Cofoundry.Core/Core/Extensions/ICollectionExtensions.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace Cofoundry.Core; - -public static class ICollectionExtensions -{ - /// - /// Removes from the target collection all elements that match the specified predicate. - /// - /// The type of elements in the target collection. - /// The target collection. - /// Optional predicate used to match elements. - /// - /// The target collection is a null reference. - ///
-or-
- /// The match predicate is a null reference. - ///
- /// Returns the number of elements removed. - public static int RemoveAll(this ICollection collection, Predicate? predicate = null) - { - ArgumentNullException.ThrowIfNull(collection); - - var count = 0; - - for (var i = collection.Count - 1; i >= 0; i--) - { - var el = collection.ElementAt(i); - if (predicate == null || predicate(el)) - { - collection.Remove(el); - count++; - } - } - - return count; - } -} diff --git a/src/Cofoundry.Core/Core/Extensions/IDictionaryExtensions.cs b/src/Cofoundry.Core/Core/Extensions/IDictionaryExtensions.cs index b8b3557b9..6ccc77f01 100644 --- a/src/Cofoundry.Core/Core/Extensions/IDictionaryExtensions.cs +++ b/src/Cofoundry.Core/Core/Extensions/IDictionaryExtensions.cs @@ -1,122 +1,126 @@ namespace Cofoundry.Core; +/// +/// Extension methods for types. +/// public static class IDictionaryExtensions { - /// - /// Returns items in the dictionary which has a key listed in the - /// collection. The method ensures no duplicates are returned even if they appear in the - /// collection. - /// - /// The dictionary to filter - /// Keys to lookup values for - public static IEnumerable FilterByKeys(this Dictionary source, IEnumerable keysToFilter) - where TKey : notnull + extension(Dictionary source) where TKey : notnull { - return source.FilterAndOrderByKeys(keysToFilter.Distinct()); - } - - /// - /// Returns items in the dictionary which has a key listed in the - /// collection. The method ensures no duplicates are returned even if they appear in the - /// collection. - /// - /// The dictionary to filter - /// Keys to lookup values for - public static IEnumerable FilterByKeys(this IDictionary source, IEnumerable keysToFilter) - { - return source.FilterAndOrderByKeys(keysToFilter.Distinct()); - } - - /// - /// Returns items in the dictionary which has a key listed in the - /// collection. The method ensures no duplicates are returned even if they appear in the - /// collection. - /// - /// The dictionary to filter - /// Keys to lookup values for - public static IEnumerable FilterByKeys(this IReadOnlyDictionary source, IEnumerable keysToFilter) - { - return source.FilterAndOrderByKeys(keysToFilter.Distinct()); - } - - /// - /// Returns items in the dictionary which has a key listed in the - /// collection, in the order they appear in that collection. Duplicates may be returned if - /// the ordered keys collections contains them. - /// - /// The dictionary to filter - /// - /// A collection of dictionary keys in the order that you would like the results - /// return in. Duplicate items may be returned if the orderedKeys collection - /// contains duplicates. - /// - public static IEnumerable FilterAndOrderByKeys(this Dictionary source, IEnumerable orderedKeys) - where TKey : notnull - { - if (orderedKeys == null) + /// + /// Returns items in the dictionary which has a key listed in the + /// collection. The method ensures no duplicates are returned even if they appear in the + /// collection. + /// + /// Keys to lookup values for + public IEnumerable FilterByKeys(IEnumerable keysToFilter) { - yield break; + return source.FilterAndOrderByKeys(keysToFilter.Distinct()); } - foreach (var key in orderedKeys) + /// + /// Returns items in the dictionary which has a key listed in the + /// collection, in the order they appear in that collection. Duplicates may be returned if + /// the ordered keys collections contains them. + /// + /// + /// A collection of dictionary keys in the order that you would like the results + /// return in. Duplicate items may be returned if the orderedKeys collection + /// contains duplicates. + /// + public IEnumerable FilterAndOrderByKeys(IEnumerable orderedKeys) { - if (source.TryGetValue(key, out var value)) + if (orderedKeys == null) { - yield return value; + yield break; + } + + foreach (var key in orderedKeys) + { + if (source.TryGetValue(key, out var value)) + { + yield return value; + } } } } - /// - /// Returns items in the dictionary which has a key listed in the - /// collection, in the order they appear in that collection. Duplicates may be returned if - /// the ordered keys collections contains them. - /// - /// The dictionary to filter - /// - /// A collection of dictionary keys in the order that you would like the results - /// return in. Duplicate items may be returned if the orderedKeys collection - /// contains duplicates. - /// - public static IEnumerable FilterAndOrderByKeys(this IDictionary source, IEnumerable orderedKeys) + extension(IDictionary source) { - if (orderedKeys == null) + /// + /// Returns items in the dictionary which has a key listed in the + /// collection. The method ensures no duplicates are returned even if they appear in the + /// collection. + /// + /// Keys to lookup values for + public IEnumerable FilterByKeys(IEnumerable keysToFilter) { - yield break; + return source.FilterAndOrderByKeys(keysToFilter.Distinct()); } - foreach (var key in orderedKeys) + /// + /// Returns items in the dictionary which has a key listed in the + /// collection, in the order they appear in that collection. Duplicates may be returned if + /// the ordered keys collections contains them. + /// + /// + /// A collection of dictionary keys in the order that you would like the results + /// return in. Duplicate items may be returned if the orderedKeys collection + /// contains duplicates. + /// + public IEnumerable FilterAndOrderByKeys(IEnumerable orderedKeys) { - if (source.TryGetValue(key, out var value)) + if (orderedKeys == null) { - yield return value; + yield break; + } + + foreach (var key in orderedKeys) + { + if (source.TryGetValue(key, out var value)) + { + yield return value; + } } } } - /// - /// Returns items in the dictionary which has a key listed in the - /// collection, in the order they appear in that collection. Duplicates may be returned if - /// the ordered keys collections contains them. - /// - /// The dictionary to filter - /// - /// A collection of dictionary keys in the order that you would like the results - /// return in. Duplicate items may be returned if the orderedKeys collection - /// contains duplicates. - /// - public static IEnumerable FilterAndOrderByKeys(this IReadOnlyDictionary source, IEnumerable orderedKeys) + extension(IReadOnlyDictionary source) { - if (orderedKeys == null) + /// + /// Returns items in the dictionary which has a key listed in the + /// collection. The method ensures no duplicates are returned even if they appear in the + /// collection. + /// + /// Keys to lookup values for + public IEnumerable FilterByKeys(IEnumerable keysToFilter) { - yield break; + return source.FilterAndOrderByKeys(keysToFilter.Distinct()); } - foreach (var key in orderedKeys) + /// + /// Returns items in the dictionary which has a key listed in the + /// collection, in the order they appear in that collection. Duplicates may be returned if + /// the ordered keys collections contains them. + /// + /// + /// A collection of dictionary keys in the order that you would like the results + /// return in. Duplicate items may be returned if the orderedKeys collection + /// contains duplicates. + /// + public IEnumerable FilterAndOrderByKeys(IEnumerable orderedKeys) { - if (source.TryGetValue(key, out var value)) + if (orderedKeys == null) + { + yield break; + } + + foreach (var key in orderedKeys) { - yield return value; + if (source.TryGetValue(key, out var value)) + { + yield return value; + } } } } diff --git a/src/Cofoundry.Core/Core/Extensions/IEnumerableExtensions.cs b/src/Cofoundry.Core/Core/Extensions/IEnumerableExtensions.cs index 6e9ae970a..fd6d77658 100644 --- a/src/Cofoundry.Core/Core/Extensions/IEnumerableExtensions.cs +++ b/src/Cofoundry.Core/Core/Extensions/IEnumerableExtensions.cs @@ -1,58 +1,57 @@ -namespace Cofoundry.Core; +namespace Cofoundry.Core; +/// +/// Extension methods for . +/// public static class IEnumerableExtensions { - /// - /// Removes nullable entries from the sequence - /// - [Obsolete("Use WhereNotNull instead.")] - public static IEnumerable FilterNotNull(this IEnumerable> source) - where T : struct + extension(IEnumerable source) where T : struct { - return source - .Where(s => s.HasValue) - .Select(s => s!.Value); + /// + /// Removes nullable entries from the sequence. + /// + public IEnumerable WhereNotNull() + { + return source + .Where(s => s != null) + .Cast(); + } } - /// - /// Removes nullable entries from the sequence. - /// - public static IEnumerable WhereNotNull(this IEnumerable> source) - where T : struct + extension(IEnumerable source) { - return source - .Where(s => s != null) - .Cast(); + /// + /// Removes nullable entries from the sequence. + /// + public IEnumerable WhereNotNull() + { + return source + .Where(s => s != null) + .Cast(); + } } - /// - /// Removes nullable entries from the sequence. - /// - public static IEnumerable WhereNotNull(this IEnumerable source) + extension(IEnumerable source) { - return source - .Where(s => s != null) - .Cast(); - } + /// + /// Removes nullable null or empty strings from the sequence. + /// + public IEnumerable WhereNotNullOrEmpty() + { + return source + .Where(s => !string.IsNullOrEmpty(s)) + .Cast(); + } - /// - /// Removes nullable null or empty strings from the sequence. - /// - public static IEnumerable WhereNotNullOrEmpty(this IEnumerable source) - { - return source - .Where(s => !string.IsNullOrEmpty(s)) - .Cast(); - } - - /// - /// Removes nullable null, empty or strings that contain only whitespace - /// from the sequence. - /// - public static IEnumerable WhereNotNullOrWhitespace(this IEnumerable source) - { - return source - .Where(s => !string.IsNullOrWhiteSpace(s)) - .Cast(); + /// + /// Removes nullable null, empty or strings that contain only whitespace + /// from the sequence. + /// + public IEnumerable WhereNotNullOrWhitespace() + { + return source + .Where(s => !string.IsNullOrWhiteSpace(s)) + .Cast(); + } } } diff --git a/src/Cofoundry.Core/Core/Extensions/IListExtensions.cs b/src/Cofoundry.Core/Core/Extensions/IListExtensions.cs deleted file mode 100644 index ccac15522..000000000 --- a/src/Cofoundry.Core/Core/Extensions/IListExtensions.cs +++ /dev/null @@ -1,36 +0,0 @@ -namespace Cofoundry.Core; - -/// -/// Extension methods for classes inherting from IList -/// -public static class IListExtensions -{ - /// - /// Swaps two items in the list - /// - /// Type of item to swap - /// The lsit to swap items in - /// Index of the first item to swap - /// Index of the second item to swap - /// - public static IList Swap(this IList list, int indexA, int indexB) - { - var tmp = list[indexA]; - list[indexA] = list[indexB]; - list[indexB] = tmp; - return list; - } - - /// - /// Adds the value to the list if it is not null, empty or whitespace. - /// - /// List to add the whitespace to - /// The value to add to the list - public static void AddIfNotEmpty(this IList list, string? value) - { - if (!string.IsNullOrWhiteSpace(value)) - { - list.Add(value); - } - } -} diff --git a/src/Cofoundry.Core/Core/Extensions/IQueryableExtensions.cs b/src/Cofoundry.Core/Core/Extensions/IQueryableExtensions.cs index b686fe9cb..114e1efa0 100644 --- a/src/Cofoundry.Core/Core/Extensions/IQueryableExtensions.cs +++ b/src/Cofoundry.Core/Core/Extensions/IQueryableExtensions.cs @@ -1,58 +1,57 @@ namespace Cofoundry.Core; +/// +/// Extension methods for types. +/// public static class IQueryableExtensions { - /// - /// Removes nullable entries from the sequence. - /// - /// - /// Queryable instance to filter. - /// - public static IQueryable WhereNotNull(this IQueryable source) - where T : struct + extension(IQueryable source) where T : struct { - return source - .Where(s => s != null) - .Cast(); + /// + /// Removes nullable entries from the sequence. + /// + public IQueryable WhereNotNull() + { + return source + .Where(s => s != null) + .Cast(); + } } - /// - /// Removes nullable entries from the sequence. - /// - /// - /// Queryable instance to filter. - /// - public static IQueryable WhereNotNull(this IQueryable source) + extension(IQueryable source) { - return source - .Where(s => s != null) - .Cast(); + /// + /// Removes nullable entries from the sequence. + /// + public IQueryable WhereNotNull() + { + return source + .Where(s => s != null) + .Cast(); + } } - /// - /// Removes nullable null or empty strings from the sequence. - /// - /// - /// Queryable instance to filter. - /// - public static IQueryable WhereNotNullOrEmpty(this IQueryable source) + extension(IQueryable source) { - return source - .Where(s => !string.IsNullOrEmpty(s)) - .Cast(); - } + /// + /// Removes nullable null or empty strings from the sequence. + /// + public IQueryable WhereNotNullOrEmpty() + { + return source + .Where(s => !string.IsNullOrEmpty(s)) + .Cast(); + } - /// - /// Removes nullable null, empty or strings that contain only whitespace - /// from the sequence. - /// - /// - /// Queryable instance to filter. - /// - public static IQueryable WhereNotNullOrWhitespace(this IQueryable source) - { - return source - .Where(s => !string.IsNullOrWhiteSpace(s)) - .Cast(); + /// + /// Removes nullable null, empty or strings that contain only whitespace + /// from the sequence. + /// + public IQueryable WhereNotNullOrWhitespace() + { + return source + .Where(s => !string.IsNullOrWhiteSpace(s)) + .Cast(); + } } } diff --git a/src/Cofoundry.Core/Core/Formatters/IEmailAddressNormalizerExtensions.cs b/src/Cofoundry.Core/Core/Formatters/IEmailAddressNormalizerExtensions.cs index 0e998080a..225c63c45 100644 --- a/src/Cofoundry.Core/Core/Formatters/IEmailAddressNormalizerExtensions.cs +++ b/src/Cofoundry.Core/Core/Formatters/IEmailAddressNormalizerExtensions.cs @@ -1,25 +1,28 @@ namespace Cofoundry.Core; +/// +/// Extension methods for . +/// public static class IEmailAddressNormalizerExtensions { - /// - /// Normalizes the specified email address into a consistent - /// format. The default implementation trims the input and lowercases the - /// domain part of the email. If the email is an invalid format then - /// is returned. - /// - /// - /// instance to extend. - /// - /// - /// The email address string to format. If the value is - /// then is returned. - /// - public static string? Normalize(this IEmailAddressNormalizer normalizer, string? emailAddress) + extension(IEmailAddressNormalizer normalizer) { - ArgumentNullException.ThrowIfNull(normalizer); + /// + /// Normalizes the specified email address into a consistent + /// format. The default implementation trims the input and lowercases the + /// domain part of the email. If the email is an invalid format then + /// is returned. + /// + /// + /// The email address string to format. If the value is + /// then is returned. + /// + public string? Normalize(string? emailAddress) + { + ArgumentNullException.ThrowIfNull(normalizer); - var parts = normalizer.NormalizeAsParts(emailAddress); - return parts?.ToEmailAddress(); + var parts = normalizer.NormalizeAsParts(emailAddress); + return parts?.ToEmailAddress(); + } } } diff --git a/src/Cofoundry.Core/Core/Formatters/IEmailAddressUniquifierExtensions.cs b/src/Cofoundry.Core/Core/Formatters/IEmailAddressUniquifierExtensions.cs index ee01fd3ab..1245fe476 100644 --- a/src/Cofoundry.Core/Core/Formatters/IEmailAddressUniquifierExtensions.cs +++ b/src/Cofoundry.Core/Core/Formatters/IEmailAddressUniquifierExtensions.cs @@ -1,54 +1,54 @@ namespace Cofoundry.Core; +/// +/// Extension methods for . +/// public static class IEmailAddressUniquifierExtensions { - /// - /// - /// Format an email address into a value that can be used for - /// uniqueness comparisons. The default implementation simply lowercases - /// the email, but this can be overriden to provide more strict uniqueness - /// checks. - /// - /// - /// As an example, if the user types their email as " L.Balfour+cofoundry@Example.com" then by - /// default the email would normalize via - /// as "L.Balfour+cofoundry@example.com" and uniquify as "l.balfour+cofoundry@example.com", - /// however if you wanted to exclude "plus addressing" from email uniqueness checks, you could - /// override the default implementation with your own - /// custom implementation. - /// - /// - /// - /// instance to extend. - /// - /// - /// The email address to uniquify. If the value is - /// then is returned. - /// - public static string? Uniquify(this IEmailAddressUniquifier uniquifier, string? emailAddress) + extension(IEmailAddressUniquifier uniquifier) { - return uniquifier - .UniquifyAsParts(emailAddress) - ?.ToEmailAddress(); - } + /// + /// + /// Format an email address into a value that can be used for + /// uniqueness comparisons. The default implementation simply lowercases + /// the email, but this can be overriden to provide more strict uniqueness + /// checks. + /// + /// + /// As an example, if the user types their email as " L.Balfour+cofoundry@Example.com" then by + /// default the email would normalize via + /// as "L.Balfour+cofoundry@example.com" and uniquify as "l.balfour+cofoundry@example.com", + /// however if you wanted to exclude "plus addressing" from email uniqueness checks, you could + /// override the default implementation with your own + /// custom implementation. + /// + /// + /// + /// The email address to uniquify. If the value is + /// then is returned. + /// + public string? Uniquify(string? emailAddress) + { + return uniquifier + .UniquifyAsParts(emailAddress) + ?.ToEmailAddress(); + } - /// - /// Format an email address into a value that can be used for - /// uniqueness comparisons. The default implementation simply lowercases - /// the email, but this can be overriden to provide more strict uniqueness - /// checks. - /// - /// - /// instance to extend. - /// - /// - /// The pre-normalized email address to uniquify. If the value is - /// then is returned. - /// - public static string? Uniquify(this IEmailAddressUniquifier uniquifier, NormalizedEmailAddress? emailAddressParts) - { - return uniquifier - .UniquifyAsParts(emailAddressParts) - ?.ToEmailAddress(); + /// + /// Format an email address into a value that can be used for + /// uniqueness comparisons. The default implementation simply lowercases + /// the email, but this can be overriden to provide more strict uniqueness + /// checks. + /// + /// + /// The pre-normalized email address to uniquify. If the value is + /// then is returned. + /// + public string? Uniquify(NormalizedEmailAddress? emailAddressParts) + { + return uniquifier + .UniquifyAsParts(emailAddressParts) + ?.ToEmailAddress(); + } } } diff --git a/src/Cofoundry.Core/Data/SimpleDatabase/ITransactionScopeManagerExtensions.cs b/src/Cofoundry.Core/Data/SimpleDatabase/ITransactionScopeManagerExtensions.cs index df1c8d6bc..a2c7d0180 100644 --- a/src/Cofoundry.Core/Data/SimpleDatabase/ITransactionScopeManagerExtensions.cs +++ b/src/Cofoundry.Core/Data/SimpleDatabase/ITransactionScopeManagerExtensions.cs @@ -1,32 +1,35 @@ namespace Cofoundry.Core.Data.SimpleDatabase; +/// +/// Extension methods for . +/// public static class ITransactionScopeManagerExtensions { - /// - /// Creates a new transaction scope associated with the connection in use by the - /// specified instance. The scope can be nested inside another scope in which - /// case the underlying db transaction is only committed once both the outer - /// and inner transaction(s) have been committed. The returned - /// implements and should be wrapped in a using statement. - /// - /// - /// Source instance to extend. - /// - /// - /// - /// The instance to manage transactions for. Transaction scopes - /// created by this instance only apply to a single DbConnection, so if you want - /// the scope to span multiple instances then they must share the same - /// connection. - /// - /// - /// You can use the to get a reference to the shared - /// connection directly. - /// - /// - /// An instance, which is and must be disposed. - public static ITransactionScope Create(this ITransactionScopeManager transactionScopeManager, IDatabase database) + extension(ITransactionScopeManager transactionScopeManager) { - return transactionScopeManager.Create(database.GetDbConnection()); + /// + /// Creates a new transaction scope associated with the connection in use by the + /// specified instance. The scope can be nested inside another scope in which + /// case the underlying db transaction is only committed once both the outer + /// and inner transaction(s) have been committed. The returned + /// implements and should be wrapped in a using statement. + /// + /// + /// + /// The instance to manage transactions for. Transaction scopes + /// created by this instance only apply to a single DbConnection, so if you want + /// the scope to span multiple instances then they must share the same + /// connection. + /// + /// + /// You can use the to get a reference to the shared + /// connection directly. + /// + /// + /// An instance, which is and must be disposed. + public ITransactionScope Create(IDatabase database) + { + return transactionScopeManager.Create(database.GetDbConnection()); + } } } diff --git a/src/Cofoundry.Core/Data/Transactions/DefaultTransactionScopeManagerExtensions.cs b/src/Cofoundry.Core/Data/Transactions/DefaultTransactionScopeManagerExtensions.cs index 3d64e7870..f4533a5ec 100644 --- a/src/Cofoundry.Core/Data/Transactions/DefaultTransactionScopeManagerExtensions.cs +++ b/src/Cofoundry.Core/Data/Transactions/DefaultTransactionScopeManagerExtensions.cs @@ -10,168 +10,147 @@ namespace Cofoundry.Core.Data.TransactionScopeManager.Default; /// public static class DefaultTransactionScopeManagerExtensions { - /// - /// Creates a new transaction scope associated with the specified connection, - /// using the specified transaction configuration options. - /// The scope can be nested inside another scope in which case the underlying - /// db transaction is only committed once both the outer and inner transaction(s) - /// have been committed. The returned implements - /// and should be wrapped in a using statement. - /// - /// - /// Source instance to extend, which - /// must be of type otherwise an - /// exception will be thrown. - /// - /// - /// - /// The instance to manage transactions for. Transaction scopes - /// created by this instance only apply to a single DbConnection, so if you want - /// the scope to span additional data access mechanism then they must share the - /// same connection. - /// - /// - /// You can use the to get a reference to the shared - /// connection directly. - /// - /// - /// This is defaulted to . - /// This is defaulted to . - /// An instance, which is and must be disposed. - public static ITransactionScope Create( - this ITransactionScopeManager transactionScopeManager, - DbConnection dbConnection, - System.Transactions.TransactionScopeOption transactionScopeOption = System.Transactions.TransactionScopeOption.Required, - System.Transactions.IsolationLevel isolationLevel = System.Transactions.IsolationLevel.ReadCommitted - ) + extension(ITransactionScopeManager transactionScopeManager) { - var defaultTransactionScopeManager = CastDefaultTransactionScopeManager(transactionScopeManager); + /// + /// Creates a new transaction scope associated with the specified connection, + /// using the specified transaction configuration options. + /// The scope can be nested inside another scope in which case the underlying + /// db transaction is only committed once both the outer and inner transaction(s) + /// have been committed. The returned implements + /// and should be wrapped in a using statement. + /// + /// + /// + /// The instance to manage transactions for. Transaction scopes + /// created by this instance only apply to a single DbConnection, so if you want + /// the scope to span additional data access mechanism then they must share the + /// same connection. + /// + /// + /// You can use the to get a reference to the shared + /// connection directly. + /// + /// + /// This is defaulted to . + /// This is defaulted to . + /// An instance, which is and must be disposed. + public ITransactionScope Create( + DbConnection dbConnection, + System.Transactions.TransactionScopeOption transactionScopeOption = System.Transactions.TransactionScopeOption.Required, + System.Transactions.IsolationLevel isolationLevel = System.Transactions.IsolationLevel.ReadCommitted + ) + { + var defaultTransactionScopeManager = CastDefaultTransactionScopeManager(transactionScopeManager); - return defaultTransactionScopeManager.Create(dbConnection, transactionScopeOption, isolationLevel); - } + return defaultTransactionScopeManager.Create(dbConnection, transactionScopeOption, isolationLevel); + } - /// - /// Creates a new transaction scope associated with the specified connection, - /// creating the inner scope using the specified factory method. - /// The scope can be nested inside another scope in which case the underlying - /// db transaction is only committed once both the outer and inner transaction(s) - /// have been committed. The returned implements - /// and should be wrapped in a using statement. - /// - /// - /// Source instance to extend, which - /// must be of type otherwise an - /// exception will be thrown. - /// - /// - /// - /// The instance to manage transactions for. Transaction scopes - /// created by this instance only apply to a single DbConnection, so if you want - /// the scope to span additional data access mechanism then they must share the - /// same connection. - /// - /// - /// You can use the to get a reference to the shared - /// connection directly. - /// - /// - /// - /// Function to use to create and configure a new . - /// - /// An instance, which is and must be disposed. - public static ITransactionScope Create( - this ITransactionScopeManager transactionScopeManager, - DbConnection dbConnection, - Func transactionScopeFactory - ) - { - var defaultTransactionScopeManager = CastDefaultTransactionScopeManager(transactionScopeManager); + /// + /// Creates a new transaction scope associated with the specified connection, + /// creating the inner scope using the specified factory method. + /// The scope can be nested inside another scope in which case the underlying + /// db transaction is only committed once both the outer and inner transaction(s) + /// have been committed. The returned implements + /// and should be wrapped in a using statement. + /// + /// + /// + /// The instance to manage transactions for. Transaction scopes + /// created by this instance only apply to a single DbConnection, so if you want + /// the scope to span additional data access mechanism then they must share the + /// same connection. + /// + /// + /// You can use the to get a reference to the shared + /// connection directly. + /// + /// + /// + /// Function to use to create and configure a new . + /// + /// An instance, which is and must be disposed. + public ITransactionScope Create( + DbConnection dbConnection, + Func transactionScopeFactory + ) + { + var defaultTransactionScopeManager = CastDefaultTransactionScopeManager(transactionScopeManager); - return defaultTransactionScopeManager.Create(dbConnection, transactionScopeFactory); - } + return defaultTransactionScopeManager.Create(dbConnection, transactionScopeFactory); + } - /// - /// Creates a new transaction scope associated with the specified connection, - /// using the specified transaction configuration options. - /// The scope can be nested inside another scope in which case the underlying - /// db transaction is only committed once both the outer and inner transaction(s) - /// have been committed. The returned implements - /// and should be wrapped in a using statement. - /// - /// - /// Source instance to extend, which - /// must be of type otherwise an - /// exception will be thrown. - /// - /// - /// - /// The EF instance to manage transactions for. Transaction scopes - /// created by this instance only apply to a single DbConnection, so if you want - /// the scope to span multiple contexts then they must share the same connection. - /// - /// - /// If you are using multiple EF DbContexts on the Cofoundry database you can make - /// them share the scoped Cofoundry connection by initializing the context with - /// . Alternatively you can use - /// to get a reference to the shared connection - /// directly. - /// - /// - /// This is defaulted to . - /// This is defaulted to . - /// An instance, which is and must be disposed. - public static ITransactionScope Create( - this ITransactionScopeManager transactionScopeManager, - DbContext dbContext, - System.Transactions.TransactionScopeOption transactionScopeOption = System.Transactions.TransactionScopeOption.Required, - System.Transactions.IsolationLevel isolationLevel = System.Transactions.IsolationLevel.ReadCommitted - ) - { - var defaultTransactionScopeManager = CastDefaultTransactionScopeManager(transactionScopeManager); + /// + /// Creates a new transaction scope associated with the specified connection, + /// using the specified transaction configuration options. + /// The scope can be nested inside another scope in which case the underlying + /// db transaction is only committed once both the outer and inner transaction(s) + /// have been committed. The returned implements + /// and should be wrapped in a using statement. + /// + /// + /// + /// The EF instance to manage transactions for. Transaction scopes + /// created by this instance only apply to a single DbConnection, so if you want + /// the scope to span multiple contexts then they must share the same connection. + /// + /// + /// If you are using multiple EF DbContexts on the Cofoundry database you can make + /// them share the scoped Cofoundry connection by initializing the context with + /// . Alternatively you can use + /// to get a reference to the shared connection + /// directly. + /// + /// + /// This is defaulted to . + /// This is defaulted to . + /// An instance, which is and must be disposed. + public ITransactionScope Create( + DbContext dbContext, + System.Transactions.TransactionScopeOption transactionScopeOption = System.Transactions.TransactionScopeOption.Required, + System.Transactions.IsolationLevel isolationLevel = System.Transactions.IsolationLevel.ReadCommitted + ) + { + var defaultTransactionScopeManager = CastDefaultTransactionScopeManager(transactionScopeManager); - return defaultTransactionScopeManager.Create(dbContext, transactionScopeOption, isolationLevel); - } + return defaultTransactionScopeManager.Create(dbContext, transactionScopeOption, isolationLevel); + } - /// - /// Creates a new transaction scope associated with the specified connection, - /// creating the inner scope using the specified factory method. - /// The scope can be nested inside another scope in which case the underlying - /// db transaction is only committed once both the outer and inner transaction(s) - /// have been committed. The returned implements - /// and should be wrapped in a using statement. - /// - /// - /// Source instance to extend, which - /// must be of type otherwise an - /// exception will be thrown. - /// - /// - /// - /// The EF instance to manage transactions for. Transaction scopes - /// created by this instance only apply to a single DbConnection, so if you want - /// the scope to span multiple contexts then they must share the same connection. - /// - /// - /// If you are using multiple EF DbContexts on the Cofoundry database you can make - /// them share the scoped Cofoundry connection by initializing the context with - /// . Alternatively you can use - /// to get a reference to the shared connection - /// directly. - /// - /// - /// - /// Function to use to create and configure a new . - /// - /// An instance, which is and must be disposed. - public static ITransactionScope Create( - this ITransactionScopeManager transactionScopeManager, - DbContext dbContext, - Func transactionScopeFactory - ) - { - var defaultTransactionScopeManager = CastDefaultTransactionScopeManager(transactionScopeManager); + /// + /// Creates a new transaction scope associated with the specified connection, + /// creating the inner scope using the specified factory method. + /// The scope can be nested inside another scope in which case the underlying + /// db transaction is only committed once both the outer and inner transaction(s) + /// have been committed. The returned implements + /// and should be wrapped in a using statement. + /// + /// + /// + /// The EF instance to manage transactions for. Transaction scopes + /// created by this instance only apply to a single DbConnection, so if you want + /// the scope to span multiple contexts then they must share the same connection. + /// + /// + /// If you are using multiple EF DbContexts on the Cofoundry database you can make + /// them share the scoped Cofoundry connection by initializing the context with + /// . Alternatively you can use + /// to get a reference to the shared connection + /// directly. + /// + /// + /// + /// Function to use to create and configure a new . + /// + /// An instance, which is and must be disposed. + public ITransactionScope Create( + DbContext dbContext, + Func transactionScopeFactory + ) + { + var defaultTransactionScopeManager = CastDefaultTransactionScopeManager(transactionScopeManager); - return defaultTransactionScopeManager.Create(dbContext, transactionScopeFactory); + return defaultTransactionScopeManager.Create(dbContext, transactionScopeFactory); + } } private static IDefaultTransactionScopeManager CastDefaultTransactionScopeManager(ITransactionScopeManager transactionScopeManager) diff --git a/src/Cofoundry.Core/DependencyInjection/ContainerSpecificInterfaces/ContainerRegisterExtensions.cs b/src/Cofoundry.Core/DependencyInjection/ContainerSpecificInterfaces/ContainerRegisterExtensions.cs index d03e39765..36beb2b73 100644 --- a/src/Cofoundry.Core/DependencyInjection/ContainerSpecificInterfaces/ContainerRegisterExtensions.cs +++ b/src/Cofoundry.Core/DependencyInjection/ContainerSpecificInterfaces/ContainerRegisterExtensions.cs @@ -1,53 +1,59 @@ -namespace Cofoundry.Core.DependencyInjection; +namespace Cofoundry.Core.DependencyInjection; +/// +/// Extension methods for . +/// public static class ContainerRegisterExtensions { - private static readonly RegistrationOptions SCOPED_OPTIONS = RegistrationOptions.Scoped(); - private static readonly RegistrationOptions SINGLETON_OPTIONS = RegistrationOptions.SingletonScope(); + private static readonly RegistrationOptions _scopedOptions = RegistrationOptions.Scoped(); + private static readonly RegistrationOptions _singletonOptions = RegistrationOptions.SingletonScope(); - /// - /// Registers a service as its concrete type only, using InstanceLifetime.Scoped. - /// - /// Type to register. - /// The IContainerRegister instance for method chaining. - public static IContainerRegister RegisterScoped(this IContainerRegister containerRegister) - where TConcrete : notnull + extension(IContainerRegister containerRegister) { - return containerRegister.Register(SCOPED_OPTIONS); - } + /// + /// Registers a service as its concrete type only, using InstanceLifetime.Scoped. + /// + /// Type to register. + /// The IContainerRegister instance for method chaining. + public IContainerRegister RegisterScoped() + where TConcrete : notnull + { + return containerRegister.Register(_scopedOptions); + } - /// - /// Registers a service using InstanceLifetime.Scoped. - /// - /// Type to register the service as. - /// Concrete type to register. - /// The IContainerRegister instance for method chaining. - public static IContainerRegister RegisterScoped(this IContainerRegister containerRegister) - where TConcrete : notnull, TRegisterAs - { - return containerRegister.Register(SCOPED_OPTIONS); - } + /// + /// Registers a service using InstanceLifetime.Scoped. + /// + /// Type to register the service as. + /// Concrete type to register. + /// The IContainerRegister instance for method chaining. + public IContainerRegister RegisterScoped() + where TConcrete : notnull, TRegisterAs + { + return containerRegister.Register(_scopedOptions); + } - /// - /// Registers a service instance using InstanceLifetime.Singleton. - /// - /// Concrete type to register. - /// The IContainerRegister instance for method chaining. - public static IContainerRegister RegisterSingleton(this IContainerRegister containerRegister) - where TConcrete : notnull - { - return containerRegister.Register(SINGLETON_OPTIONS); - } + /// + /// Registers a service instance using InstanceLifetime.Singleton. + /// + /// Concrete type to register. + /// The IContainerRegister instance for method chaining. + public IContainerRegister RegisterSingleton() + where TConcrete : notnull + { + return containerRegister.Register(_singletonOptions); + } - /// - /// Registers a service instance using InstanceLifetime.Singleton. - /// - /// Type to register the service as. - /// Concrete type to register. - /// The IContainerRegister instance for method chaining. - public static IContainerRegister RegisterSingleton(this IContainerRegister containerRegister) - where TConcrete : notnull, TRegisterAs - { - return containerRegister.Register(SINGLETON_OPTIONS); + /// + /// Registers a service instance using InstanceLifetime.Singleton. + /// + /// Type to register the service as. + /// Concrete type to register. + /// The IContainerRegister instance for method chaining. + public IContainerRegister RegisterSingleton() + where TConcrete : notnull, TRegisterAs + { + return containerRegister.Register(_singletonOptions); + } } } diff --git a/src/Cofoundry.Core/EntityFramework/PropertyBuilderExtensions.cs b/src/Cofoundry.Core/EntityFramework/PropertyBuilderExtensions.cs index 98cfbe52d..04363fc2f 100644 --- a/src/Cofoundry.Core/EntityFramework/PropertyBuilderExtensions.cs +++ b/src/Cofoundry.Core/EntityFramework/PropertyBuilderExtensions.cs @@ -1,72 +1,78 @@ -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; namespace Cofoundry.Core.EntityFramework; +/// +/// Extension methods for . +/// public static class PropertyBuilderExtensions { - /// - /// Defines the property as an MS SqlServer fixed length char type. - /// - /// Type of property being configured. - /// The property builder instance to act on and chain. - /// The fixed length of the char field. - /// Property builder for chaining. - public static PropertyBuilder IsCharType(this PropertyBuilder builder, int length) + extension(PropertyBuilder builder) { - builder - .HasColumnType($"char({ length })") - .HasMaxLength(length) - .IsUnicode(false); + /// + /// Defines the property as an MS SqlServer fixed length char type. + /// + /// The fixed length of the char field. + /// Property builder for chaining. + public PropertyBuilder IsCharType(int length) + { + builder + .HasColumnType($"char({length})") + .HasMaxLength(length) + .IsUnicode(false); - return builder; - } + return builder; + } - /// - /// Defines the property as an MS SqlServer nvarchar(max) field. - /// - /// Type of property being configured. - /// The property builder instance to act on and chain. - /// Property builder for chaining. - public static PropertyBuilder IsNVarCharMaxType(this PropertyBuilder builder) - { - builder - .HasColumnType("nvarchar(max)") - .IsUnicode(); + /// + /// Defines the property as an MS SqlServer nvarchar(max) field. + /// + /// Property builder for chaining. + public PropertyBuilder IsNVarCharMaxType() + { + builder + .HasColumnType("nvarchar(max)") + .IsUnicode(); - return builder; - } + return builder; + } - /// - /// Defines the property as an MS SqlServer varchar(max) field. - /// - /// Type of property being configured. - /// The property builder instance to act on and chain. - /// Property builder for chaining. - public static PropertyBuilder IsVarCharMaxType(this PropertyBuilder builder) - { - builder - .HasColumnType("varchar(max)") - .IsUnicode(false); + /// + /// Defines the property as an MS SqlServer varchar(max) field. + /// + /// Property builder for chaining. + public PropertyBuilder IsVarCharMaxType() + { + builder + .HasColumnType("varchar(max)") + .IsUnicode(false); - return builder; + return builder; + } } - /// - /// Indicates that the field is a UTC , ensuring it is specified as - /// when it is mapped from the database. - /// - public static PropertyBuilder IsUtc(this PropertyBuilder propertyBuilder) + extension(PropertyBuilder propertyBuilder) { - return propertyBuilder.HasConversion(i => i, o => DateTime.SpecifyKind(o, DateTimeKind.Utc)); + /// + /// Indicates that the field is a UTC , ensuring it is specified as + /// when it is mapped from the database. + /// + public PropertyBuilder IsUtc() + { + return propertyBuilder.HasConversion(i => i, o => DateTime.SpecifyKind(o, DateTimeKind.Utc)); + } } - /// - /// Indicates that the field is a UTC , ensuring it is specified as - /// when it is mapped from the database. - /// - public static PropertyBuilder IsUtc(this PropertyBuilder propertyBuilder) + extension(PropertyBuilder propertyBuilder) { - return propertyBuilder.HasConversion(i => i, o => o.HasValue ? DateTime.SpecifyKind(o.Value, DateTimeKind.Utc) : o); + /// + /// Indicates that the field is a UTC , ensuring it is specified as + /// when it is mapped from the database. + /// + public PropertyBuilder IsUtc() + { + return propertyBuilder.HasConversion(i => i, o => o.HasValue ? DateTime.SpecifyKind(o.Value, DateTimeKind.Utc) : o); + } } } diff --git a/src/Cofoundry.Core/Web/AngleSharp/AngleSharpExtensions.cs b/src/Cofoundry.Core/Web/AngleSharp/AngleSharpHelper.cs similarity index 94% rename from src/Cofoundry.Core/Web/AngleSharp/AngleSharpExtensions.cs rename to src/Cofoundry.Core/Web/AngleSharp/AngleSharpHelper.cs index 3f004545b..4d9c650a9 100644 --- a/src/Cofoundry.Core/Web/AngleSharp/AngleSharpExtensions.cs +++ b/src/Cofoundry.Core/Web/AngleSharp/AngleSharpHelper.cs @@ -1,7 +1,10 @@ -using AngleSharp.Dom; +using AngleSharp.Dom; namespace Cofoundry.Core.Web; +/// +/// Helper methods for working with HTML documents via AngleSharp. +/// public static class AngleSharpHelper { /// diff --git a/src/Cofoundry.Domain/Cofoundry.Domain.csproj b/src/Cofoundry.Domain/Cofoundry.Domain.csproj index 1b76b647a..aa10dd335 100644 --- a/src/Cofoundry.Domain/Cofoundry.Domain.csproj +++ b/src/Cofoundry.Domain/Cofoundry.Domain.csproj @@ -12,10 +12,10 @@ - + - + diff --git a/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAsset.cs b/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAsset.cs index 968691377..db9506ed9 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAsset.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAsset.cs @@ -74,12 +74,11 @@ public class DocumentAsset : IUpdateAuditable /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } /// @@ -88,12 +87,11 @@ public User Creator /// public int UpdaterId { get; set; } - private User? _updater; /// public User Updater { - get => _updater ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _updater = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } [Obsolete("The document asset grouping system will be revised in an upcomming release.")] diff --git a/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAssetGroup.cs b/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAssetGroup.cs index 14cd7e0db..392ca7d95 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAssetGroup.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAssetGroup.cs @@ -21,11 +21,10 @@ public class DocumentAssetGroup : ICreateAuditable /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAssetGroupItem.cs b/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAssetGroupItem.cs index 2827e5b6a..84fcca2e1 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAssetGroupItem.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAssetGroupItem.cs @@ -5,20 +5,18 @@ public class DocumentAssetGroupItem : ICreateAuditable { public int DocumentAssetId { get; set; } - private DocumentAsset? _documentAsset; public DocumentAsset DocumentAsset { - get => _documentAsset ?? throw NavigationPropertyNotInitializedException.Create(nameof(DocumentAsset)); - set => _documentAsset = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(DocumentAsset)); + set; } public int DocumentAssetGroupId { get; set; } - private DocumentAssetGroup? _documentAssetGroup; public DocumentAssetGroup DocumentAssetGroup { - get => _documentAssetGroup ?? throw NavigationPropertyNotInitializedException.Create(nameof(DocumentAssetGroup)); - set => _documentAssetGroup = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(DocumentAssetGroup)); + set; } public int Ordering { get; set; } @@ -29,11 +27,10 @@ public DocumentAssetGroup DocumentAssetGroup /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAssetQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAssetQueryExtensions.cs index 86afd3b0f..1b818bf13 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAssetQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAssetQueryExtensions.cs @@ -1,20 +1,29 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class DocumentAssetQueryExtensions { - public static IQueryable FilterById(this IQueryable documents, int id) + extension(IQueryable documents) { - var result = documents - .Where(i => i.DocumentAssetId == id); + public IQueryable FilterById(int id) + { + var result = documents + .Where(i => i.DocumentAssetId == id); - return result; + return result; + } } - public static IQueryable FilterByIds(this IQueryable document, IEnumerable ids) + extension(IQueryable document) { - var result = document - .Where(i => ids.Contains(i.DocumentAssetId)); + public IQueryable FilterByIds(IEnumerable ids) + { + var result = document + .Where(i => ids.Contains(i.DocumentAssetId)); - return result; + return result; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAssetTag.cs b/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAssetTag.cs index 596be57a9..ae3722384 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAssetTag.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Assets/DocumentAssetTag.cs @@ -4,20 +4,18 @@ public class DocumentAssetTag : ICreateAuditable, IEntityTag { public int DocumentAssetId { get; set; } - private DocumentAsset? _documentAsset; public DocumentAsset DocumentAsset { - get => _documentAsset ?? throw NavigationPropertyNotInitializedException.Create(nameof(DocumentAsset)); - set => _documentAsset = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(DocumentAsset)); + set; } public int TagId { get; set; } - private Tag? _tag; public Tag Tag { - get => _tag ?? throw NavigationPropertyNotInitializedException.Create(nameof(Tag)); - set => _tag = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Tag)); + set; } /// @@ -26,11 +24,10 @@ public Tag Tag /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAsset.cs b/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAsset.cs index 396541234..e58c63918 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAsset.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAsset.cs @@ -75,12 +75,11 @@ public class ImageAsset : IUpdateAuditable /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } /// @@ -89,12 +88,11 @@ public User Creator /// public int UpdaterId { get; set; } - private User? _updater; /// public User Updater { - get => _updater ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _updater = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } [Obsolete("The image asset grouping system will be revised in an upcomming release.")] diff --git a/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAssetGroup.cs b/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAssetGroup.cs index 30080a9f5..e66ac990a 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAssetGroup.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAssetGroup.cs @@ -17,12 +17,11 @@ public class ImageAssetGroup : ICreateAuditable /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } public ICollection ImageAssetGroupItems { get; set; } = new List(); diff --git a/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAssetGroupItem.cs b/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAssetGroupItem.cs index d97e3bd08..6e57feeaa 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAssetGroupItem.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAssetGroupItem.cs @@ -5,20 +5,18 @@ public class ImageAssetGroupItem : ICreateAuditable { public int ImageAssetId { get; set; } - private ImageAsset? _imageAsset; public ImageAsset ImageAsset { - get => _imageAsset ?? throw NavigationPropertyNotInitializedException.Create(nameof(ImageAsset)); - set => _imageAsset = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(ImageAsset)); + set; } public int ImageAssetGroupId { get; set; } - private ImageAssetGroup? _imageAssetGroup; public ImageAssetGroup ImageAssetGroup { - get => _imageAssetGroup ?? throw NavigationPropertyNotInitializedException.Create(nameof(ImageAssetGroup)); - set => _imageAssetGroup = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(ImageAssetGroup)); + set; } public int Ordering { get; set; } @@ -29,11 +27,10 @@ public ImageAssetGroup ImageAssetGroup /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAssetQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAssetQueryExtensions.cs index 07fdc8b5d..8b4b10685 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAssetQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAssetQueryExtensions.cs @@ -1,20 +1,26 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class ImageAssetQueryExtensions { - public static IQueryable FilterById(this IQueryable images, int id) + extension(IQueryable images) { - var result = images - .Where(i => i.ImageAssetId == id); + public IQueryable FilterById(int id) + { + var result = images + .Where(i => i.ImageAssetId == id); - return result; - } + return result; + } - public static IQueryable FilterByIds(this IQueryable images, IEnumerable ids) - { - var result = images - .Where(i => ids.Contains(i.ImageAssetId)); + public IQueryable FilterByIds(IEnumerable ids) + { + var result = images + .Where(i => ids.Contains(i.ImageAssetId)); - return result; + return result; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAssetTag.cs b/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAssetTag.cs index d487df700..06ffeb869 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAssetTag.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Assets/ImageAssetTag.cs @@ -4,20 +4,18 @@ public class ImageAssetTag : IEntityTag, ICreateAuditable { public int ImageAssetId { get; set; } - private ImageAsset? _imageAsset; public ImageAsset ImageAsset { - get => _imageAsset ?? throw NavigationPropertyNotInitializedException.Create(nameof(ImageAsset)); - set => _imageAsset = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(ImageAsset)); + set; } public int TagId { get; set; } - private Tag? _tag; public Tag Tag { - get => _tag ?? throw NavigationPropertyNotInitializedException.Create(nameof(Tag)); - set => _tag = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Tag)); + set; } /// @@ -26,11 +24,10 @@ public Tag Tag /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } } diff --git a/src/Cofoundry.Domain/Data/DbContext/AuthorizedTasks/AuthorizedTask.cs b/src/Cofoundry.Domain/Data/DbContext/AuthorizedTasks/AuthorizedTask.cs index 0e77afbba..0518bb9f7 100644 --- a/src/Cofoundry.Domain/Data/DbContext/AuthorizedTasks/AuthorizedTask.cs +++ b/src/Cofoundry.Domain/Data/DbContext/AuthorizedTasks/AuthorizedTask.cs @@ -28,15 +28,14 @@ public class AuthorizedTask /// public int UserId { get; set; } - private User? _user; /// /// The user associated with the task e.g. for an acount recovery task this /// is the user account being recovered. /// public User User { - get => _user ?? throw NavigationPropertyNotInitializedException.Create(nameof(User)); - set => _user = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(User)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/CofoundryDbContext.cs b/src/Cofoundry.Domain/Data/DbContext/CofoundryDbContext.cs index 4c921d28f..38cd3f4fb 100644 --- a/src/Cofoundry.Domain/Data/DbContext/CofoundryDbContext.cs +++ b/src/Cofoundry.Domain/Data/DbContext/CofoundryDbContext.cs @@ -12,9 +12,7 @@ public partial class CofoundryDbContext : DbContext { private readonly ICofoundryDbContextInitializer _cofoundryDbContextInitializer; - public CofoundryDbContext( - ICofoundryDbContextInitializer cofoundryDbContextInitializer - ) + public CofoundryDbContext(ICofoundryDbContextInitializer cofoundryDbContextInitializer) { _cofoundryDbContextInitializer = cofoundryDbContextInitializer; } @@ -30,8 +28,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasDefaultSchema(DbConstants.CofoundrySchema) .MapCofoundryContent() .ApplyConfiguration(new SettingMap()) - .ApplyConfiguration(new RewriteRuleMap()) - ; + .ApplyConfiguration(new RewriteRuleMap()); } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntity.cs b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntity.cs index a10b64c31..a1be8c0e7 100644 --- a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntity.cs +++ b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntity.cs @@ -1,4 +1,4 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; /// /// @@ -27,14 +27,13 @@ public class CustomEntity : ICreateAuditable, IEntityPublishable /// public string CustomEntityDefinitionCode { get; set; } = string.Empty; - private CustomEntityDefinition? _customEntityDefinition; /// /// Definition representing the type of custom entity. /// public CustomEntityDefinition CustomEntityDefinition { - get => _customEntityDefinition ?? throw NavigationPropertyNotInitializedException.Create(nameof(CustomEntityDefinition)); - set => _customEntityDefinition = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(CustomEntityDefinition)); + set; } /// @@ -78,12 +77,11 @@ public CustomEntityDefinition CustomEntityDefinition /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityDefinition.cs b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityDefinition.cs index 3954e3744..21f23a1f5 100644 --- a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityDefinition.cs +++ b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityDefinition.cs @@ -1,4 +1,4 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; /// /// @@ -47,10 +47,9 @@ public class CustomEntityDefinition /// public bool HasLocale { get; set; } - private EntityDefinition? _entityDefinition; public EntityDefinition EntityDefinition { - get => _entityDefinition ?? throw NavigationPropertyNotInitializedException.Create(nameof(EntityDefinition)); - set => _entityDefinition = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(EntityDefinition)); + set; } } diff --git a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityDefinitionQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityDefinitionQueryExtensions.cs index c814fbe72..a882a5d78 100644 --- a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityDefinitionQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityDefinitionQueryExtensions.cs @@ -1,12 +1,18 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class CustomEntityDefinitionQueryExtensions { - public static IQueryable FilterByCode(this IQueryable customEntityDefinitions, string code) + extension(IQueryable customEntityDefinitions) { - var result = customEntityDefinitions - .Where(i => i.CustomEntityDefinitionCode == code); + public IQueryable FilterByCode(string code) + { + var result = customEntityDefinitions + .Where(i => i.CustomEntityDefinitionCode == code); - return result; + return result; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityPublishStatusQuery.cs b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityPublishStatusQuery.cs index cfa3aff3f..18051c4be 100644 --- a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityPublishStatusQuery.cs +++ b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityPublishStatusQuery.cs @@ -25,25 +25,23 @@ public class CustomEntityPublishStatusQuery /// public int CustomEntityVersionId { get; set; } - private CustomEntity? _customEntity; /// /// Custom entity that this record represents. /// public CustomEntity CustomEntity { - get => _customEntity ?? throw NavigationPropertyNotInitializedException.Create(nameof(CustomEntity)); - set => _customEntity = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(CustomEntity)); + set; } - private CustomEntityVersion? _customEntityVersion; /// /// The version of the custom entity that should be displayed /// for the corresponding PublishStatusQueryId. /// public CustomEntityVersion CustomEntityVersion { - get => _customEntityVersion ?? throw NavigationPropertyNotInitializedException.Create(nameof(CustomEntityVersion)); - set => _customEntityVersion = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(CustomEntityVersion)); + set; } } diff --git a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityPublishStatusQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityPublishStatusQueryExtensions.cs index 5df50d297..c2ddaa3c3 100644 --- a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityPublishStatusQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityPublishStatusQueryExtensions.cs @@ -1,192 +1,185 @@ namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class CustomEntityPublishStatusQueryExtensions { - /// - /// Filters the results by the publish status query type. - /// - /// - /// Queryable instance to extend. - /// - /// - /// Query status to filter by. If the value is PublishStatusQuery.Published then additional filtering by publish date will be applied. - /// - /// - /// UTC execution date of the query. This is used to compare the publish date. - /// - public static IQueryable FilterByStatus(this IQueryable source, PublishStatusQuery statusQuery, DateTime executionDate) + extension(IQueryable source) { - if (statusQuery == PublishStatusQuery.SpecificVersion) + /// + /// Filters the results by the publish status query type. + /// + /// + /// Query status to filter by. If the value is PublishStatusQuery.Published then additional filtering by publish date will be applied. + /// + /// + /// UTC execution date of the query. This is used to compare the publish date. + /// + public IQueryable FilterByStatus(PublishStatusQuery statusQuery, DateTime executionDate) { - throw new Exception("Cannot filter by PublishStatusQuery.SpecificVersion using the FilterByStatus extension method."); - } + if (statusQuery == PublishStatusQuery.SpecificVersion) + { + throw new Exception("Cannot filter by PublishStatusQuery.SpecificVersion using the FilterByStatus extension method."); + } - IQueryable filtered; + IQueryable filtered; - if (statusQuery == PublishStatusQuery.Published) - { - filtered = source - .Where(p => p.PublishStatusQueryId == (short)statusQuery && p.CustomEntity.PublishDate <= executionDate); - } - else - { - filtered = source - .Where(p => p.PublishStatusQueryId == (short)statusQuery); - } + if (statusQuery == PublishStatusQuery.Published) + { + filtered = source + .Where(p => p.PublishStatusQueryId == (short)statusQuery && p.CustomEntity.PublishDate <= executionDate); + } + else + { + filtered = source + .Where(p => p.PublishStatusQueryId == (short)statusQuery); + } - return filtered; - } + return filtered; + } - /// - /// Removes any custom entities from the query that are inactive (attached to an inactive locale). - /// - /// - /// Queryable instance to extend. - /// - public static IQueryable FilterActive(this IQueryable customEntities) - { - var result = customEntities - .Where(e => e.CustomEntity.LocaleId == null || e.CustomEntity.Locale!.IsActive); + /// + /// Filters the collection to only include records associated with + /// the specified CustomEntityId. + /// + /// Database id of the entity to filter by. + public IQueryable FilterByCustomEntityId(int customEntityId) + { + var filtered = source + .Where(e => e.CustomEntityId == customEntityId); - return result; + return filtered; + } } - /// - /// Filters the collection to only include records associated with - /// the specified CustomEntityId. - /// - /// - /// Queryable instance to extend. - /// - /// Database id of the entity to filter by. - public static IQueryable FilterByCustomEntityId(this IQueryable source, int customEntityId) + extension(IQueryable customEntities) { - var filtered = source - .Where(e => e.CustomEntityId == customEntityId); + /// + /// Removes any custom entities from the query that are inactive (attached to an inactive locale). + /// + public IQueryable FilterActive() + { + var result = customEntities + .Where(e => e.CustomEntity.LocaleId == null || e.CustomEntity.Locale!.IsActive); - return filtered; - } + return result; + } - /// - /// Filters the collection to only include records associated with - /// the specified custom entity UrlSlug. - /// - /// - /// Queryable instance to extend. - /// - /// Url slug of the custom entity record to filter by. - public static IQueryable FilterByCustomEntityUrlSlug(this IQueryable customEntities, string urlSlug) - { - var result = customEntities - .Where(e => e.CustomEntity.UrlSlug == urlSlug); + /// + /// Filters the collection to only include records associated with + /// the specified custom entity UrlSlug. + /// + /// Url slug of the custom entity record to filter by. + public IQueryable FilterByCustomEntityUrlSlug(string urlSlug) + { + var result = customEntities + .Where(e => e.CustomEntity.UrlSlug == urlSlug); - return result; - } + return result; + } - /// - /// Fitlers the results to only include custom entities of a specific type. - /// - /// - /// Queryable instance to extend. - /// - /// Unique definition code of the custom entity type to filter by. - public static IQueryable FilterByCustomEntityDefinitionCode(this IQueryable customEntities, string customEntityDefinitionCode) - { - var result = customEntities - .Where(e => e.CustomEntity.CustomEntityDefinitionCode == customEntityDefinitionCode); + /// + /// Fitlers the results to only include custom entities of a specific type. + /// + /// Unique definition code of the custom entity type to filter by. + public IQueryable FilterByCustomEntityDefinitionCode(string customEntityDefinitionCode) + { + var result = customEntities + .Where(e => e.CustomEntity.CustomEntityDefinitionCode == customEntityDefinitionCode); - return result; + return result; + } } - /// - /// Applies the specified sorting to the query, taking into account - /// the any default sorting settings on the custom entity definition. - /// - /// Query to sort. - /// - /// The definition for the entity being sorted. This may contain default - /// sorting settings that will be applied if CustomEntityQuerySortType.Default - /// is specified. - /// - /// The sort type to apply. - /// - /// An optional sort direction, falling back to the default - /// if not specified. - /// - public static IOrderedQueryable SortBy( - this IQueryable dbQuery, - ICustomEntityDefinition customEntityDefinition, - CustomEntityQuerySortType sortType, - SortDirection? optionalSortDirection = null - ) + extension(IQueryable dbQuery) { - IOrderedQueryable result; + /// + /// Applies the specified sorting to the query, taking into account + /// the any default sorting settings on the custom entity definition. + /// + /// + /// The definition for the entity being sorted. This may contain default + /// sorting settings that will be applied if CustomEntityQuerySortType.Default + /// is specified. + /// + /// The sort type to apply. + /// + /// An optional sort direction, falling back to the default + /// if not specified. + /// + public IOrderedQueryable SortBy( + ICustomEntityDefinition customEntityDefinition, + CustomEntityQuerySortType sortType, + SortDirection? optionalSortDirection = null) + { + IOrderedQueryable result; - var sortDirection = optionalSortDirection ?? SortDirection.Default; + var sortDirection = optionalSortDirection ?? SortDirection.Default; - if (sortType == CustomEntityQuerySortType.Default - && customEntityDefinition is ISortedCustomEntityDefinition sortedDefinition - && !(customEntityDefinition is IOrderableCustomEntityDefinition)) - { - sortType = sortedDefinition.DefaultSortType; - if (!optionalSortDirection.HasValue) + if (sortType == CustomEntityQuerySortType.Default + && customEntityDefinition is ISortedCustomEntityDefinition sortedDefinition + && !(customEntityDefinition is IOrderableCustomEntityDefinition)) { - sortDirection = sortedDefinition.DefaultSortDirection; - } - } - - switch (sortType) - { - case CustomEntityQuerySortType.Default: - case CustomEntityQuerySortType.Natural: - if (UseOrderableSort(customEntityDefinition)) + sortType = sortedDefinition.DefaultSortType; + if (!optionalSortDirection.HasValue) { - result = SortByOrdering(dbQuery, sortDirection, customEntityDefinition); + sortDirection = sortedDefinition.DefaultSortDirection; } - else - { + } + + switch (sortType) + { + case CustomEntityQuerySortType.Default: + case CustomEntityQuerySortType.Natural: + if (UseOrderableSort(customEntityDefinition)) + { + result = SortByOrdering(dbQuery, sortDirection, customEntityDefinition); + } + else + { + result = dbQuery + .OrderByWithSortDirection(e => e.CustomEntityVersion.Title, sortDirection); + } + break; + case CustomEntityQuerySortType.Locale: + + if (UseOrderableSort(customEntityDefinition)) + { + result = SortByOrdering(dbQuery, sortDirection, customEntityDefinition); + } + else + { + result = dbQuery + .OrderByWithSortDirection(e => e.CustomEntity.Locale!.IETFLanguageTag, sortDirection) + .ThenByWithSortDirection(e => e.CustomEntityVersion.Title, sortDirection); + } + break; + case CustomEntityQuerySortType.Title: result = dbQuery .OrderByWithSortDirection(e => e.CustomEntityVersion.Title, sortDirection); - } - break; - case CustomEntityQuerySortType.Locale: - - if (UseOrderableSort(customEntityDefinition)) - { - result = SortByOrdering(dbQuery, sortDirection, customEntityDefinition); - } - else - { + break; + case CustomEntityQuerySortType.CreateDate: result = dbQuery - .OrderByWithSortDirection(e => e.CustomEntity.Locale!.IETFLanguageTag, sortDirection) - .ThenByWithSortDirection(e => e.CustomEntityVersion.Title, sortDirection); - } - break; - case CustomEntityQuerySortType.Title: - result = dbQuery - .OrderByWithSortDirection(e => e.CustomEntityVersion.Title, sortDirection); - break; - case CustomEntityQuerySortType.CreateDate: - result = dbQuery - .OrderByDescendingWithSortDirection(e => e.CustomEntity.CreateDate, sortDirection); - break; - case CustomEntityQuerySortType.PublishDate: - result = dbQuery - .OrderByDescendingWithSortDirection(e => e.CustomEntity.PublishDate ?? e.CustomEntityVersion.CreateDate, sortDirection) - ; - break; - default: - throw new Exception($"{nameof(CustomEntityQuerySortType)} not recognised: {sortType}"); - } + .OrderByDescendingWithSortDirection(e => e.CustomEntity.CreateDate, sortDirection); + break; + case CustomEntityQuerySortType.PublishDate: + result = dbQuery + .OrderByDescendingWithSortDirection(e => e.CustomEntity.PublishDate ?? e.CustomEntityVersion.CreateDate, sortDirection) + ; + break; + default: + throw new Exception($"{nameof(CustomEntityQuerySortType)} not recognised: {sortType}"); + } - return result; + return result; + } } private static IOrderedQueryable SortByOrdering( IQueryable dbQuery, SortDirection sortDirection, - ICustomEntityDefinition definition - ) + ICustomEntityDefinition definition) { var primarySorted = dbQuery diff --git a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityQueryExtensions.cs index 2dcddc0de..38170703a 100644 --- a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityQueryExtensions.cs @@ -1,12 +1,17 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class CustomEntityExtensions { - public static IQueryable FilterByCustomEntityId(this IQueryable customEntities, int customEntityId) + extension(IQueryable customEntities) { - var result = customEntities - .Where(i => i.CustomEntityId == customEntityId); + public IQueryable FilterByCustomEntityId(int customEntityId) + { + var result = customEntities.Where(i => i.CustomEntityId == customEntityId); - return result; + return result; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityVersion.cs b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityVersion.cs index d27c2777b..2f77de17f 100644 --- a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityVersion.cs +++ b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityVersion.cs @@ -1,4 +1,4 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; /// /// @@ -59,7 +59,6 @@ public class CustomEntityVersion : ICreateAuditable, IEntityVersion /// public string SerializedData { get; set; } = string.Empty; - private CustomEntity? _customEntity; /// /// The custom entity this version is parented to. /// Custom entities can have many versions, but only one is @@ -67,8 +66,8 @@ public class CustomEntityVersion : ICreateAuditable, IEntityVersion /// public CustomEntity CustomEntity { - get => _customEntity ?? throw NavigationPropertyNotInitializedException.Create(nameof(CustomEntity)); - set => _customEntity = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(CustomEntity)); + set; } /// @@ -77,12 +76,11 @@ public CustomEntity CustomEntity /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityVersionPageBlock.cs b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityVersionPageBlock.cs index cdc119028..9de394cbd 100644 --- a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityVersionPageBlock.cs +++ b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityVersionPageBlock.cs @@ -1,4 +1,4 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; /// /// Page block data for a specific custom entity version on a custom entity @@ -57,18 +57,16 @@ public class CustomEntityVersionPageBlock : IEntityOrderable, IEntityVersionPage /// public int Ordering { get; set; } - private CustomEntityVersion? _customEntityVersion; /// /// The custom entity version that this instance is /// parented to. /// public CustomEntityVersion CustomEntityVersion { - get => _customEntityVersion ?? throw NavigationPropertyNotInitializedException.Create(nameof(CustomEntityVersion)); - set => _customEntityVersion = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(CustomEntityVersion)); + set; } - private Page? _page; /// /// It's unlikely but there can be multiple pages using the same /// template for a custom entity type, so a page reference is required @@ -76,21 +74,19 @@ public CustomEntityVersion CustomEntityVersion /// public Page Page { - get => _page ?? throw NavigationPropertyNotInitializedException.Create(nameof(Page)); - set => _page = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Page)); + set; } - private PageTemplateRegion? _pageTemplateRegion; /// /// The template region this block belongs to. /// public PageTemplateRegion PageTemplateRegion { - get => _pageTemplateRegion ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageTemplateRegion)); - set => _pageTemplateRegion = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageTemplateRegion)); + set; } - private PageBlockType? _pageBlockType; /// /// The block type which defines the data model and display /// templates available to render the block e.g. 'Image', @@ -98,8 +94,8 @@ public PageTemplateRegion PageTemplateRegion /// public PageBlockType PageBlockType { - get => _pageBlockType ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageBlockType)); - set => _pageBlockType = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageBlockType)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityVersionPageBlockQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityVersionPageBlockQueryExtensions.cs index 3316af19e..890177b6b 100644 --- a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityVersionPageBlockQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityVersionPageBlockQueryExtensions.cs @@ -1,15 +1,21 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class CustomEntityVersionPageBlockQueryExtensions { - /// - /// Filters the collection to only include blocks that - /// have not been archived. - /// - public static IQueryable FilterActive(this IQueryable pages) + extension(IQueryable pages) { - var filtered = pages.Where(p => !p.PageBlockType.IsArchived); + /// + /// Filters the collection to only include blocks that + /// have not been archived. + /// + public IQueryable FilterActive() + { + var filtered = pages.Where(p => !p.PageBlockType.IsArchived); - return filtered; + return filtered; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityVersionQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityVersionQueryExtensions.cs index 07bdc00fd..338de85fd 100644 --- a/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityVersionQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/CustomEntities/CustomEntityVersionQueryExtensions.cs @@ -1,88 +1,79 @@ namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class CustomEntityVersionQueryExtensions { - /// - /// Filters the collection to only include records associated with - /// the specified CustomEntityId. - /// - /// - /// Queryable instance to filter. - /// - /// Database id of the entity to filter by. - public static IQueryable FilterByCustomEntityId(this IQueryable customEntities, int customEntityId) + extension(IQueryable customEntities) { - var result = customEntities - .Where(e => e.CustomEntityId == customEntityId); + /// + /// Filters the collection to only include records associated with + /// the specified CustomEntityId. + /// + /// Database id of the entity to filter by. + public IQueryable FilterByCustomEntityId(int customEntityId) + { + var result = customEntities + .Where(e => e.CustomEntityId == customEntityId); - return result; - } + return result; + } - /// - /// Filters the collection to only include records associated with - /// the specified custom entity UrlSlug. - /// - /// - /// Queryable instance to filter. - /// - /// Url slug of the custom entity record to filter by. - public static IQueryable FilterByCustomEntityUrlSlug(this IQueryable customEntities, string urlSlug) - { - var result = customEntities - .Where(e => e.CustomEntity.UrlSlug == urlSlug); + /// + /// Filters the collection to only include records associated with + /// the specified custom entity UrlSlug. + /// + /// Url slug of the custom entity record to filter by. + public IQueryable FilterByCustomEntityUrlSlug(string urlSlug) + { + var result = customEntities + .Where(e => e.CustomEntity.UrlSlug == urlSlug); - return result; - } + return result; + } - /// - /// Filters the collection to only include the version with the specific Id - /// - /// - /// Queryable instance to filter. - /// - /// Database id of the version to filter by. - public static IQueryable FilterByCustomEntityVersionId(this IQueryable customEntities, int customEntityVersionId) - { - var result = customEntities - .Where(e => e.CustomEntityVersionId == customEntityVersionId); + /// + /// Filters the collection to only include the version with the specific Id + /// + /// Database id of the version to filter by. + public IQueryable FilterByCustomEntityVersionId(int customEntityVersionId) + { + var result = customEntities + .Where(e => e.CustomEntityVersionId == customEntityVersionId); - return result; - } + return result; + } - /// - /// Fitlers the results to only include custom entities of a specific type. - /// - /// - /// Queryable instance to filter. - /// - /// Unique definition code of the custom entity type to filter by. - public static IQueryable FilterByCustomEntityDefinitionCode(this IQueryable customEntities, string customEntityDefinitionCode) - { - var result = customEntities - .Where(e => e.CustomEntity.CustomEntityDefinitionCode == customEntityDefinitionCode); + /// + /// Fitlers the results to only include custom entities of a specific type. + /// + /// Unique definition code of the custom entity type to filter by. + public IQueryable FilterByCustomEntityDefinitionCode(string customEntityDefinitionCode) + { + var result = customEntities + .Where(e => e.CustomEntity.CustomEntityDefinitionCode == customEntityDefinitionCode); - return result; - } + return result; + } - /// - /// Removes any custom entities from the query that are inactive (attached to an inactive locale). - /// - /// - /// Queryable instance to filter. - /// - public static IQueryable FilterActive(this IQueryable customEntities) - { - var result = customEntities - .Where(e => e.CustomEntity.LocaleId == null || e.CustomEntity.Locale!.IsActive); + /// + /// Removes any custom entities from the query that are inactive (attached to an inactive locale). + /// + public IQueryable FilterActive() + { + var result = customEntities + .Where(e => e.CustomEntity.LocaleId == null || e.CustomEntity.Locale!.IsActive); - return result; - } + return result; + } - public static IQueryable FilterByLocale(this IQueryable customEntities, int? localeId) - { - var result = customEntities - .Where(e => e.CustomEntity.LocaleId == localeId); + public IQueryable FilterByLocale(int? localeId) + { + var result = customEntities + .Where(e => e.CustomEntity.LocaleId == localeId); - return result; + return result; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/DbModelBuilderExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/DbModelBuilderExtensions.cs index 89f74c661..0c2701518 100644 --- a/src/Cofoundry.Domain/Data/DbContext/DbModelBuilderExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/DbModelBuilderExtensions.cs @@ -1,4 +1,4 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; /// /// Extend DbModelBuilder to reduce boilerplate code when @@ -6,143 +6,144 @@ /// public static class DbModelBuilderExtensions { - /// - /// - /// Makes the "app" schema as the default. "app" is the recommended - /// schema to use for any custom tables you add to the database, keeping - /// them separate from Cofoundry tables and any other tables created - /// by 3rd parties. - /// - /// - /// This schema can also be references with DbConstants.DefaultAppSchema - /// - /// - /// DbModelBuilder for method chaining. - public static ModelBuilder HasAppSchema(this ModelBuilder modelBuilder) + extension(ModelBuilder modelBuilder) { - return modelBuilder.HasDefaultSchema(DbConstants.DefaultAppSchema); - } + /// + /// + /// Makes the "app" schema as the default. "app" is the recommended + /// schema to use for any custom tables you add to the database, keeping + /// them separate from Cofoundry tables and any other tables created + /// by 3rd parties. + /// + /// + /// This schema can also be references with DbConstants.DefaultAppSchema + /// + /// + /// DbModelBuilder for method chaining. + public ModelBuilder HasAppSchema() + { + return modelBuilder.HasDefaultSchema(DbConstants.DefaultAppSchema); + } - /// - /// Maps Cofoundry ImageAsset classes to the DbModelBuilder. Requires Cofoundry Users and Tags to be mapped. - /// - /// DbModelBuilder for method chaining. - public static ModelBuilder MapCofoundryImageAssets(this ModelBuilder modelBuilder) - { - modelBuilder - .ApplyConfiguration(new ImageAssetMap()) + /// + /// Maps Cofoundry ImageAsset classes to the DbModelBuilder. Requires Cofoundry Users and Tags to be mapped. + /// + /// DbModelBuilder for method chaining. + public ModelBuilder MapCofoundryImageAssets() + { + modelBuilder + .ApplyConfiguration(new ImageAssetMap()) #pragma warning disable CS0618 // Type or member is obsolete - .ApplyConfiguration(new ImageAssetGroupMap()) - .ApplyConfiguration(new ImageAssetGroupItemMap()) + .ApplyConfiguration(new ImageAssetGroupMap()) + .ApplyConfiguration(new ImageAssetGroupItemMap()) #pragma warning restore CS0618 // Type or member is obsolete - .ApplyConfiguration(new ImageAssetTagMap()); + .ApplyConfiguration(new ImageAssetTagMap()); - return modelBuilder; - } + return modelBuilder; + } - /// - /// Maps Cofoundry DocumentAsset classes to the DbModelBuilder. Requires Cofoundry Users and Tags to be mapped. - /// - /// DbModelBuilder for method chaining - public static ModelBuilder MapCofoundryDocumentAssets(this ModelBuilder modelBuilder) - { - modelBuilder - .ApplyConfiguration(new DocumentAssetMap()) + /// + /// Maps Cofoundry DocumentAsset classes to the DbModelBuilder. Requires Cofoundry Users and Tags to be mapped. + /// + /// DbModelBuilder for method chaining + public ModelBuilder MapCofoundryDocumentAssets() + { + modelBuilder + .ApplyConfiguration(new DocumentAssetMap()) #pragma warning disable CS0618 // Type or member is obsolete - .ApplyConfiguration(new DocumentAssetGroupMap()) - .ApplyConfiguration(new DocumentAssetGroupItemMap()) + .ApplyConfiguration(new DocumentAssetGroupMap()) + .ApplyConfiguration(new DocumentAssetGroupItemMap()) #pragma warning restore CS0618 // Type or member is obsolete - .ApplyConfiguration(new DocumentAssetTagMap()); + .ApplyConfiguration(new DocumentAssetTagMap()); - return modelBuilder; - } + return modelBuilder; + } - /// - /// Maps Cofoundry Users classes to the DbModelBuilder - /// - /// DbModelBuilder for method chaining - public static ModelBuilder MapCofoundryUsers(this ModelBuilder modelBuilder) - { - modelBuilder - .ApplyConfiguration(new IPAddressMap()) - .ApplyConfiguration(new AuthorizedTaskMap()) - .ApplyConfiguration(new EmailDomainMap()) - .ApplyConfiguration(new UserMap()) - .ApplyConfiguration(new UserAuthenticationLogMap()) - .ApplyConfiguration(new UserAuthenticationFailLogMap()) - .ApplyConfiguration(new UserAreaMap()) - .ApplyConfiguration(new RoleMap()) - .ApplyConfiguration(new PermissionMap()) - .ApplyConfiguration(new RolePermissionMap()) - ; + /// + /// Maps Cofoundry Users classes to the DbModelBuilder + /// + /// DbModelBuilder for method chaining + public ModelBuilder MapCofoundryUsers() + { + modelBuilder + .ApplyConfiguration(new IPAddressMap()) + .ApplyConfiguration(new AuthorizedTaskMap()) + .ApplyConfiguration(new EmailDomainMap()) + .ApplyConfiguration(new UserMap()) + .ApplyConfiguration(new UserAuthenticationLogMap()) + .ApplyConfiguration(new UserAuthenticationFailLogMap()) + .ApplyConfiguration(new UserAreaMap()) + .ApplyConfiguration(new RoleMap()) + .ApplyConfiguration(new PermissionMap()) + .ApplyConfiguration(new RolePermissionMap()); - return modelBuilder; - } + return modelBuilder; + } - /// - /// Maps Cofoundry Users classes to the DbModelBuilder - /// - /// DbModelBuilder for method chaining - public static ModelBuilder MapCofoundryTags(this ModelBuilder modelBuilder) - { - modelBuilder.ApplyConfiguration(new TagMap()); + /// + /// Maps Cofoundry Users classes to the DbModelBuilder + /// + /// DbModelBuilder for method chaining + public ModelBuilder MapCofoundryTags() + { + modelBuilder.ApplyConfiguration(new TagMap()); - return modelBuilder; - } + return modelBuilder; + } - /// - /// Maps Cofoundry locales classes to the DbModelBuilder - /// - /// DbModelBuilder for method chaining - public static ModelBuilder MapCofoundryLocales(this ModelBuilder modelBuilder) - { - modelBuilder.ApplyConfiguration(new LocaleMap()); + /// + /// Maps Cofoundry locales classes to the DbModelBuilder + /// + /// DbModelBuilder for method chaining + public ModelBuilder MapCofoundryLocales() + { + modelBuilder.ApplyConfiguration(new LocaleMap()); - return modelBuilder; - } + return modelBuilder; + } - /// - /// Maps Cofoundry page, custom entities, images and all dependency classes - /// to the DbModelBuilder. - /// - /// DbModelBuilder for method chaining - public static ModelBuilder MapCofoundryContent(this ModelBuilder modelBuilder) - { - modelBuilder - .MapCofoundryLocales() - .MapCofoundryUsers() - .MapCofoundryTags() - .MapCofoundryImageAssets() - .MapCofoundryDocumentAssets() - .ApplyConfiguration(new AssetFileCleanupQueueItemMap()) - .ApplyConfiguration(new CustomEntityVersionPageBlockMap()) - .ApplyConfiguration(new PageTemplateMap()) - .ApplyConfiguration(new PageTemplateRegionMap()) - .ApplyConfiguration(new PageBlockTypeTemplateMap()) - .ApplyConfiguration(new PageBlockTypeMap()) + /// + /// Maps Cofoundry page, custom entities, images and all dependency classes + /// to the DbModelBuilder. + /// + /// DbModelBuilder for method chaining + public ModelBuilder MapCofoundryContent() + { + modelBuilder + .MapCofoundryLocales() + .MapCofoundryUsers() + .MapCofoundryTags() + .MapCofoundryImageAssets() + .MapCofoundryDocumentAssets() + .ApplyConfiguration(new AssetFileCleanupQueueItemMap()) + .ApplyConfiguration(new CustomEntityVersionPageBlockMap()) + .ApplyConfiguration(new PageTemplateMap()) + .ApplyConfiguration(new PageTemplateRegionMap()) + .ApplyConfiguration(new PageBlockTypeTemplateMap()) + .ApplyConfiguration(new PageBlockTypeMap()) #pragma warning disable CS0618 // Type or member is obsolete - .ApplyConfiguration(new PageGroupItemMap()) - .ApplyConfiguration(new PageGroupMap()) + .ApplyConfiguration(new PageGroupItemMap()) + .ApplyConfiguration(new PageGroupMap()) #pragma warning restore CS0618 // Type or member is obsolete - .ApplyConfiguration(new PageVersionBlockMap()) - .ApplyConfiguration(new PageMap()) - .ApplyConfiguration(new PageAccessRuleMap()) - .ApplyConfiguration(new PagePublishStatusQueryMap()) - .ApplyConfiguration(new PageTagMap()) - .ApplyConfiguration(new PageVersionMap()) - .ApplyConfiguration(new PageDirectoryMap()) - .ApplyConfiguration(new PageDirectoryPathMap()) - .ApplyConfiguration(new PageDirectoryClosureMap()) - .ApplyConfiguration(new PageDirectoryAccessRuleMap()) - .ApplyConfiguration(new PageDirectoryLocaleMap()) - .ApplyConfiguration(new EntityDefinitionMap()) - .ApplyConfiguration(new UnstructuredDataDependencyMap()) - .ApplyConfiguration(new CustomEntityDefinitionMap()) - .ApplyConfiguration(new CustomEntityMap()) - .ApplyConfiguration(new CustomEntityPublishStatusQueryMap()) - .ApplyConfiguration(new CustomEntityVersionMap()) - ; + .ApplyConfiguration(new PageVersionBlockMap()) + .ApplyConfiguration(new PageMap()) + .ApplyConfiguration(new PageAccessRuleMap()) + .ApplyConfiguration(new PagePublishStatusQueryMap()) + .ApplyConfiguration(new PageTagMap()) + .ApplyConfiguration(new PageVersionMap()) + .ApplyConfiguration(new PageDirectoryMap()) + .ApplyConfiguration(new PageDirectoryPathMap()) + .ApplyConfiguration(new PageDirectoryClosureMap()) + .ApplyConfiguration(new PageDirectoryAccessRuleMap()) + .ApplyConfiguration(new PageDirectoryLocaleMap()) + .ApplyConfiguration(new EntityDefinitionMap()) + .ApplyConfiguration(new UnstructuredDataDependencyMap()) + .ApplyConfiguration(new CustomEntityDefinitionMap()) + .ApplyConfiguration(new CustomEntityMap()) + .ApplyConfiguration(new CustomEntityPublishStatusQueryMap()) + .ApplyConfiguration(new CustomEntityVersionMap()); - return modelBuilder; + return modelBuilder; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Entities/UnstructuredDataDependency.cs b/src/Cofoundry.Domain/Data/DbContext/Entities/UnstructuredDataDependency.cs index 8c07f007e..cdcaffa60 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Entities/UnstructuredDataDependency.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Entities/UnstructuredDataDependency.cs @@ -1,4 +1,4 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; /// /// Contains a record of a relation between one entitiy and another @@ -14,7 +14,6 @@ public class UnstructuredDataDependency /// public string RootEntityDefinitionCode { get; set; } = string.Empty; - private EntityDefinition? _rootEntityDefinition; /// /// The entity definition for the root entity. The root entity is the main entity record /// e.g. if an image is used in a custom entity data model, the image is the root entity @@ -22,8 +21,8 @@ public class UnstructuredDataDependency /// public EntityDefinition RootEntityDefinition { - get => _rootEntityDefinition ?? throw NavigationPropertyNotInitializedException.Create(nameof(RootEntityDefinition)); - set => _rootEntityDefinition = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(RootEntityDefinition)); + set; } /// @@ -42,7 +41,6 @@ public EntityDefinition RootEntityDefinition /// public string RelatedEntityDefinitionCode { get; set; } = string.Empty; - private EntityDefinition? _relatedEntityDefinition; /// /// The entity definition the root is entity is related to. The related entity /// is the entity that contains a property that references the root entity e.g. if an image @@ -51,8 +49,8 @@ public EntityDefinition RootEntityDefinition /// public EntityDefinition RelatedEntityDefinition { - get => _relatedEntityDefinition ?? throw NavigationPropertyNotInitializedException.Create(nameof(EntityDefinition)); - set => _relatedEntityDefinition = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(EntityDefinition)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/Entities/UnstructuredDataDependencyQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Entities/UnstructuredDataDependencyQueryExtensions.cs index f2e8ac770..4db1fd605 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Entities/UnstructuredDataDependencyQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Entities/UnstructuredDataDependencyQueryExtensions.cs @@ -1,100 +1,103 @@ namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class UnstructuredDataDependencyExtensions { - /// - /// Filters the collection to only include dependencies related to the specified - /// root entity i.e. the entity itself which may contain references to other entities. - /// - /// Collection to filter. - /// - /// 6 character identifier of the root entity type to filter to. - /// - /// Database id of the root entity to filter on. - public static IQueryable FilterByRootEntity(this IQueryable dependencies, string rootEntityEntityDefinitionCode, int rootEntityId) + extension(IQueryable dependencies) { - var filtered = dependencies.Where(d => d.RootEntityDefinitionCode == rootEntityEntityDefinitionCode && d.RootEntityId == rootEntityId); + /// + /// Filters the collection to only include dependencies related to the specified + /// root entity i.e. the entity itself which may contain references to other entities. + /// + /// + /// 6 character identifier of the root entity type to filter to. + /// + /// Database id of the root entity to filter on. + public IQueryable FilterByRootEntity(string rootEntityEntityDefinitionCode, int rootEntityId) + { + var filtered = dependencies.Where(d => d.RootEntityDefinitionCode == rootEntityEntityDefinitionCode && d.RootEntityId == rootEntityId); - return filtered; - } + return filtered; + } - /// - /// Filters the collection to only include dependencies related to the specified - /// root entity i.e. the entity itself which may contain references to other entities. - /// - /// Collection to filter. - /// - /// 6 character identifier of the root entity type to filter to. - /// - /// Database id of the root entity to filter on. - public static IEnumerable FilterByRootEntity(this IEnumerable dependencies, string rootEntityEntityDefinitionCode, int rootEntityId) - { - var filtered = dependencies.Where(d => d.RootEntityDefinitionCode == rootEntityEntityDefinitionCode && d.RootEntityId == rootEntityId); + /// + /// Filters the collection to only include dependencies where the specified + /// entity is the relation i.e. the entities it is assigned to in data properties. + /// + /// + /// 6 character identifier of the related entity type to filter to. + /// + /// Database id of the related entity to filter on. + public IQueryable FilterByRelatedEntity(string relatedEntityEntityDefinitionCode, int relatedEntityId) + { + var filtered = dependencies.Where(d => d.RelatedEntityDefinitionCode == relatedEntityEntityDefinitionCode && d.RelatedEntityId == relatedEntityId); - return filtered; - } + return filtered; + } - /// - /// Filters the collection to only include dependencies where the specified - /// entity is the relation i.e. the entities it is assigned to in data properties. - /// - /// Collection to filter. - /// - /// 6 character identifier of the related entity type to filter to. - /// - /// Database id of the related entity to filter on. - public static IQueryable FilterByRelatedEntity(this IQueryable dependencies, string relatedEntityEntityDefinitionCode, int relatedEntityId) - { - var filtered = dependencies.Where(d => d.RelatedEntityDefinitionCode == relatedEntityEntityDefinitionCode && d.RelatedEntityId == relatedEntityId); + /// + /// Filters the collection to only include dependencies where the specified + /// entities are the relation i.e. the entities it is assigned to in data properties. + /// + /// + /// 6 character identifier of the related entity type to filter to. + /// + /// Database ids of the related entities to filter on. + public IQueryable FilterByRelatedEntity(string relatedEntityEntityDefinitionCode, IEnumerable relatedEntityIds) + { + var filtered = dependencies.Where(d => d.RelatedEntityDefinitionCode == relatedEntityEntityDefinitionCode && relatedEntityIds.Contains(d.RelatedEntityId)); - return filtered; + return filtered; + } } - /// - /// Filters the collection to only include dependencies where the specified - /// entity is the relation i.e. the entities it is assigned to in data properties. - /// - /// Collection to filter. - /// - /// 6 character identifier of the related entity type to filter to. - /// - /// Database id of the related entity to filter on. - public static IEnumerable FilterByRelatedEntity(this IEnumerable dependencies, string relatedEntityEntityDefinitionCode, int relatedEntityId) + extension(IEnumerable dependencies) { - var filtered = dependencies.Where(d => d.RelatedEntityDefinitionCode == relatedEntityEntityDefinitionCode && d.RelatedEntityId == relatedEntityId); + /// + /// Filters the collection to only include dependencies related to the specified + /// root entity i.e. the entity itself which may contain references to other entities. + /// + /// + /// 6 character identifier of the root entity type to filter to. + /// + /// Database id of the root entity to filter on. + public IEnumerable FilterByRootEntity(string rootEntityEntityDefinitionCode, int rootEntityId) + { + var filtered = dependencies.Where(d => d.RootEntityDefinitionCode == rootEntityEntityDefinitionCode && d.RootEntityId == rootEntityId); - return filtered; - } + return filtered; + } - /// - /// Filters the collection to only include dependencies where the specified - /// entities are the relation i.e. the entities it is assigned to in data properties. - /// - /// Collection to filter. - /// - /// 6 character identifier of the related entity type to filter to. - /// - /// Database ids of the related entities to filter on. - public static IQueryable FilterByRelatedEntity(this IQueryable dependencies, string relatedEntityEntityDefinitionCode, IEnumerable relatedEntityIds) - { - var filtered = dependencies.Where(d => d.RelatedEntityDefinitionCode == relatedEntityEntityDefinitionCode && relatedEntityIds.Contains(d.RelatedEntityId)); + /// + /// Filters the collection to only include dependencies where the specified + /// entity is the relation i.e. the entities it is assigned to in data properties. + /// + /// + /// 6 character identifier of the related entity type to filter to. + /// + /// Database id of the related entity to filter on. + public IEnumerable FilterByRelatedEntity(string relatedEntityEntityDefinitionCode, int relatedEntityId) + { + var filtered = dependencies.Where(d => d.RelatedEntityDefinitionCode == relatedEntityEntityDefinitionCode && d.RelatedEntityId == relatedEntityId); - return filtered; - } + return filtered; + } - /// - /// Filters the collection to only include dependencies where the specified - /// entities are the relation i.e. the entities it is assigned to in data properties. - /// - /// Collection to filter. - /// - /// 6 character identifier of the related entity type to filter to. - /// - /// Database ids of the related entities to filter on. - public static IEnumerable FilterByRelatedEntity(this IEnumerable dependencies, string relatedEntityEntityDefinitionCode, IEnumerable relatedEntityIds) - { - var filtered = dependencies.Where(d => d.RelatedEntityDefinitionCode == relatedEntityEntityDefinitionCode && relatedEntityIds.Contains(d.RelatedEntityId)); + /// + /// Filters the collection to only include dependencies where the specified + /// entities are the relation i.e. the entities it is assigned to in data properties. + /// + /// + /// 6 character identifier of the related entity type to filter to. + /// + /// Database ids of the related entities to filter on. + public IEnumerable FilterByRelatedEntity(string relatedEntityEntityDefinitionCode, IEnumerable relatedEntityIds) + { + var filtered = dependencies.Where(d => d.RelatedEntityDefinitionCode == relatedEntityEntityDefinitionCode && relatedEntityIds.Contains(d.RelatedEntityId)); - return filtered; + return filtered; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/PageTemplates/PageTemplateQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/PageTemplates/PageTemplateQueryExtensions.cs index 1c6dec99d..c671556e8 100644 --- a/src/Cofoundry.Domain/Data/DbContext/PageTemplates/PageTemplateQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/PageTemplates/PageTemplateQueryExtensions.cs @@ -1,34 +1,34 @@ namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class PageTemplateQueryExtensions { - /// - /// Fitlers the collection to only include templates with the - /// specified id. - /// - /// - /// Queryable instance to filter. - /// - /// PageTemplateId to filter by. - public static IQueryable FilterByPageTemplateId(this IQueryable pageTemplates, int pageTemplateId) + extension(IQueryable pageTemplates) { - var result = pageTemplates - .Where(i => i.PageTemplateId == pageTemplateId); + /// + /// Fitlers the collection to only include templates with the + /// specified id. + /// + /// PageTemplateId to filter by. + public IQueryable FilterByPageTemplateId(int pageTemplateId) + { + var result = pageTemplates + .Where(i => i.PageTemplateId == pageTemplateId); - return result; - } + return result; + } - /// - /// Filters the collection to only include templates that are - /// not archived. - /// - /// - /// Queryable instance to filter. - /// - public static IQueryable FilterActive(this IQueryable pageTemplates) - { - var filtered = pageTemplates.Where(p => !p.IsArchived); + /// + /// Filters the collection to only include templates that are + /// not archived. + /// + public IQueryable FilterActive() + { + var filtered = pageTemplates.Where(p => !p.IsArchived); - return filtered; + return filtered; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/PageTemplates/PageTemplateRegion.cs b/src/Cofoundry.Domain/Data/DbContext/PageTemplates/PageTemplateRegion.cs index 99eede6a2..dcdafc4a7 100644 --- a/src/Cofoundry.Domain/Data/DbContext/PageTemplates/PageTemplateRegion.cs +++ b/src/Cofoundry.Domain/Data/DbContext/PageTemplates/PageTemplateRegion.cs @@ -18,14 +18,13 @@ public class PageTemplateRegion /// public int PageTemplateId { get; set; } - private PageTemplate? _pageTemplate; /// /// The page tmeplate this region is parented to /// public PageTemplate PageTemplate { - get => _pageTemplate ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageTemplate)); - set => _pageTemplate = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageTemplate)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/Page.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/Page.cs index 8b85df332..d83d272f2 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/Page.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/Page.cs @@ -19,14 +19,13 @@ public class Page : IEntityAccessRestrictable, ICreateAuditable, /// public int PageDirectoryId { get; set; } - private PageDirectory? _pageDirectory; /// /// The this page is in. /// public PageDirectory PageDirectory { - get => _pageDirectory ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageDirectory)); - set => _pageDirectory = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageDirectory)); + set; } /// @@ -89,12 +88,11 @@ public PageDirectory PageDirectory /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } [Obsolete("The page grouping system will be revised in an upcomming release.")] diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageAccessRule.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageAccessRule.cs index 034077d4c..72a9e5256 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageAccessRule.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageAccessRule.cs @@ -1,4 +1,4 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; /// /// @@ -25,25 +25,23 @@ public class PageAccessRule : IEntityAccessRule /// public int PageId { get; set; } - private Page? _page; /// /// that this rule controls access to. /// public Page Page { - get => _page ?? throw NavigationPropertyNotInitializedException.Create(nameof(Page)); - set => _page = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Page)); + set; } /// public string UserAreaCode { get; set; } = string.Empty; - private UserArea? _userArea; /// public UserArea UserArea { - get => _userArea ?? throw NavigationPropertyNotInitializedException.Create(nameof(UserArea)); - set => _userArea = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(UserArea)); + set; } /// @@ -58,12 +56,11 @@ public UserArea UserArea /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageAccessRuleQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageAccessRuleQueryExtensions.cs index 4e69c3063..0d71bf8dd 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageAccessRuleQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageAccessRuleQueryExtensions.cs @@ -1,19 +1,22 @@ namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class PageAccessRuleQueryExtensions { - /// - /// Filters the collection to only include access rules associated with - /// a specific page. - /// - /// - /// Queryable instance to filter. - /// - /// Id of the to filter on. - public static IQueryable FilterByPageId(this IQueryable pageAccessRules, int pageId) + extension(IQueryable pageAccessRules) { - var filtered = pageAccessRules.Where(p => p.PageId == pageId); + /// + /// Filters the collection to only include access rules associated with + /// a specific page. + /// + /// Id of the to filter on. + public IQueryable FilterByPageId(int pageId) + { + var filtered = pageAccessRules.Where(p => p.PageId == pageId); - return filtered; + return filtered; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageBlockTypeQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageBlockTypeQueryExtensions.cs index 85cdc2d11..3bd36106f 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageBlockTypeQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageBlockTypeQueryExtensions.cs @@ -1,15 +1,21 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class PageBlockTypeQueryExtensions { - /// - /// Filters the collection to only include block types that - /// have not been archived. - /// - public static IQueryable FilterActive(this IQueryable pages) + extension(IQueryable pages) { - var filtered = pages.Where(p => !p.IsArchived); + /// + /// Filters the collection to only include block types that + /// have not been archived. + /// + public IQueryable FilterActive() + { + var filtered = pages.Where(p => !p.IsArchived); - return filtered; + return filtered; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageBlockTypeTemplate.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageBlockTypeTemplate.cs index 0499f507d..6be5b2b6f 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageBlockTypeTemplate.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageBlockTypeTemplate.cs @@ -18,15 +18,14 @@ public class PageBlockTypeTemplate /// public int PageBlockTypeId { get; set; } - private PageBlockType? _pageBlockType; /// /// The block type this template belongs to. One block type can /// 0 or more templates. /// public PageBlockType PageBlockType { - get => _pageBlockType ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageBlockType)); - set => _pageBlockType = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageBlockType)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectory.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectory.cs index 7d4da7407..55304fed8 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectory.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectory.cs @@ -49,12 +49,11 @@ public class PageDirectory : IEntityAccessRestrictable, /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } /// @@ -103,7 +102,6 @@ public User Creator /// public ICollection DescendantPageDirectories { get; set; } = new List(); - private PageDirectoryPath? _pageDirectoryPath; /// /// Information about the full directory path and it's position in the directory /// heirachy. This table is automatically updated whenever changes are made to the page @@ -111,8 +109,8 @@ public User Creator /// public PageDirectoryPath PageDirectoryPath { - get => _pageDirectoryPath ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageDirectoryPath)); - set => _pageDirectoryPath = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageDirectoryPath)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryAccessRule.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryAccessRule.cs index 6cf8856eb..d682c3f75 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryAccessRule.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryAccessRule.cs @@ -1,4 +1,4 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; /// /// @@ -26,26 +26,24 @@ public class PageDirectoryAccessRule : IEntityAccessRule /// public int PageDirectoryId { get; set; } - private PageDirectory? _pageDirectory; /// /// that this rule controls access to, /// as well as any child directories or pages. /// public PageDirectory PageDirectory { - get => _pageDirectory ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageDirectory)); - set => _pageDirectory = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageDirectory)); + set; } /// public string UserAreaCode { get; set; } = string.Empty; - private UserArea? _userArea; /// public UserArea UserArea { - get => _userArea ?? throw NavigationPropertyNotInitializedException.Create(nameof(UserArea)); - set => _userArea = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(UserArea)); + set; } /// @@ -60,12 +58,11 @@ public UserArea UserArea /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryAccessRuleQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryAccessRuleQueryExtensions.cs index d63354b17..b31526db7 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryAccessRuleQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryAccessRuleQueryExtensions.cs @@ -1,34 +1,34 @@ namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class PageDirectoryAccessRuleQueryExtensions { - /// - /// Filters the collection to only include the access rule with the - /// specified PageDirectoryAccessRuleId primary key. - /// - /// - /// Queryable instance to filter. - /// - /// Primary key to filter on. - public static IQueryable FilterById(this IQueryable accessRules, int pageDirectoryAccessRuleId) + extension(IQueryable accessRules) { - var filtered = accessRules.Where(p => p.PageDirectoryAccessRuleId == pageDirectoryAccessRuleId); + /// + /// Filters the collection to only include the access rule with the + /// specified PageDirectoryAccessRuleId primary key. + /// + /// Primary key to filter on. + public IQueryable FilterById(int pageDirectoryAccessRuleId) + { + var filtered = accessRules.Where(p => p.PageDirectoryAccessRuleId == pageDirectoryAccessRuleId); - return filtered; - } + return filtered; + } - /// - /// Filters the collection to only include access rules associated with - /// a specific directory. - /// - /// - /// Queryable instance to filter. - /// - /// Id of the to filter on. - public static IQueryable FilterByPageDirectoryId(this IQueryable accessRules, int pageDirectoryId) - { - var filtered = accessRules.Where(p => p.PageDirectoryId == pageDirectoryId); + /// + /// Filters the collection to only include access rules associated with + /// a specific directory. + /// + /// Id of the to filter on. + public IQueryable FilterByPageDirectoryId(int pageDirectoryId) + { + var filtered = accessRules.Where(p => p.PageDirectoryId == pageDirectoryId); - return filtered; + return filtered; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryClosure.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryClosure.cs index 37527baea..bd0e95f3a 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryClosure.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryClosure.cs @@ -20,7 +20,6 @@ public class PageDirectoryClosure /// public int AncestorPageDirectoryId { get; set; } - private PageDirectory? _ancestorPageDirectory; /// /// The page directory that is an ancestor of . /// The table includes a self-referencing node, so this can also be the same as @@ -28,8 +27,8 @@ public class PageDirectoryClosure /// public PageDirectory AncestorPageDirectory { - get => _ancestorPageDirectory ?? throw NavigationPropertyNotInitializedException.Create(nameof(AncestorPageDirectory)); - set => _ancestorPageDirectory = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(AncestorPageDirectory)); + set; } /// @@ -39,7 +38,6 @@ public PageDirectory AncestorPageDirectory /// public int DescendantPageDirectoryId { get; set; } - private PageDirectory? _descendantPageDirectory; /// /// The page directory that is a descendant of . /// The table includes a self-referencing node, so this can also be the same as @@ -47,8 +45,8 @@ public PageDirectory AncestorPageDirectory /// public PageDirectory DescendantPageDirectory { - get => _descendantPageDirectory ?? throw NavigationPropertyNotInitializedException.Create(nameof(DescendantPageDirectory)); - set => _descendantPageDirectory = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(DescendantPageDirectory)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryClosureQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryClosureQueryExtensions.cs index 529a746f1..faa5d3201 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryClosureQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryClosureQueryExtensions.cs @@ -1,120 +1,105 @@ namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class PageDirectoryClosureQueryExtensions { - /// - /// Fitlers the collection based on the on the DescendantPageDirectoryId - /// field i.e. this will only return the self-referencing record and - /// ancestors of the specified directory. - /// - /// - /// Queryable instance to filter. - /// - /// PageDirectoryId to filter by on the DescendantPageDirectoryId field. - public static IQueryable FilterByDescendantId(this IQueryable closures, int pageDirectoryId) + extension(IQueryable closures) { - var result = closures.Where(i => i.DescendantPageDirectoryId == pageDirectoryId); - - return result; - } - - /// - /// Fitlers the collection based on the on the DescendantPageDirectoryId - /// field i.e. this will only return the self-referencing record and - /// ancestors of the specified directory. - /// - /// - /// Enumerable to filter. - /// - /// PageDirectoryId to filter by on the DescendantPageDirectoryId field. - public static IEnumerable FilterByDescendantId(this IEnumerable closures, int pageDirectoryId) - { - var result = closures.Where(i => i.DescendantPageDirectoryId == pageDirectoryId); - - return result; - } - - /// - /// Fitlers the collection based on the on the AncestorPageDirectoryId - /// field i.e. this will only return the self-referencing record and - /// decendants of the specified directory. - /// - /// - /// Queryable instance to filter. - /// - /// PageDirectoryId to filter by on the AncestorPageDirectoryId field. - public static IQueryable FilterByAncestorId(this IQueryable closures, int pageDirectoryId) - { - var result = closures.Where(i => i.AncestorPageDirectoryId == pageDirectoryId); - - return result; - } - - /// - /// Fitlers the collection based on the on the AncestorPageDirectoryId - /// field i.e. this will only return the self-referencing record and - /// decendants of the specified directory. - /// - /// - /// Enumerable to filter. - /// - /// PageDirectoryId to filter by on the AncestorPageDirectoryId field. - public static IEnumerable FilterByAncestorId(this IEnumerable closures, int pageDirectoryId) - { - var result = closures.Where(i => i.AncestorPageDirectoryId == pageDirectoryId); - - return result; + /// + /// Fitlers the collection based on the on the DescendantPageDirectoryId + /// field i.e. this will only return the self-referencing record and + /// ancestors of the specified directory. + /// + /// PageDirectoryId to filter by on the DescendantPageDirectoryId field. + public IQueryable FilterByDescendantId(int pageDirectoryId) + { + var result = closures.Where(i => i.DescendantPageDirectoryId == pageDirectoryId); + + return result; + } + + /// + /// Fitlers the collection based on the on the AncestorPageDirectoryId + /// field i.e. this will only return the self-referencing record and + /// decendants of the specified directory. + /// + /// PageDirectoryId to filter by on the AncestorPageDirectoryId field. + public IQueryable FilterByAncestorId(int pageDirectoryId) + { + var result = closures.Where(i => i.AncestorPageDirectoryId == pageDirectoryId); + + return result; + } + + /// + /// Filters to include only the self-referencing records, where the ancestor and descenent are the same. + /// + public IQueryable FilterSelfReferencing() + { + var result = closures.Where(i => i.AncestorPageDirectoryId == i.DescendantPageDirectoryId); + + return result; + } + + /// + /// Removes the self-referencing records, where the ancestor and descendant are the same. + /// + public IQueryable FilterNotSelfReferencing() + { + var result = closures.Where(i => i.AncestorPageDirectoryId != i.DescendantPageDirectoryId); + + return result; + } } - /// - /// Filters to include only the self-referencing records, where the ancestor and descenent are the same. - /// - /// - /// Queryable instance to filter. - /// - public static IQueryable FilterSelfReferencing(this IQueryable closures) + extension(IEnumerable closures) { - var result = closures.Where(i => i.AncestorPageDirectoryId == i.DescendantPageDirectoryId); - - return result; - } - - /// - /// Filters to include only the self-referencing records, where the ancestor and descenent are the same. - /// - /// - /// Enumerable to filter. - /// - public static IEnumerable FilterSelfReferencing(this IEnumerable closures) - { - var result = closures.Where(i => i.AncestorPageDirectoryId == i.DescendantPageDirectoryId); - - return result; - } - - /// - /// Removes the self-referencing records, where the ancestor and descendant are the same. - /// - /// - /// Queryable instance to filter. - /// - public static IQueryable FilterNotSelfReferencing(this IQueryable closures) - { - var result = closures.Where(i => i.AncestorPageDirectoryId != i.DescendantPageDirectoryId); - - return result; - } - - /// - /// Removes the self-referencing records, where the ancestor and descendant are the same. - /// - /// - /// Enumerable to filter. - /// - public static IEnumerable FilterNotSelfReferencing(this IEnumerable closures) - { - var result = closures.Where(i => i.AncestorPageDirectoryId != i.DescendantPageDirectoryId); - - return result; + /// + /// Fitlers the collection based on the on the DescendantPageDirectoryId + /// field i.e. this will only return the self-referencing record and + /// ancestors of the specified directory. + /// + /// PageDirectoryId to filter by on the DescendantPageDirectoryId field. + public IEnumerable FilterByDescendantId(int pageDirectoryId) + { + var result = closures.Where(i => i.DescendantPageDirectoryId == pageDirectoryId); + + return result; + } + + /// + /// Fitlers the collection based on the on the AncestorPageDirectoryId + /// field i.e. this will only return the self-referencing record and + /// decendants of the specified directory. + /// + /// PageDirectoryId to filter by on the AncestorPageDirectoryId field. + public IEnumerable FilterByAncestorId(int pageDirectoryId) + { + var result = closures.Where(i => i.AncestorPageDirectoryId == pageDirectoryId); + + return result; + } + + /// + /// Filters to include only the self-referencing records, where the ancestor and descenent are the same. + /// + public IEnumerable FilterSelfReferencing() + { + var result = closures.Where(i => i.AncestorPageDirectoryId == i.DescendantPageDirectoryId); + + return result; + } + + /// + /// Removes the self-referencing records, where the ancestor and descendant are the same. + /// + public IEnumerable FilterNotSelfReferencing() + { + var result = closures.Where(i => i.AncestorPageDirectoryId != i.DescendantPageDirectoryId); + + return result; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryLocale.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryLocale.cs index 8bf2b422c..f8ef9f751 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryLocale.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryLocale.cs @@ -6,20 +6,18 @@ public class PageDirectoryLocale : ICreateAuditable public int PageDirectoryId { get; set; } - private PageDirectory? _pageDirectory; public PageDirectory PageDirectory { - get => _pageDirectory ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _pageDirectory = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } public int LocaleId { get; set; } - private Locale? _locale; public Locale Locale { - get => _locale ?? throw NavigationPropertyNotInitializedException.Create(nameof(Locale)); - set => _locale = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Locale)); + set; } public string UrlPath { get; set; } = string.Empty; @@ -30,11 +28,10 @@ public Locale Locale /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryPath.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryPath.cs index 870041fc8..65b055586 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryPath.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryPath.cs @@ -12,15 +12,14 @@ public class PageDirectoryPath /// public int PageDirectoryId { get; set; } - private PageDirectory? _pageDirectory; /// /// The parent . This can only be null for the /// root directory. /// public PageDirectory PageDirectory { - get => _pageDirectory ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageDirectory)); - set => _pageDirectory = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageDirectory)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryQueryExtensions.cs index 28d301a5c..16d5be245 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageDirectoryQueryExtensions.cs @@ -1,34 +1,37 @@ namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class PageDirectoryQueryExtensions { - /// - /// Fitlers the collection to only include pages with the - /// specified primary key. - /// - /// - /// Queryable instance to filter. - /// - /// PageDirectoryId to filter by. - public static IQueryable FilterById(this IQueryable pageDirectories, int pageDirectoryId) + extension(IQueryable pageDirectories) { - var result = pageDirectories.Where(i => i.PageDirectoryId == pageDirectoryId); + /// + /// Fitlers the collection to only include pages with the + /// specified primary key. + /// + /// PageDirectoryId to filter by. + public IQueryable FilterById(int pageDirectoryId) + { + var result = pageDirectories.Where(i => i.PageDirectoryId == pageDirectoryId); - return result; + return result; + } } - /// - /// Fitlers the collection to only include pages with the - /// specified primary key. - /// - /// - /// Enumerable to filter. - /// - /// PageDirectoryId to filter by. - public static IEnumerable FilterById(this IEnumerable pageDirectories, int pageDirectoryId) + extension(IEnumerable pageDirectories) { - var result = pageDirectories.Where(i => i.PageDirectoryId == pageDirectoryId); + /// + /// Fitlers the collection to only include pages with the + /// specified primary key. + /// + /// PageDirectoryId to filter by. + public IEnumerable FilterById(int pageDirectoryId) + { + var result = pageDirectories.Where(i => i.PageDirectoryId == pageDirectoryId); - return result; + return result; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageGroup.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageGroup.cs index d103c24d7..3c8f275fb 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageGroup.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageGroup.cs @@ -17,12 +17,11 @@ public class PageGroup : ICreateAuditable /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } public ICollection PageGroupItems { get; set; } = new List(); diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageGroupItem.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageGroupItem.cs index 20a70e11b..517be521e 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageGroupItem.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageGroupItem.cs @@ -5,20 +5,18 @@ public class PageGroupItem : ICreateAuditable { public int PageId { get; set; } - private Page? _page; public Page Page { - get => _page ?? throw NavigationPropertyNotInitializedException.Create(nameof(Page)); - set => _page = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Page)); + set; } public int PageGroupId { get; set; } - private PageGroup? _pageGroup; public PageGroup PageGroup { - get => _pageGroup ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageGroup)); - set => _pageGroup = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageGroup)); + set; } public int Ordering { get; set; } @@ -29,11 +27,10 @@ public PageGroup PageGroup /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PagePublishStatusQuery.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PagePublishStatusQuery.cs index ea24e85d0..95daac377 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PagePublishStatusQuery.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PagePublishStatusQuery.cs @@ -25,25 +25,23 @@ public class PagePublishStatusQuery /// public int PageVersionId { get; set; } - private Page? _page; /// /// Page that this record represents. /// public Page Page { - get => _page ?? throw NavigationPropertyNotInitializedException.Create(nameof(Page)); - set => _page = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Page)); + set; } - private PageVersion? _pageVersion; /// /// The version of the page that should be displayed /// for the corresponding PublishStatusQueryId. /// public PageVersion PageVersion { - get => _pageVersion ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageVersion)); - set => _pageVersion = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageVersion)); + set; } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PagePublishStatusQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PagePublishStatusQueryExtensions.cs index 91e5f5e95..b1b7a11c4 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PagePublishStatusQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PagePublishStatusQueryExtensions.cs @@ -1,145 +1,132 @@ namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class PagePublishStatusQueryExtensions { - /// - /// Filters the results by the publish status query type. - /// - /// - /// Queryable instance to filter. - /// - /// Query status to filter by. If the value is PublishStatusQuery.Published then additional filtering by publish date will be applied. - /// UTC execution date of the query. This is used to compare the publish date. - public static IQueryable FilterByStatus(this IQueryable source, PublishStatusQuery publishStatusQuery, DateTime executionDate) + extension(IQueryable source) { - if (publishStatusQuery == PublishStatusQuery.SpecificVersion) + /// + /// Filters the results by the publish status query type. + /// + /// Query status to filter by. If the value is PublishStatusQuery.Published then additional filtering by publish date will be applied. + /// UTC execution date of the query. This is used to compare the publish date. + public IQueryable FilterByStatus(PublishStatusQuery publishStatusQuery, DateTime executionDate) { - throw new InvalidOperationException($"Cannot filter by {nameof(PublishStatusQuery)}.{nameof(PublishStatusQuery.SpecificVersion)} using the {nameof(FilterByStatus)} extension method."); - } + if (publishStatusQuery == PublishStatusQuery.SpecificVersion) + { + throw new InvalidOperationException($"Cannot filter by {nameof(PublishStatusQuery)}.{nameof(PublishStatusQuery.SpecificVersion)} using the {nameof(FilterByStatus)} extension method."); + } - IQueryable filtered; + IQueryable filtered; - if (publishStatusQuery == PublishStatusQuery.Published) - { - filtered = source - .Where(p => p.PublishStatusQueryId == (short)publishStatusQuery && p.Page.PublishDate <= executionDate); - } - else - { - filtered = source - .Where(p => p.PublishStatusQueryId == (short)publishStatusQuery); + if (publishStatusQuery == PublishStatusQuery.Published) + { + filtered = source + .Where(p => p.PublishStatusQueryId == (short)publishStatusQuery && p.Page.PublishDate <= executionDate); + } + else + { + filtered = source + .Where(p => p.PublishStatusQueryId == (short)publishStatusQuery); + } + + return filtered; } - return filtered; - } + /// + /// Filters the collection to only include pages that are + /// not deleted. + /// + public IQueryable FilterActive() + { + var filtered = source + .Where(p => !p.PageVersion.PageTemplate.IsArchived); - /// - /// Filters the collection to only include pages that are - /// not deleted. - /// - /// - /// Queryable instance to filter. - /// - public static IQueryable FilterActive(this IQueryable source) - { - var filtered = source - .Where(p => !p.PageVersion.PageTemplate.IsArchived); + return filtered; + } - return filtered; - } + /// + /// Filters the collection to only include records with the specified page id. + /// + /// + /// Id of the page to filter by. + /// + public IQueryable FilterByPageId(int pageId) + { + var filtered = source + .Where(p => p.PageId == pageId); - /// - /// Filters the collection to only include records with the specified page id. - /// - /// - /// Queryable instance to filter. - /// - /// - /// Id of the page to filter by. - /// - public static IQueryable FilterByPageId(this IQueryable source, int pageId) - { - var filtered = source - .Where(p => p.PageId == pageId); + return filtered; + } - return filtered; - } + /// + /// Filters the collection to only include records with the specified locale id. + /// + /// + /// Id of the locale to filter by. + /// + public IQueryable FilterByLocaleId(int localeId) + { + var filtered = source + .Where(p => p.Page.LocaleId == localeId); - /// - /// Filters the collection to only include records with the specified locale id. - /// - /// - /// Queryable instance to filter. - /// - /// - /// Id of the locale to filter by. - /// - public static IQueryable FilterByLocaleId(this IQueryable source, int localeId) - { - var filtered = source - .Where(p => p.Page.LocaleId == localeId); + return filtered; + } - return filtered; - } + /// + /// Filters the collection to only include records with the specified page directory id. + /// + /// + /// Id of the directory to filter by. + /// + public IQueryable FilterByDirectoryId(int directoryId) + { + var filtered = source + .Where(p => p.Page.PageDirectoryId == directoryId); - /// - /// Filters the collection to only include records with the specified page directory id. - /// - /// - /// Queryable instance to filter. - /// - /// - /// Id of the directory to filter by. - /// - public static IQueryable FilterByDirectoryId(this IQueryable source, int directoryId) - { - var filtered = source - .Where(p => p.Page.PageDirectoryId == directoryId); + return filtered; + } - return filtered; - } + /// + /// Sorts the collection using the standard query sort parameters and rules. + /// + /// Field to sort on. + /// Direction to sort by. + public IOrderedQueryable SortBy( + PageQuerySortType pageQuerySortType, + SortDirection sortDirection + ) + { + IOrderedQueryable result; - /// - /// Sorts the collection using the standard query sort parameters and rules. - /// - /// - /// Queryable instance to sort. - /// - /// Field to sort on. - /// Direction to sort by. - public static IOrderedQueryable SortBy( - this IQueryable source, - PageQuerySortType pageQuerySortType, - SortDirection sortDirection - ) - { - IOrderedQueryable result; + switch (pageQuerySortType) + { + case PageQuerySortType.Default: + case PageQuerySortType.Title: + result = source + .OrderByWithSortDirection(e => e.PageVersion.Title, sortDirection); + break; + case PageQuerySortType.Locale: + result = source + .OrderByWithSortDirection(e => e.Page.Locale!.IETFLanguageTag, sortDirection) + .ThenByWithSortDirection(e => e.PageVersion.Title, sortDirection); + break; + case PageQuerySortType.CreateDate: + result = source + .OrderByDescendingWithSortDirection(e => e.PageVersion.CreateDate, sortDirection); + break; + case PageQuerySortType.PublishDate: + result = source + .OrderByDescendingWithSortDirection(e => e.Page.PublishDate ?? e.PageVersion.CreateDate, sortDirection) + ; + break; + default: + throw new Exception($"{nameof(PageQuerySortType)} not recognised."); + } - switch (pageQuerySortType) - { - case PageQuerySortType.Default: - case PageQuerySortType.Title: - result = source - .OrderByWithSortDirection(e => e.PageVersion.Title, sortDirection); - break; - case PageQuerySortType.Locale: - result = source - .OrderByWithSortDirection(e => e.Page.Locale!.IETFLanguageTag, sortDirection) - .ThenByWithSortDirection(e => e.PageVersion.Title, sortDirection); - break; - case PageQuerySortType.CreateDate: - result = source - .OrderByDescendingWithSortDirection(e => e.PageVersion.CreateDate, sortDirection); - break; - case PageQuerySortType.PublishDate: - result = source - .OrderByDescendingWithSortDirection(e => e.Page.PublishDate ?? e.PageVersion.CreateDate, sortDirection) - ; - break; - default: - throw new Exception($"{nameof(PageQuerySortType)} not recognised."); + return result; } - - return result; } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageQueryExtensions.cs index 727358516..5c15fd292 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageQueryExtensions.cs @@ -1,50 +1,47 @@ namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class PageQueryExtensions { - /// - /// Fitlers the collection to only include pages with the - /// specified . - /// - /// - /// Queryable instance to filter. - /// - /// PageId to filter by. - public static IQueryable FilterById(this IQueryable pages, int pageId) + extension(IQueryable pages) { - var result = pages - .Where(i => i.PageId == pageId); + /// + /// Fitlers the collection to only include pages with the + /// specified . + /// + /// PageId to filter by. + public IQueryable FilterById(int pageId) + { + var result = pages + .Where(i => i.PageId == pageId); - return result; - } + return result; + } - /// - /// Fitlers the collection to only include pages parented to the - /// specified directory. - /// - /// - /// Queryable instance to filter. - /// - /// PageDirectoryId to filter by. - public static IQueryable FilterByPageDirectoryId(this IQueryable pages, int pageDirectoryId) - { - var result = pages - .Where(i => i.PageDirectoryId == pageDirectoryId); + /// + /// Fitlers the collection to only include pages parented to the + /// specified directory. + /// + /// PageDirectoryId to filter by. + public IQueryable FilterByPageDirectoryId(int pageDirectoryId) + { + var result = pages + .Where(i => i.PageDirectoryId == pageDirectoryId); - return result; - } + return result; + } - /// - /// Filters the collection to only include versions that are - /// not deleted and not in deleted directories. - /// - /// - /// Queryable instance to filter. - /// - public static IQueryable FilterActive(this IQueryable pages) - { - // Not currently filtered, but may need to add locale filtering in here - // in a later version so will leave this here for now. - return pages; + /// + /// Filters the collection to only include versions that are + /// not deleted and not in deleted directories. + /// + public IQueryable FilterActive() + { + // Not currently filtered, but may need to add locale filtering in here + // in a later version so will leave this here for now. + return pages; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageTag.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageTag.cs index 657d37059..acf407a19 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageTag.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageTag.cs @@ -4,20 +4,18 @@ public class PageTag : IEntityTag, ICreateAuditable { public int PageId { get; set; } - private Page? _page; public Page Page { - get => _page ?? throw NavigationPropertyNotInitializedException.Create(nameof(Page)); - set => _page = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Page)); + set; } public int TagId { get; set; } - private Tag? _tag; public Tag Tag { - get => _tag ?? throw NavigationPropertyNotInitializedException.Create(nameof(Tag)); - set => _tag = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Tag)); + set; } /// @@ -26,11 +24,10 @@ public Tag Tag /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageVersion.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageVersion.cs index bdf0365c8..311c619f0 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageVersion.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageVersion.cs @@ -19,14 +19,13 @@ public class PageVersion : ICreateAuditable, IEntityVersion /// public int PageId { get; set; } - private Page? _page; /// /// The page this version is parented to. /// public Page Page { - get => _page ?? throw NavigationPropertyNotInitializedException.Create(nameof(Page)); - set => _page = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Page)); + set; } /// @@ -34,14 +33,13 @@ public Page Page /// public int PageTemplateId { get; set; } - private PageTemplate? _pageTemplate; /// /// The template used to render this version. /// public PageTemplate PageTemplate { - get => _pageTemplate ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageTemplate)); - set => _pageTemplate = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageTemplate)); + set; } /// @@ -105,12 +103,11 @@ public PageTemplate PageTemplate /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageVersionBlock.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageVersionBlock.cs index dcfe9d796..da577b786 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageVersionBlock.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageVersionBlock.cs @@ -18,37 +18,34 @@ public class PageVersionBlock : ICreateAuditable, IEntityVersionPageBlock /// public int PageVersionId { get; set; } - private PageVersion? _pageVersion; /// /// The page version that this instance is /// parented to. /// public PageVersion PageVersion { - get => _pageVersion ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageVersion)); - set => _pageVersion = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageVersion)); + set; } /// public int PageTemplateRegionId { get; set; } - private PageTemplateRegion? _pageTemplateRegion; /// public PageTemplateRegion PageTemplateRegion { - get => _pageTemplateRegion ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageTemplateRegion)); - set => _pageTemplateRegion = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageTemplateRegion)); + set; } /// public int PageBlockTypeId { get; set; } - private PageBlockType? _pageBlockType; /// public PageBlockType PageBlockType { - get => _pageBlockType ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageBlockType)); - set => _pageBlockType = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(PageBlockType)); + set; } /// @@ -72,12 +69,11 @@ public PageBlockType PageBlockType /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageVersionBlockQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageVersionBlockQueryExtensions.cs index 596dd7e4c..744640373 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageVersionBlockQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageVersionBlockQueryExtensions.cs @@ -1,15 +1,21 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class PageVersionBlockQueryExtensions { - /// - /// Filters the collection to only include blocks that - /// have not been archived. - /// - public static IQueryable FilterActive(this IQueryable pages) + extension(IQueryable pages) { - var filtered = pages.Where(p => !p.PageBlockType.IsArchived); + /// + /// Filters the collection to only include blocks that + /// have not been archived. + /// + public IQueryable FilterActive() + { + var filtered = pages.Where(p => !p.PageBlockType.IsArchived); - return filtered; + return filtered; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Pages/PageVersionQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Pages/PageVersionQueryExtensions.cs index bb7d4cb8d..d643312f2 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Pages/PageVersionQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Pages/PageVersionQueryExtensions.cs @@ -1,38 +1,41 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class PageVersionQueryExtensions { - /// - /// Filters the result to include only the version with the specified PageVersionId - /// - public static IQueryable FilterByPageVersionId(this IQueryable pageVersions, int pageVersionId) + extension(IQueryable pageVersions) { - var filtered = pageVersions - .Where(v => v.PageVersionId == pageVersionId); + /// + /// Filters the result to include only the version with the specified PageVersionId + /// + public IQueryable FilterByPageVersionId(int pageVersionId) + { + var filtered = pageVersions.Where(v => v.PageVersionId == pageVersionId); - return filtered; - } + return filtered; + } - /// - /// Filters the result to include only the version with the specified PageVersionId - /// - public static IQueryable FilterByPageId(this IQueryable pageVersions, int pageId) - { - var filtered = pageVersions - .Where(v => v.PageId == pageId); + /// + /// Filters the result to include only the version with the specified PageVersionId + /// + public IQueryable FilterByPageId(int pageId) + { + var filtered = pageVersions.Where(v => v.PageId == pageId); - return filtered; - } + return filtered; + } - /// - /// Filters the collection to only include versions that are - /// not deleted. - /// - public static IQueryable FilterActive(this IQueryable pageVersions) - { - var filtered = pageVersions - .Where(v => !v.PageTemplate.IsArchived); + /// + /// Filters the collection to only include versions that are + /// not deleted. + /// + public IQueryable FilterActive() + { + var filtered = pageVersions.Where(v => !v.PageTemplate.IsArchived); - return filtered; + return filtered; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/RewriteRules/RewriteRule.cs b/src/Cofoundry.Domain/Data/DbContext/RewriteRules/RewriteRule.cs index 12ec626a0..f68b7e1d3 100644 --- a/src/Cofoundry.Domain/Data/DbContext/RewriteRules/RewriteRule.cs +++ b/src/Cofoundry.Domain/Data/DbContext/RewriteRules/RewriteRule.cs @@ -29,11 +29,10 @@ public class RewriteRule : ICreateAuditable /// public int CreatorId { get; set; } - private User? _creator; /// public User Creator { - get => _creator ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); - set => _creator = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Creator)); + set; } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Roles/Role.cs b/src/Cofoundry.Domain/Data/DbContext/Roles/Role.cs index 9b82abc9d..03cb577b7 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Roles/Role.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Roles/Role.cs @@ -30,14 +30,13 @@ public class Role /// public string UserAreaCode { get; set; } = string.Empty; - private UserArea? _userArea; /// /// A role must be assigned to a user area e.g. CofoundryAdminUserArea. /// public UserArea UserArea { - get => _userArea ?? throw NavigationPropertyNotInitializedException.Create(nameof(UserArea)); - set => _userArea = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(UserArea)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/Roles/RolePermission.cs b/src/Cofoundry.Domain/Data/DbContext/Roles/RolePermission.cs index 21580f736..d5d14c01c 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Roles/RolePermission.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Roles/RolePermission.cs @@ -1,22 +1,20 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; public class RolePermission { public int RoleId { get; set; } - private Role? _role; public Role Role { - get => _role ?? throw NavigationPropertyNotInitializedException.Create(nameof(Role)); - set => _role = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Role)); + set; } public int PermissionId { get; set; } - private Permission? _permission; public Permission Permission { - get => _permission ?? throw NavigationPropertyNotInitializedException.Create(nameof(Permission)); - set => _permission = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Permission)); + set; } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Roles/RoleQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Roles/RoleQueryExtensions.cs index ec0e1ba74..98d667fc6 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Roles/RoleQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Roles/RoleQueryExtensions.cs @@ -1,54 +1,57 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class RoleQueryExtensions { - /// - /// Filters the roles collection to include only the role - /// with the specified . - /// - /// Collection of roles to filter. - /// Id of the role to filter to. - /// The filtered role collection. - public static IQueryable FilterById(this IQueryable roles, int roleId) + extension(IQueryable roles) { - var role = roles - .Where(r => r.RoleId == roleId); + /// + /// Filters the roles collection to include only the role + /// with the specified . + /// + /// Id of the role to filter to. + /// The filtered role collection. + public IQueryable FilterById(int roleId) + { + var role = roles + .Where(r => r.RoleId == roleId); - return role; - } + return role; + } - /// - /// Filters the roles collection to include only the role - /// with the specified if one if defined, - /// otherwise by . - /// - /// Collection of roles to filter. - /// Id of the role to filter to. - /// 3 character identifier of the role to filter to. - /// The filtered role collection. - public static IQueryable FilterByIdOrCode(this IQueryable roles, int? roleId, string? roleCode) - { - if (roleId.HasValue) + /// + /// Filters the roles collection to include only the role + /// with the specified if one if defined, + /// otherwise by . + /// + /// Id of the role to filter to. + /// 3 character identifier of the role to filter to. + /// The filtered role collection. + public IQueryable FilterByIdOrCode(int? roleId, string? roleCode) { - return roles.FilterById(roleId.Value); - } + if (roleId.HasValue) + { + return roles.FilterById(roleId.Value); + } - return roles.FilterByRoleCode(roleCode); - } + return roles.FilterByRoleCode(roleCode); + } - /// - /// Filters the roles collection to include only the role - /// with the specified . Role codes are globally - /// unique. - /// - /// Collection of roles to filter. - /// 3 character identifier of the role to filter to. - /// The filtered role collection. - public static IQueryable FilterByRoleCode(this IQueryable roles, string? roleCode) - { - var role = roles - .Where(r => r.RoleCode != null && r.RoleCode == roleCode); + /// + /// Filters the roles collection to include only the role + /// with the specified . Role codes are globally + /// unique. + /// + /// 3 character identifier of the role to filter to. + /// The filtered role collection. + public IQueryable FilterByRoleCode(string? roleCode) + { + var role = roles + .Where(r => r.RoleCode != null && r.RoleCode == roleCode); - return role; + return role; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Shared/AccessRules/IEntityAccessRuleQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Shared/AccessRules/IEntityAccessRuleQueryExtensions.cs index 388d2c8a4..9fae21697 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Shared/AccessRules/IEntityAccessRuleQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Shared/AccessRules/IEntityAccessRuleQueryExtensions.cs @@ -1,70 +1,69 @@ namespace Cofoundry.Domain.Data; +/// +/// Extension methods for querying entities that implement . +/// public static class IEntityAccessRuleQueryExtensions { - /// - /// Filters the collection to only include the access rule with the - /// specified PageAccessRuleId primary key. - /// - /// - /// Queryable instance to filter. - /// - /// Primary key to filter on. - public static IQueryable FilterById(this IQueryable rules, int id) - where TEntity : IEntityAccessRule + extension(IQueryable rules) where TEntity : IEntityAccessRule { - var filtered = rules.Where(p => p.GetId() == id); + /// + /// Filters the collection to only include the access rule with the + /// specified PageAccessRuleId primary key. + /// + /// Primary key to filter on. + public IQueryable FilterById(int id) + { + var filtered = rules.Where(p => p.GetId() == id); - return filtered; + return filtered; + } } - /// - /// Filters the collection to only include the access rule with the - /// specified PageAccessRuleId primary key. - /// - /// - /// Enumerable to filter. - /// - /// Primary key to filter on. - public static IEnumerable FilterById(this IEnumerable rules, int id) - where TEntity : IEntityAccessRule + extension(IEnumerable rules) where TEntity : IEntityAccessRule { - var filtered = rules.Where(p => p.GetId() == id); + /// + /// Filters the collection to only include the access rule with the + /// specified PageAccessRuleId primary key. + /// + /// Primary key to filter on. + public IEnumerable FilterById(int id) + { + var filtered = rules.Where(p => p.GetId() == id); - return filtered; + return filtered; + } } - /// - /// Orders the access rule collection using the default ordering - /// i.e. by user area, then by role. - /// - /// - /// Queryable instance to sort. - /// - public static IOrderedQueryable OrderByDefault(this IQueryable accessRules) - where TEntity : IEntityAccessRule + extension(IQueryable accessRules) where TEntity : IEntityAccessRule { - var filtered = accessRules - .OrderBy(r => r.UserAreaCode) - .ThenBy(r => r.RoleId); + /// + /// Orders the access rule collection using the default ordering + /// i.e. by user area, then by role. + /// + public IOrderedQueryable OrderByDefault() + { + var filtered = accessRules + .OrderBy(r => r.UserAreaCode) + .ThenBy(r => r.RoleId); - return filtered; + return filtered; + } } - /// - /// Orders the access rule collection using the default ordering - /// i.e. by user area, then by role. - /// - /// - /// Enumerable to sort. - /// - public static IOrderedEnumerable OrderByDefault(this IEnumerable accessRules) - where TEntity : IEntityAccessRule + extension(IEnumerable accessRules) where TEntity : IEntityAccessRule { - var filtered = accessRules - .OrderBy(r => r.UserAreaCode) - .ThenBy(r => r.RoleId); + /// + /// Orders the access rule collection using the default ordering + /// i.e. by user area, then by role. + /// + public IOrderedEnumerable OrderByDefault() + { + var filtered = accessRules + .OrderBy(r => r.UserAreaCode) + .ThenBy(r => r.RoleId); - return filtered; + return filtered; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Shared/Audit/Interfaces/ICreateableExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Shared/Audit/Interfaces/ICreateableExtensions.cs index cfaa32eeb..3241d1c79 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Shared/Audit/Interfaces/ICreateableExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Shared/Audit/Interfaces/ICreateableExtensions.cs @@ -1,54 +1,52 @@ namespace Cofoundry.Domain.Data; +/// +/// Extension methods for querying entities that implement . +/// public static class ICreateableExtensions { - /// - /// Filters the create date value by the specified parameters. Date - /// parameters can be null which indicates an unbounded query. - /// - /// - /// Queryable instance to filter. - /// - /// Inclusive start date. - /// Exclusive end date to filter by. - public static IQueryable FilterByCreateDate(this IQueryable source, DateTime? startDate, DateTime? endDate) - where TEntity : class, ICreateable + extension(IQueryable source) where TEntity : class, ICreateable { - if (startDate.HasValue) + /// + /// Filters the create date value by the specified parameters. Date + /// parameters can be null which indicates an unbounded query. + /// + /// Inclusive start date. + /// Exclusive end date to filter by. + public IQueryable FilterByCreateDate(DateTime? startDate, DateTime? endDate) { - source = source.Where(c => c.CreateDate >= startDate.Value); - } + if (startDate.HasValue) + { + source = source.Where(c => c.CreateDate >= startDate.Value); + } - if (endDate.HasValue) - { - source = source.Where(c => c.CreateDate < endDate.Value); - } - - return source; - } + if (endDate.HasValue) + { + source = source.Where(c => c.CreateDate < endDate.Value); + } - /// - /// Filters the create date value by the specified parameters. Date - /// parameters can be null which indicates an unbounded query. - /// - /// - /// Queryable instance to filter. - /// - /// Inclusive start date. - /// Exclusive end date to filter by. - public static IQueryable FilterByCreateDate(this IQueryable source, DateTimeOffset? startDate, DateTimeOffset? endDate) - where TEntity : class, ICreateable - { - if (startDate.HasValue) - { - source = source.Where(c => c.CreateDate >= startDate.Value.UtcDateTime); + return source; } - if (endDate.HasValue) + /// + /// Filters the create date value by the specified parameters. Date + /// parameters can be null which indicates an unbounded query. + /// + /// Inclusive start date. + /// Exclusive end date to filter by. + public IQueryable FilterByCreateDate(DateTimeOffset? startDate, DateTimeOffset? endDate) { - source = source.Where(c => c.CreateDate < endDate.Value.UtcDateTime); - } + if (startDate.HasValue) + { + source = source.Where(c => c.CreateDate >= startDate.Value.UtcDateTime); + } - return source; + if (endDate.HasValue) + { + source = source.Where(c => c.CreateDate < endDate.Value.UtcDateTime); + } + + return source; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Shared/EntityVersions/EntityVersionExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Shared/EntityVersions/EntityVersionExtensions.cs index 59d2f9c4e..442296881 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Shared/EntityVersions/EntityVersionExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Shared/EntityVersions/EntityVersionExtensions.cs @@ -1,26 +1,33 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; +/// +/// Extension methods for querying entities that implement . +/// public static class EntityVersionExtensions { - /// - /// Orders the versions by date ensuring that the draft version is always first. - /// - public static IOrderedEnumerable OrderByLatest(this IEnumerable source) - where T : IEntityVersion + extension(IEnumerable source) where T : IEntityVersion { - return source - .OrderByDescending(v => v.WorkFlowStatusId == (int)WorkFlowStatus.Draft) - .ThenByDescending(v => v.CreateDate); + /// + /// Orders the versions by date ensuring that the draft version is always first. + /// + public IOrderedEnumerable OrderByLatest() + { + return source + .OrderByDescending(v => v.WorkFlowStatusId == (int)WorkFlowStatus.Draft) + .ThenByDescending(v => v.CreateDate); + } } - /// - /// Orders the versions by date ensuring that the draft version is always first. - /// - public static IOrderedQueryable OrderByLatest(this IQueryable source) - where T : IEntityVersion + extension(IQueryable source) where T : IEntityVersion { - return source - .OrderByDescending(v => v.WorkFlowStatusId == (int)WorkFlowStatus.Draft) - .ThenByDescending(v => v.CreateDate); + /// + /// Orders the versions by date ensuring that the draft version is always first. + /// + public IOrderedQueryable OrderByLatest() + { + return source + .OrderByDescending(v => v.WorkFlowStatusId == (int)WorkFlowStatus.Draft) + .ThenByDescending(v => v.CreateDate); + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Shared/IQueryableExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Shared/IQueryableExtensions.cs index 58815eff6..9ba819a5d 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Shared/IQueryableExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Shared/IQueryableExtensions.cs @@ -2,69 +2,67 @@ namespace Cofoundry.Domain.Data; +/// +/// Extension methods for querying entities via . +/// public static class IQueryableExtensions { - /// - /// Filters the collection by a date value using the specified parameters. Date - /// parameters can be null which indicates an unbounded query. - /// - /// - /// Queryable instance to filter. - /// - /// Date field selector to filter on. - /// Inclusive start date. - /// Exclusive end date to filter by. - public static IQueryable FilterByDate( - this IQueryable source, - Expression> selector, - DateTime? startDate, - DateTime? endDate - ) + extension(IQueryable source) { - return source.ApplyFilterByDate(selector, startDate, endDate); - } - - /// - /// Filters the collection by a date value using the specified parameters. Date - /// parameters can be null which indicates an unbounded query. - /// - /// - /// Queryable instance to filter. - /// - /// Date field selector to filter on. - /// Inclusive start date. - /// Exclusive end date to filter by. - public static IQueryable FilterByDate(this IQueryable source, Expression> selector, DateTimeOffset? startDate, DateTimeOffset? endDate) - { - return source.ApplyFilterByDate(selector, startDate?.UtcDateTime, endDate?.UtcDateTime); - } - - private static IQueryable ApplyFilterByDate( - this IQueryable source, - Expression> selector, - DateTime? startDate, - DateTime? endDate - ) - { - if (startDate.HasValue) + /// + /// Filters the collection by a date value using the specified parameters. Date + /// parameters can be null which indicates an unbounded query. + /// + /// Date field selector to filter on. + /// Inclusive start date. + /// Exclusive end date to filter by. + public IQueryable FilterByDate( + Expression> selector, + DateTime? startDate, + DateTime? endDate + ) { - var predicate = Expression.Lambda>( - Expression.GreaterThanOrEqual(selector.Body, Expression.Constant(startDate.Value)), - selector.Parameters - ); - - source = source.Where(predicate); + return source.ApplyFilterByDate(selector, startDate, endDate); } - if (endDate.HasValue) + /// + /// Filters the collection by a date value using the specified parameters. Date + /// parameters can be null which indicates an unbounded query. + /// + /// Date field selector to filter on. + /// Inclusive start date. + /// Exclusive end date to filter by. + public IQueryable FilterByDate(Expression> selector, DateTimeOffset? startDate, DateTimeOffset? endDate) { - var predicate = Expression.Lambda>( - Expression.LessThan(selector.Body, Expression.Constant(endDate.Value)), - selector.Parameters - ); - source = source.Where(predicate); + return source.ApplyFilterByDate(selector, startDate?.UtcDateTime, endDate?.UtcDateTime); } - return source; + private IQueryable ApplyFilterByDate( + Expression> selector, + DateTime? startDate, + DateTime? endDate + ) + { + if (startDate.HasValue) + { + var predicate = Expression.Lambda>( + Expression.GreaterThanOrEqual(selector.Body, Expression.Constant(startDate.Value)), + selector.Parameters + ); + + source = source.Where(predicate); + } + + if (endDate.HasValue) + { + var predicate = Expression.Lambda>( + Expression.LessThan(selector.Body, Expression.Constant(endDate.Value)), + selector.Parameters + ); + source = source.Where(predicate); + } + + return source; + } } } diff --git a/src/Cofoundry.Domain/Data/DbContext/Shared/Publishing/IEntityPublishableExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Shared/Publishing/IEntityPublishableExtensions.cs index 64030e22c..97f601e32 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Shared/Publishing/IEntityPublishableExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Shared/Publishing/IEntityPublishableExtensions.cs @@ -1,40 +1,43 @@ -namespace Cofoundry.Domain.Data.Internal; +namespace Cofoundry.Domain.Data.Internal; +/// +/// Extension methods for querying entities that implement . +/// public static class IEntityPublishableExtensions { - /// - /// Updates the and - /// publish date properties to mark the entity as published. - /// - /// Type of entity to act on. - /// Entity to act on. - /// The current date and time, typically passed from the execution context in the domain layer. - /// - /// Optional time that the entity should be published and made public. If - /// this is left then the publish date is set to the current - /// date and the page is made immediately available. - /// - /// - /// Returns if the entity status has changed. If the entity was already published and - /// no change needed to be made, then is returned. - /// - public static bool SetPublished(this TEntity entity, DateTime currentDate, DateTime? publishDate = null) - where TEntity : IEntityPublishable + extension(TEntity entity) where TEntity : IEntityPublishable { - ArgumentNullException.ThrowIfNull(entity); - ArgumentEmptyException.ThrowIfDefault(currentDate); + /// + /// Updates the and + /// publish date properties to mark the entity as published. + /// + /// The current date and time, typically passed from the execution context in the domain layer. + /// + /// Optional time that the entity should be published and made public. If + /// this is left then the publish date is set to the current + /// date and the page is made immediately available. + /// + /// + /// Returns if the entity status has changed. If the entity was already published and + /// no change needed to be made, then is returned. + /// + public bool SetPublished(DateTime currentDate, DateTime? publishDate = null) + { + ArgumentNullException.ThrowIfNull(entity); + ArgumentEmptyException.ThrowIfDefault(currentDate); - var hasPublishStatusChanged = false; + var hasPublishStatusChanged = false; - if (entity.PublishStatusCode != PublishStatusCode.Published) - { - hasPublishStatusChanged = true; - entity.PublishStatusCode = PublishStatusCode.Published; - } + if (entity.PublishStatusCode != PublishStatusCode.Published) + { + hasPublishStatusChanged = true; + entity.PublishStatusCode = PublishStatusCode.Published; + } - UpdatePublishDate(entity, currentDate, publishDate); + UpdatePublishDate(entity, currentDate, publishDate); - return hasPublishStatusChanged; + return hasPublishStatusChanged; + } } private static void UpdatePublishDate(TEntity entity, DateTime currentDate, DateTime? publishDate = null) diff --git a/src/Cofoundry.Domain/Data/DbContext/Users/User.cs b/src/Cofoundry.Domain/Data/DbContext/Users/User.cs index 7c7a0f45c..8844b1628 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Users/User.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Users/User.cs @@ -156,15 +156,14 @@ public class User /// public int RoleId { get; set; } - private Role? _role; /// /// The that this user is assigned to. The role is /// required and determines the permissions available to the user /// public Role Role { - get => _role ?? throw NavigationPropertyNotInitializedException.Create(nameof(Role)); - set => _role = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(Role)); + set; } /// @@ -174,15 +173,14 @@ public Role Role /// public string UserAreaCode { get; set; } = string.Empty; - private UserArea? _userArea; /// /// The Cofoundry user system can be partitioned into user areas. This enables /// reuse of user functionality to create custom sign in areas in your application. /// public UserArea UserArea { - get => _userArea ?? throw NavigationPropertyNotInitializedException.Create(nameof(UserArea)); - set => _userArea = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(UserArea)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/Users/UserAuthenticationFailLog.cs b/src/Cofoundry.Domain/Data/DbContext/Users/UserAuthenticationFailLog.cs index e4f1f84b7..1eb3acc6d 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Users/UserAuthenticationFailLog.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Users/UserAuthenticationFailLog.cs @@ -16,15 +16,14 @@ public class UserAuthenticationFailLog /// public string UserAreaCode { get; set; } = string.Empty; - private UserArea? _userArea; /// /// The that the client was attempting to /// authenticated against. /// public virtual UserArea UserArea { - get => _userArea ?? throw NavigationPropertyNotInitializedException.Create(nameof(UserArea)); - set => _userArea = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(UserArea)); + set; } /// @@ -38,14 +37,13 @@ public virtual UserArea UserArea /// public long IPAddressId { get; set; } - private IPAddress? _ipAddress; /// /// IP Address of the connection requested authentication. /// public IPAddress IPAddress { - get => _ipAddress ?? throw NavigationPropertyNotInitializedException.Create(nameof(IPAddress)); - set => _ipAddress = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(IPAddress)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/Users/UserAuthenticationLog.cs b/src/Cofoundry.Domain/Data/DbContext/Users/UserAuthenticationLog.cs index ec06f82cb..32bbeecb3 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Users/UserAuthenticationLog.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Users/UserAuthenticationLog.cs @@ -15,14 +15,13 @@ public class UserAuthenticationLog /// public int UserId { get; set; } - private User? _user; /// /// The that successfully authenticated. /// public virtual User User { - get => _user ?? throw NavigationPropertyNotInitializedException.Create(nameof(User)); - set => _user = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(User)); + set; } /// @@ -30,14 +29,13 @@ public virtual User User /// public long IPAddressId { get; set; } - private IPAddress? _ipAddress; /// /// IP Address of the connection that authenticated the user. /// public IPAddress IPAddress { - get => _ipAddress ?? throw NavigationPropertyNotInitializedException.Create(nameof(IPAddress)); - set => _ipAddress = value; + get => field ?? throw NavigationPropertyNotInitializedException.Create(nameof(IPAddress)); + set; } /// diff --git a/src/Cofoundry.Domain/Data/DbContext/Users/UserQueryExtensions.cs b/src/Cofoundry.Domain/Data/DbContext/Users/UserQueryExtensions.cs index 3ffc3a012..5acc9a5b7 100644 --- a/src/Cofoundry.Domain/Data/DbContext/Users/UserQueryExtensions.cs +++ b/src/Cofoundry.Domain/Data/DbContext/Users/UserQueryExtensions.cs @@ -1,86 +1,89 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class UserQueryExtensions { - /// - /// Filters the result to include only the user with the specified UserId - /// - public static IQueryable FilterById(this IQueryable users, int id) + extension(IQueryable users) { - var user = users - .Where(u => u.UserId == id); + /// + /// Filters the result to include only the user with the specified UserId + /// + public IQueryable FilterById(int id) + { + var user = users.Where(u => u.UserId == id); - return user; - } + return user; + } - /// - /// Filters the collection to only include users who are not deleted (i.e. not deleted). - /// This will not filter out inactive users. - /// - public static IQueryable FilterNotDeleted(this IQueryable users) - { - var user = users - .Where(u => !u.DeletedDate.HasValue); + /// + /// Filters the collection to only include users who are not deleted (i.e. not deleted). + /// This will not filter out inactive users. + /// + public IQueryable FilterNotDeleted() + { + var user = users.Where(u => !u.DeletedDate.HasValue); - return user; - } + return user; + } - /// - /// Filters the collection to only include users who have an active account that has not - /// been deleted. This includes the system user account; to exclude it use - /// instead. - /// - public static IQueryable FilterEnabled(this IQueryable users) - { - var user = users - .Where(u => !u.DeletedDate.HasValue && !u.DeactivatedDate.HasValue); + /// + /// Filters the collection to only include users who have an active account that has not + /// been deleted. This includes the system user account; to exclude it use + /// instead. + /// + public IQueryable FilterEnabled() + { + var user = users.Where(u => !u.DeletedDate.HasValue && !u.DeactivatedDate.HasValue); - return user; - } + return user; + } - /// - /// Returns only users that are allowed to be signed in i.e. is active, not - /// deleted and is not the system user. - /// - public static IQueryable FilterCanSignIn(this IQueryable users) - { - var user = users - .Where(u => !u.IsSystemAccount && !u.DeletedDate.HasValue && !u.DeactivatedDate.HasValue); + /// + /// Returns only users that are allowed to be signed in i.e. is active, not + /// deleted and is not the system user. + /// + public IQueryable FilterCanSignIn() + { + var user = users.Where(u => + !u.IsSystemAccount + && !u.DeletedDate.HasValue + && !u.DeactivatedDate.HasValue); - return user; - } + return user; + } - /// - /// Filters the collection to only exclude the system user account. - /// - public static IQueryable FilterNotSystemAccount(this IQueryable users) - { - var user = users - .Where(u => !u.IsSystemAccount); + /// + /// Filters the collection to only exclude the system user account. + /// + public IQueryable FilterNotSystemAccount() + { + var user = users.Where(u => !u.IsSystemAccount); - return user; - } + return user; + } - /// - /// Filters the collection to only include users whoa re assigned to the specified user area - /// - public static IQueryable FilterByUserArea(this IQueryable users, string userArea) - { - var user = users - .Where(u => u.UserAreaCode == userArea); + /// + /// Filters the collection to only include users whoa re assigned to the specified user area + /// + public IQueryable FilterByUserArea(string userArea) + { + var user = users.Where(u => u.UserAreaCode == userArea); - return user; - } + return user; + } - /// - /// Includes the required entities to map a projection. - /// - public static IQueryable IncludeForSummary(this IQueryable users) - { - var user = users - .Include(u => u.Role) - .Include(u => u.Creator); + /// + /// Includes the required entities to map a projection. + /// + public IQueryable IncludeForSummary() + { + var user = users + .Include(u => u.Role) + .Include(u => u.Creator); - return user; + return user; + } } } diff --git a/src/Cofoundry.Domain/Data/QueryHelpers/EntityFrameworkPagingExtensions.cs b/src/Cofoundry.Domain/Data/QueryHelpers/EntityFrameworkPagingExtensions.cs index 1333b2eb3..e80b7d744 100644 --- a/src/Cofoundry.Domain/Data/QueryHelpers/EntityFrameworkPagingExtensions.cs +++ b/src/Cofoundry.Domain/Data/QueryHelpers/EntityFrameworkPagingExtensions.cs @@ -1,20 +1,26 @@ -namespace Cofoundry.Domain.Data; +namespace Cofoundry.Domain.Data; +/// +/// Extension methods for paging data via . +/// public static class EntityFrameworkPagingExtensions { - /// - /// Converts a query to an instance of PagedQueryResult, executing the query twice, - /// once to get the total count and again to get the results. - /// - public static async Task> ToPagedResultAsync(this IQueryable source, IPageableQuery query) + extension(IQueryable source) { - ArgumentNullException.ThrowIfNull(source); + /// + /// Converts a query to an instance of PagedQueryResult, executing the query twice, + /// once to get the total count and again to get the results. + /// + public async Task> ToPagedResultAsync(IPageableQuery query) + { + ArgumentNullException.ThrowIfNull(source); - var result = new PagedQueryResult(); - result.TotalItems = await source.CountAsync(); - result.Items = await source.Page(query).ToArrayAsync(); - PagingQueryExtensions.MapPagingData(query, result); + var result = new PagedQueryResult(); + result.TotalItems = await source.CountAsync(); + result.Items = await source.Page(query).ToArrayAsync(); + PagingQueryExtensions.MapPagingData(query, result); - return result; + return result; + } } } diff --git a/src/Cofoundry.Domain/Data/QueryHelpers/OrderBySortDirectionExtensions.cs b/src/Cofoundry.Domain/Data/QueryHelpers/OrderBySortDirectionExtensions.cs index b94acbaea..50bded6ec 100644 --- a/src/Cofoundry.Domain/Data/QueryHelpers/OrderBySortDirectionExtensions.cs +++ b/src/Cofoundry.Domain/Data/QueryHelpers/OrderBySortDirectionExtensions.cs @@ -1,106 +1,108 @@ -using System.Linq.Expressions; +using System.Linq.Expressions; namespace Cofoundry.Domain.Data; +/// +/// Extension methods for sorting data via using the +/// Cofoundry enum. +/// public static class OrderBySortDirectionExtensions { - /// - /// Does the same as a regular OrderBy clause, but inverts the direction if the SortDirection - /// is Descending. Used to simplify sorting when applying a directionable higher level query - /// (.e.g by relevance/date/title) to a lower level (e.g. EF) query that may have more complex - /// underlying primary/secondary sorting that needs inverting. - /// - /// The type of the elements of source. - /// The type of the key returned by the function that is represented by keySelector. - /// A sequence of values to order. - /// A function to extract a key from an element. - /// - /// The direction of the higher level sort, which is simply used to invert the ordering if it is - /// SortDirection.Descending - /// - /// An System.Linq.IOrderedQueryable`1 whose elements are sorted according to a key. - public static IOrderedQueryable OrderByWithSortDirection(this IQueryable source, Expression> keySelector, SortDirection sortDirection) + extension(IQueryable source) { - if (sortDirection == SortDirection.Default) + /// + /// Does the same as a regular OrderBy clause, but inverts the direction if the SortDirection + /// is Descending. Used to simplify sorting when applying a directionable higher level query + /// (.e.g by relevance/date/title) to a lower level (e.g. EF) query that may have more complex + /// underlying primary/secondary sorting that needs inverting. + /// + /// The type of the key returned by the function that is represented by keySelector. + /// A function to extract a key from an element. + /// + /// The direction of the higher level sort, which is simply used to invert the ordering if it is + /// SortDirection.Descending + /// + /// An System.Linq.IOrderedQueryable`1 whose elements are sorted according to a key. + public IOrderedQueryable OrderByWithSortDirection(Expression> keySelector, SortDirection sortDirection) { - return source.OrderBy(keySelector); - } + if (sortDirection == SortDirection.Default) + { + return source.OrderBy(keySelector); + } - return source.OrderByDescending(keySelector); - } - - /// - /// Does the same as a regular OrderByDescending clause, but inverts the direction if the SortDirection - /// is Descending. Used to simplify sorting when applying a directionable higher level query - /// (.e.g by relevance/date/title) to a lower level (e.g. EF) query that may have more complex - /// underlying primary/secondary sorting that needs inverting. - /// - /// The type of the elements of source. - /// The type of the key returned by the function that is represented by keySelector. - /// A sequence of values to order. - /// A function to extract a key from an element. - /// - /// The direction of the higher level sort, which is simply used to invert the ordering if it is - /// SortDirection.Descending - /// - /// An System.Linq.IOrderedQueryable`1 whose elements are sorted according to a key. - public static IOrderedQueryable OrderByDescendingWithSortDirection(this IQueryable source, Expression> keySelector, SortDirection sortDirection) - { - if (sortDirection == SortDirection.Default) - { return source.OrderByDescending(keySelector); } - return source.OrderBy(keySelector); - } - - /// - /// Does the same as a regular ThenBy clause, but inverts the direction if the SortDirection - /// is Descending. Used to simplify sorting when applying a directionable higher level query - /// (.e.g by relevance/date/title) to a lower level (e.g. EF) query that may have more complex - /// underlying primary/secondary sorting that needs inverting. - /// - /// The type of the elements of source. - /// The type of the key returned by the function that is represented by keySelector. - /// An System.Linq.IOrderedQueryable`1 that contains elements to sort. - /// A function to extract a key from an element. - /// - /// The direction of the higher level sort, which is simply used to invert the ordering if it is - /// SortDirection.Descending - /// - /// An System.Linq.IOrderedQueryable`1 whose elements are sorted according to a key. - public static IOrderedQueryable ThenByWithSortDirection(this IOrderedQueryable source, Expression> keySelector, SortDirection sortDirection) - { - if (sortDirection == SortDirection.Default) + /// + /// Does the same as a regular OrderByDescending clause, but inverts the direction if the SortDirection + /// is Descending. Used to simplify sorting when applying a directionable higher level query + /// (.e.g by relevance/date/title) to a lower level (e.g. EF) query that may have more complex + /// underlying primary/secondary sorting that needs inverting. + /// + /// The type of the key returned by the function that is represented by keySelector. + /// A function to extract a key from an element. + /// + /// The direction of the higher level sort, which is simply used to invert the ordering if it is + /// SortDirection.Descending + /// + /// An System.Linq.IOrderedQueryable`1 whose elements are sorted according to a key. + public IOrderedQueryable OrderByDescendingWithSortDirection(Expression> keySelector, SortDirection sortDirection) { - return source.ThenBy(keySelector); - } + if (sortDirection == SortDirection.Default) + { + return source.OrderByDescending(keySelector); + } - return source.ThenByDescending(keySelector); + return source.OrderBy(keySelector); + } } - /// - /// Does the same as a regular ThenByDescending clause, but inverts the direction if the SortDirection - /// is Descending. Used to simplify sorting when applying a directionable higher level query - /// (.e.g by relevance/date/title) to a lower level (e.g. EF) query that may have more complex - /// underlying primary/secondary sorting that needs inverting. - /// - /// The type of the elements of source. - /// The type of the key returned by the function that is represented by keySelector. - /// An System.Linq.IOrderedQueryable`1 that contains elements to sort. - /// A function to extract a key from an element. - /// - /// The direction of the higher level sort, which is simply used to invert the ordering if it is - /// SortDirection.Descending - /// - /// An System.Linq.IOrderedQueryable`1 whose elements are sorted according to a key. - public static IOrderedQueryable ThenByDescendingWithSortDirection(this IOrderedQueryable source, Expression> keySelector, SortDirection sortDirection) + extension(IOrderedQueryable source) { - if (sortDirection == SortDirection.Default) + /// + /// Does the same as a regular ThenBy clause, but inverts the direction if the SortDirection + /// is Descending. Used to simplify sorting when applying a directionable higher level query + /// (.e.g by relevance/date/title) to a lower level (e.g. EF) query that may have more complex + /// underlying primary/secondary sorting that needs inverting. + /// + /// The type of the key returned by the function that is represented by keySelector. + /// A function to extract a key from an element. + /// + /// The direction of the higher level sort, which is simply used to invert the ordering if it is + /// SortDirection.Descending + /// + /// An System.Linq.IOrderedQueryable`1 whose elements are sorted according to a key. + public IOrderedQueryable ThenByWithSortDirection(Expression> keySelector, SortDirection sortDirection) { + if (sortDirection == SortDirection.Default) + { + return source.ThenBy(keySelector); + } + return source.ThenByDescending(keySelector); } - return source.ThenBy(keySelector); + /// + /// Does the same as a regular ThenByDescending clause, but inverts the direction if the SortDirection + /// is Descending. Used to simplify sorting when applying a directionable higher level query + /// (.e.g by relevance/date/title) to a lower level (e.g. EF) query that may have more complex + /// underlying primary/secondary sorting that needs inverting. + /// + /// The type of the key returned by the function that is represented by keySelector. + /// A function to extract a key from an element. + /// + /// The direction of the higher level sort, which is simply used to invert the ordering if it is + /// SortDirection.Descending + /// + /// An System.Linq.IOrderedQueryable`1 whose elements are sorted according to a key. + public IOrderedQueryable ThenByDescendingWithSortDirection(Expression> keySelector, SortDirection sortDirection) + { + if (sortDirection == SortDirection.Default) + { + return source.ThenByDescending(keySelector); + } + + return source.ThenBy(keySelector); + } } } diff --git a/src/Cofoundry.Domain/Data/UnstructuredData/IEmptyDataModelFactoryExtensions.cs b/src/Cofoundry.Domain/Data/UnstructuredData/IEmptyDataModelFactoryExtensions.cs index c94027269..34654aaf5 100644 --- a/src/Cofoundry.Domain/Data/UnstructuredData/IEmptyDataModelFactoryExtensions.cs +++ b/src/Cofoundry.Domain/Data/UnstructuredData/IEmptyDataModelFactoryExtensions.cs @@ -1,24 +1,30 @@ namespace Cofoundry.Domain.Data; +/// +/// Extension methods for . +/// public static class IEmptyDataModelFactoryExtensions { - /// - /// Create an empty instance of an entity data model of type - /// . This is expected to be - /// used in mapping when there is a problem deserializing an existing - /// data model so that we don't ever have to return . - /// - /// - /// The concrete data model type to create e.g. "ExampleBlogDataModel". All data - /// model types should support a public parameterless constructor, otherwise an - /// will be thrown. - /// - /// - /// Newly created empty instance of . - /// - public static TConcrete Create(this IEmptyDataModelFactory emptyDataModelFactory) - where TConcrete : class + extension(IEmptyDataModelFactory emptyDataModelFactory) { - return emptyDataModelFactory.Create(typeof(TConcrete)); + /// + /// Create an empty instance of an entity data model of type + /// . This is expected to be + /// used in mapping when there is a problem deserializing an existing + /// data model so that we don't ever have to return . + /// + /// + /// The concrete data model type to create e.g. "ExampleBlogDataModel". All data + /// model types should support a public parameterless constructor, otherwise an + /// will be thrown. + /// + /// + /// Newly created empty instance of . + /// + public TConcrete Create() + where TConcrete : class + { + return emptyDataModelFactory.Create(typeof(TConcrete)); + } } } diff --git a/src/Cofoundry.Domain/Domain/AccessRules/Models/EntityAccessRuleSetCollectionExtensions.cs b/src/Cofoundry.Domain/Domain/AccessRules/Models/EntityAccessRuleSetCollectionExtensions.cs index 4696ec5c2..9a772974e 100644 --- a/src/Cofoundry.Domain/Domain/AccessRules/Models/EntityAccessRuleSetCollectionExtensions.cs +++ b/src/Cofoundry.Domain/Domain/AccessRules/Models/EntityAccessRuleSetCollectionExtensions.cs @@ -1,18 +1,23 @@ -namespace Cofoundry.Domain; +namespace Cofoundry.Domain; +/// +/// Extension methods for collections of . +/// public static class EntityAccessRuleSetCollectionExtensions { - /// - /// Filters the collection to include only rule sets not authorized to - /// be accessed by the . - /// - /// The collection to filer. - /// The to filter on. Cannot be null. - /// A collection of rules that don't match the specified user account. - public static IEnumerable GetRuleViolations(this IEnumerable accessRules, IUserContext user) + extension(IEnumerable accessRules) { - ArgumentNullException.ThrowIfNull(user); + /// + /// Filters the collection to include only rule sets not authorized to + /// be accessed by the . + /// + /// The to filter on. Cannot be null. + /// A collection of rules that don't match the specified user account. + public IEnumerable GetRuleViolations(IUserContext user) + { + ArgumentNullException.ThrowIfNull(user); - return accessRules.Where(r => !r.IsAuthorized(user)); + return accessRules.Where(r => !r.IsAuthorized(user)); + } } } diff --git a/src/Cofoundry.Domain/Domain/AdminModules/Models/AdminModuleCollectionExtensions.cs b/src/Cofoundry.Domain/Domain/AdminModules/Models/AdminModuleCollectionExtensions.cs index f17aa2389..ea0e4fe34 100644 --- a/src/Cofoundry.Domain/Domain/AdminModules/Models/AdminModuleCollectionExtensions.cs +++ b/src/Cofoundry.Domain/Domain/AdminModules/Models/AdminModuleCollectionExtensions.cs @@ -1,13 +1,19 @@ -namespace Cofoundry.Domain; +namespace Cofoundry.Domain; +/// +/// Extension methods for collections of . +/// public static class AdminModuleCollectionExtensions { - public static IEnumerable SetStandardOrdering(this IEnumerable source) + extension(IEnumerable source) { - return source - .OrderBy(r => r.MenuCategory) - .ThenBy(r => r.PrimaryOrdering) - .ThenByDescending(r => r.SecondaryOrdering) - .ThenBy(r => r.Title); + public IEnumerable SetStandardOrdering() + { + return source + .OrderBy(r => r.MenuCategory) + .ThenBy(r => r.PrimaryOrdering) + .ThenByDescending(r => r.SecondaryOrdering) + .ThenBy(r => r.Title); + } } } diff --git a/src/Cofoundry.Domain/Domain/AuthorizedTasks/ContentRepository/ContentRepositoryAuthorizedTaskExtensions.cs b/src/Cofoundry.Domain/Domain/AuthorizedTasks/ContentRepository/ContentRepositoryAuthorizedTaskExtensions.cs index 9aaabc247..5d8305f55 100644 --- a/src/Cofoundry.Domain/Domain/AuthorizedTasks/ContentRepository/ContentRepositoryAuthorizedTaskExtensions.cs +++ b/src/Cofoundry.Domain/Domain/AuthorizedTasks/ContentRepository/ContentRepositoryAuthorizedTaskExtensions.cs @@ -3,23 +3,29 @@ namespace Cofoundry.Domain; +/// +/// extension methods for authorized tasks. +/// public static class ContentRepositoryAuthorizedTaskExtensions { - /// - /// - /// Authorized tasks represent a single user-based operation that can be executed without - /// being logged in. Task authorization is validated by a crytographically random - /// generated token, often communicated via an out-of-band communication mechanism - /// such as an email. Examples include password reset or email address validation flows. - /// - /// - /// Tasks tend to be single-use and can be marked when completed, and can also be - /// invalidated explicitly. They can also be rate-limited by IPAddress and time-limited - /// by validating against the create date. - /// - /// - public static IAdvancedContentRepositoryAuthorizedTaskRepository AuthorizedTasks(this IAdvancedContentRepository contentRepository) + extension(IAdvancedContentRepository contentRepository) { - return new ContentRepositoryAuthorizedTaskRepository(contentRepository.AsExtendableContentRepository()); + /// + /// + /// Authorized tasks represent a single user-based operation that can be executed without + /// being logged in. Task authorization is validated by a crytographically random + /// generated token, often communicated via an out-of-band communication mechanism + /// such as an email. Examples include password reset or email address validation flows. + /// + /// + /// Tasks tend to be single-use and can be marked when completed, and can also be + /// invalidated explicitly. They can also be rate-limited by IPAddress and time-limited + /// by validating against the create date. + /// + /// + public IAdvancedContentRepositoryAuthorizedTaskRepository AuthorizedTasks() + { + return new ContentRepositoryAuthorizedTaskRepository(contentRepository.AsExtendableContentRepository()); + } } } diff --git a/src/Cofoundry.Domain/Domain/ContentRepository/Extension/DomainRepositoryDefaultTransactionManagerExtensions.cs b/src/Cofoundry.Domain/Domain/ContentRepository/Extension/DomainRepositoryDefaultTransactionManagerExtensions.cs index dc6ff3696..2aa795d92 100644 --- a/src/Cofoundry.Domain/Domain/ContentRepository/Extension/DomainRepositoryDefaultTransactionManagerExtensions.cs +++ b/src/Cofoundry.Domain/Domain/ContentRepository/Extension/DomainRepositoryDefaultTransactionManagerExtensions.cs @@ -4,31 +4,52 @@ namespace Cofoundry.Domain.TransactionManager.Default; +/// +/// Extension methods for . +/// public static class DomainRepositoryDefaultTransactionManagerExtensions { - /// - /// Creates a new transaction scope associated with the specified connection, - /// using the specified transaction configuration options. - /// The scope can be nested inside another scope in which case the underlying - /// db transaction is only committed once both the outer and inner transaction(s) - /// have been committed. The returned implements - /// and should be wrapped in a using statement. - /// - /// - /// Repository instance to extend. - /// - /// This is defaulted to . - /// This is defaulted to . - /// An instance, which is IDisposable and must be disposed. - public static ITransactionScope CreateScope( - this IDomainRepositoryTransactionManager domainRepositoryTransactionManager, - System.Transactions.TransactionScopeOption transactionScopeOption = System.Transactions.TransactionScopeOption.Required, - System.Transactions.IsolationLevel isolationLevel = System.Transactions.IsolationLevel.ReadCommitted - ) + extension(IDomainRepositoryTransactionManager domainRepositoryTransactionManager) { - var extendable = domainRepositoryTransactionManager.AsExtendableDomainRepositoryTransactionManager(); - var defaultTransactionScopeManager = CastDefaultTransactionScopeManager(extendable.TransactionScopeManager); - return defaultTransactionScopeManager.Create(extendable.DbContext, transactionScopeOption, isolationLevel); + /// + /// Creates a new transaction scope associated with the specified connection, + /// using the specified transaction configuration options. + /// The scope can be nested inside another scope in which case the underlying + /// db transaction is only committed once both the outer and inner transaction(s) + /// have been committed. The returned implements + /// and should be wrapped in a using statement. + /// + /// This is defaulted to . + /// This is defaulted to . + /// An instance, which is IDisposable and must be disposed. + public ITransactionScope CreateScope( + System.Transactions.TransactionScopeOption transactionScopeOption = System.Transactions.TransactionScopeOption.Required, + System.Transactions.IsolationLevel isolationLevel = System.Transactions.IsolationLevel.ReadCommitted) + { + var extendable = domainRepositoryTransactionManager.AsExtendableDomainRepositoryTransactionManager(); + var defaultTransactionScopeManager = CastDefaultTransactionScopeManager(extendable.TransactionScopeManager); + return defaultTransactionScopeManager.Create(extendable.DbContext, transactionScopeOption, isolationLevel); + } + + /// + /// Creates a new transaction scope associated with the specified connection, + /// creating the inner scope using the specified factory method. + /// The scope can be nested inside another scope in which case the underlying + /// db transaction is only committed once both the outer and inner transaction(s) + /// have been committed. The returned implements + /// and should be wrapped in a using statement. + /// + /// + /// Function to use to create and configure a new . + /// + /// An instance, which is IDisposable and must be disposed. + public ITransactionScope CreateScope(Func transactionScopeFactory) + { + var extendable = domainRepositoryTransactionManager.AsExtendableDomainRepositoryTransactionManager(); + var defaultTransactionScopeManager = CastDefaultTransactionScopeManager(extendable.TransactionScopeManager); + + return defaultTransactionScopeManager.Create(extendable.DbContext, transactionScopeFactory); + } } private static IDefaultTransactionScopeManager CastDefaultTransactionScopeManager(ITransactionScopeManager transactionScopeManager) @@ -40,30 +61,4 @@ private static IDefaultTransactionScopeManager CastDefaultTransactionScopeManage return defaultTransactionScopeManager; } - - /// - /// Creates a new transaction scope associated with the specified connection, - /// creating the inner scope using the specified factory method. - /// The scope can be nested inside another scope in which case the underlying - /// db transaction is only committed once both the outer and inner transaction(s) - /// have been committed. The returned implements - /// and should be wrapped in a using statement. - /// - /// - /// Repository instance to extend. - /// - /// - /// Function to use to create and configure a new . - /// - /// An instance, which is IDisposable and must be disposed. - public static ITransactionScope CreateScope( - this IDomainRepositoryTransactionManager domainRepositoryTransactionManager, - Func transactionScopeFactory - ) - { - var extendable = domainRepositoryTransactionManager.AsExtendableDomainRepositoryTransactionManager(); - var defaultTransactionScopeManager = CastDefaultTransactionScopeManager(extendable.TransactionScopeManager); - - return defaultTransactionScopeManager.Create(extendable.DbContext, transactionScopeFactory); - } } diff --git a/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IAdvancedContentRepositoryExtensions.cs b/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IAdvancedContentRepositoryExtensions.cs index 604ffb304..5cebb7059 100644 --- a/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IAdvancedContentRepositoryExtensions.cs +++ b/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IAdvancedContentRepositoryExtensions.cs @@ -1,21 +1,27 @@ -namespace Cofoundry.Domain; +namespace Cofoundry.Domain; +/// +/// Extension methods for . +/// public static class IAdvancedContentRepositoryExtensions { - /// - /// Execute queries or commands using the user context associated with the - /// specified user area. This is useful when implementing multiple user areas - /// whereby a client can be signed into multiple user accounts belonging to - /// different user areas. Use this to force execution to use the context - /// of a specific user area rather than relying on the "ambient" or default. - /// - /// - /// The user area to use when determining the signed in user to execute - /// tasks with. - /// - public static IAdvancedContentRepository WithContext(this IAdvancedContentRepository repository) - where TUserAreaDefinition : IUserAreaDefinition + extension(IAdvancedContentRepository repository) { - return (IAdvancedContentRepository)IDomainRepositoryExtensions.WithContext(repository); + /// + /// Execute queries or commands using the user context associated with the + /// specified user area. This is useful when implementing multiple user areas + /// whereby a client can be signed into multiple user accounts belonging to + /// different user areas. Use this to force execution to use the context + /// of a specific user area rather than relying on the "ambient" or default. + /// + /// + /// The user area to use when determining the signed in user to execute + /// tasks with. + /// + public IAdvancedContentRepository WithContext() + where TUserAreaDefinition : IUserAreaDefinition + { + return (IAdvancedContentRepository)IDomainRepositoryExtensions.WithContext(repository); + } } } diff --git a/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IContentRepositoryExtensions.cs b/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IContentRepositoryExtensions.cs index 98a4a7bde..1707dc33e 100644 --- a/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IContentRepositoryExtensions.cs +++ b/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IContentRepositoryExtensions.cs @@ -1,24 +1,27 @@ namespace Cofoundry.Domain; +/// +/// Extension methods for . +/// public static class IContentRepositoryExtensions { - /// - /// Execute queries or commands using the user context associated with the - /// specified user area. This is useful when implementing multiple user areas - /// whereby a client can be logged into multiple user accounts belonging to - /// different user areas. Use this to force execution to use the context - /// of a specific user area rather than relying on the "ambient" or default. - /// - /// - /// The user area to use when determining the signed in user to execute - /// tasks with. - /// - /// - /// Repository instance to extend. - /// - public static IContentRepository WithContext(this IContentRepository repository) - where TUserAreaDefinition : IUserAreaDefinition + extension(IContentRepository repository) { - return (IContentRepository)IDomainRepositoryExtensions.WithContext(repository); + /// + /// Execute queries or commands using the user context associated with the + /// specified user area. This is useful when implementing multiple user areas + /// whereby a client can be logged into multiple user accounts belonging to + /// different user areas. Use this to force execution to use the context + /// of a specific user area rather than relying on the "ambient" or default. + /// + /// + /// The user area to use when determining the signed in user to execute + /// tasks with. + /// + public IContentRepository WithContext() + where TUserAreaDefinition : IUserAreaDefinition + { + return (IContentRepository)IDomainRepositoryExtensions.WithContext(repository); + } } } diff --git a/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IDomainRepositoryExtensions.cs b/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IDomainRepositoryExtensions.cs index 49f2d0b51..e9b3339df 100644 --- a/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IDomainRepositoryExtensions.cs +++ b/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IDomainRepositoryExtensions.cs @@ -5,229 +5,204 @@ namespace Cofoundry.Domain; +/// +/// Extension methods for . +/// public static class IDomainRepositoryExtensions { - /// - /// Used to manage transactions for multiple domain commands. - /// This abstraction is an enhanced version of - /// and works in the same way. - /// - /// - /// Repository instance to extend. - /// - public static IDomainRepositoryTransactionManager Transactions(this IDomainRepository domainRepository) + extension(IDomainRepository domainRepository) { - var extendedContentRepositry = domainRepository.AsExtendableContentRepository(); - - return extendedContentRepositry.ServiceProvider.GetRequiredService(); - } - - /// - /// Sets the execution context for any queries or commands chained off this - /// instance. Typically used to impersonate a user, elevate permissions or - /// maintain context in nested query or command execution. - /// - /// - /// Repository instance to extend. - /// - /// - /// The execution context instance to use. - /// - public static TRepository WithContext(this TRepository repository, IExecutionContext executionContext) - where TRepository : IDomainRepository - { - ArgumentNullException.ThrowIfNull(executionContext); - - var extendedContentRepositry = repository.AsExtendableContentRepository(); - return (TRepository)extendedContentRepositry.WithExecutor(executor => new DomainRepositoryExecutorWithExecutionContext(executor, executionContext)); - } - - /// - /// Uses the specified to build a new - /// to run queries or commands under. Typically this is used to impersonate a user or - /// elevate permissions. - /// - /// - /// Repository instance to extend. - /// - /// - /// The to build into a new . - /// - public static TRepository WithContext(this TRepository repository, IUserContext userContext) - where TRepository : IDomainRepository - { - ArgumentNullException.ThrowIfNull(userContext); - - var extendedContentRepositry = repository.AsExtendableContentRepository(); - var executionContextFactory = extendedContentRepositry.ServiceProvider.GetRequiredService(); - - return (TRepository)extendedContentRepositry.WithExecutor(executor => new DomainRepositoryExecutorWithUserContext(executor, executionContextFactory, userContext)); - } - - /// - /// Execute queries or commands using the user context associated with the - /// specified user area. This is useful when implementing multiple user areas - /// whereby a client can be logged into multiple user accounts belonging to - /// different user areas. Use this to force execution to use the context - /// of a specific user area rather than relying on the "ambient" or default. - /// - /// - /// The user area to use when determining the signed in user to execute - /// tasks with. - /// - /// - /// Repository instance to extend. - /// - public static IDomainRepository WithContext(this IDomainRepository repository) - where TUserAreaDefinition : IUserAreaDefinition - { - var extendedContentRepositry = repository.AsExtendableContentRepository(); - var userArea = extendedContentRepositry.ServiceProvider.GetRequiredService(); - var userContextService = extendedContentRepositry.ServiceProvider.GetRequiredService(); - var executionContextFactory = extendedContentRepositry.ServiceProvider.GetRequiredService(); - - return extendedContentRepositry.WithExecutor(executor => new DomainRepositoryExecutorWithUserAreaContext(executor, userArea, userContextService, executionContextFactory)); - } - - /// - /// Runs any queries or commands chained off this instance under - /// the system user account which has no permission restrictions. - /// This is useful when you need to perform an action that the currently - /// signed in user does not have permission for, e.g. signing up a new - /// user prior to sign. - /// - /// - /// Repository instance to extend. - /// - public static TRepository WithElevatedPermissions(this TRepository repository) - where TRepository : IDomainRepository - { - var extendedContentRepositry = repository.AsExtendableContentRepository(); - var executionContextFactory = extendedContentRepositry.ServiceProvider.GetRequiredService(); - - return (TRepository)extendedContentRepositry.WithExecutor(executor => new DomainRepositoryExecutorWithElevatedPermissions(executor, executionContextFactory)); - } - - /// - /// Allows you to chain mutator functions to run after execution of a query. - /// - /// Query result type. - /// - /// Repository instance to extend. - /// - /// Query to mutate. - /// A query context that allows chaining of mutator functions. - public static IDomainRepositoryQueryContext WithQuery(this IDomainRepository domainRepository, IQuery query) - { - var extendableContentRepository = domainRepository.AsExtendableContentRepository(); - - return DomainRepositoryQueryContextFactory.Create(query, extendableContentRepository); - } - - /// - /// Patches a command to modify the current state and then executes it. - /// - /// Type of command to patch and execute. - /// - /// Repository instance to extend. - /// - /// - /// An action to configure or "patch" a command that's been initialized - /// with existing data. - /// - public static async Task PatchCommandAsync(this IDomainRepository repository, Action commandPatcher) - where TCommand : IPatchableCommand - { - var query = new GetPatchableCommandQuery(); - var command = await repository.ExecuteQueryAsync(query); - EntityNotFoundException.ThrowIfNull(command); - - commandPatcher(command); + /// + /// Used to manage transactions for multiple domain commands. + /// This abstraction is an enhanced version of + /// and works in the same way. + /// + public IDomainRepositoryTransactionManager Transactions() + { + var extendedContentRepositry = domainRepository.AsExtendableContentRepository(); + + return extendedContentRepositry.ServiceProvider.GetRequiredService(); + } + + /// + /// Allows you to chain mutator functions to run after execution of a query. + /// + /// Query result type. + /// Query to mutate. + /// A query context that allows chaining of mutator functions. + public IDomainRepositoryQueryContext WithQuery(IQuery query) + { + var extendableContentRepository = domainRepository.AsExtendableContentRepository(); - await repository.ExecuteCommandAsync(command); + return DomainRepositoryQueryContextFactory.Create(query, extendableContentRepository); + } } - /// - /// Patches a command to modify the current state and then executes it. - /// - /// Type of command to patch and execute. - /// - /// Repository instance to extend. - /// - /// - /// The integer database identifier of the entity associated with - /// patchable command. - /// - /// - /// An action to configure or "patch" a command that's been initialized - /// with existing data. - /// - public static async Task PatchCommandAsync(this IDomainRepository repository, int id, Action commandPatcher) - where TCommand : IPatchableByIdCommand + extension(TRepository repository) where TRepository : IDomainRepository { - var query = new GetPatchableCommandByIdQuery(id); - var command = await repository.ExecuteQueryAsync(query); - - EntityNotFoundException.ThrowIfNull(command, id); - commandPatcher(command); + /// + /// Sets the execution context for any queries or commands chained off this + /// instance. Typically used to impersonate a user, elevate permissions or + /// maintain context in nested query or command execution. + /// + /// + /// The execution context instance to use. + /// + public TRepository WithContext(IExecutionContext executionContext) + { + ArgumentNullException.ThrowIfNull(executionContext); + + var extendedContentRepositry = repository.AsExtendableContentRepository(); + return (TRepository)extendedContentRepositry.WithExecutor(executor => new DomainRepositoryExecutorWithExecutionContext(executor, executionContext)); + } + + /// + /// Uses the specified to build a new + /// to run queries or commands under. Typically this is used to impersonate a user or + /// elevate permissions. + /// + /// + /// Repository instance to extend. + /// + /// + /// The to build into a new . + /// + public TRepository WithContext(IUserContext userContext) + { + ArgumentNullException.ThrowIfNull(userContext); + + var extendedContentRepositry = repository.AsExtendableContentRepository(); + var executionContextFactory = extendedContentRepositry.ServiceProvider.GetRequiredService(); + + return (TRepository)extendedContentRepositry.WithExecutor(executor => new DomainRepositoryExecutorWithUserContext(executor, executionContextFactory, userContext)); + } + + /// + /// Runs any queries or commands chained off this instance under + /// the system user account which has no permission restrictions. + /// This is useful when you need to perform an action that the currently + /// signed in user does not have permission for, e.g. signing up a new + /// user prior to sign. + /// + public TRepository WithElevatedPermissions() + { + var extendedContentRepositry = repository.AsExtendableContentRepository(); + var executionContextFactory = extendedContentRepositry.ServiceProvider.GetRequiredService(); + + return (TRepository)extendedContentRepositry.WithExecutor(executor => new DomainRepositoryExecutorWithElevatedPermissions(executor, executionContextFactory)); + } + + /// + /// Prevents execution completing before a random duration has elapsed by padding the + /// execution time using . This can help mitigate against time-based + /// enumeration attacks by extending the beyond + /// the expected bounds of the completion time. For example, this could be used to mitigate harvesting + /// of valid usernames from login or forgot password pages by measuring the response times. + /// + /// + /// The minimum duration to extend the exection to. The execution will not complete quicker + /// than this value. + /// + /// + /// The maximum duration to extend the exection to. + /// + public TRepository WithRandomDuration(int minDurationInMilliseconds, int maxDurationInMilliseconds) + { + return WithRandomDuration(repository, new RandomizedExecutionDuration() + { + Enabled = true, + MinInMilliseconds = minDurationInMilliseconds, + MaxInMilliseconds = maxDurationInMilliseconds + }); + } + + /// + /// Prevents execution completing before a random duration has elapsed by padding the + /// execution time using . This can help mitigate against time-based + /// enumeration attacks by extending the exection duration beyond the expected bounds + /// of the query or command completion time. For example, this could be used to mitigate harvesting + /// of valid usernames from login or forgot password pages by measuring the response times. + /// + /// + /// The parameters to use in extending the duration. + /// + public TRepository WithRandomDuration( + RandomizedExecutionDuration duration + ) + { + var extendedContentRepositry = repository.AsExtendableContentRepository(); + var executionDurationRandomizerScopeManager = extendedContentRepositry.ServiceProvider.GetRequiredService(); - await repository.ExecuteCommandAsync(command); + return (TRepository)extendedContentRepositry.WithExecutor(executor => new DomainRepositoryExecutorWithRandomizedDuration(executor, executionDurationRandomizerScopeManager, duration)); + } } - /// - /// Prevents execution completing before a random duration has elapsed by padding the - /// execution time using . This can help mitigate against time-based - /// enumeration attacks by extending the beyond - /// the expected bounds of the completion time. For example, this could be used to mitigate harvesting - /// of valid usernames from login or forgot password pages by measuring the response times. - /// - /// - /// Repository instance to extend. - /// - /// - /// The minimum duration to extend the exection to. The execution will not complete quicker - /// than this value. - /// - /// - /// The maximum duration to extend the exection to. - /// - public static TRepository WithRandomDuration( - this TRepository repository, - int minDurationInMilliseconds, - int maxDurationInMilliseconds - ) - where TRepository : IDomainRepository + extension(IDomainRepository repository) { - return WithRandomDuration(repository, new RandomizedExecutionDuration() + /// + /// Execute queries or commands using the user context associated with the + /// specified user area. This is useful when implementing multiple user areas + /// whereby a client can be logged into multiple user accounts belonging to + /// different user areas. Use this to force execution to use the context + /// of a specific user area rather than relying on the "ambient" or default. + /// + /// + /// The user area to use when determining the signed in user to execute + /// tasks with. + /// + public IDomainRepository WithContext() + where TUserAreaDefinition : IUserAreaDefinition { - Enabled = true, - MinInMilliseconds = minDurationInMilliseconds, - MaxInMilliseconds = maxDurationInMilliseconds - }); - } + var extendedContentRepositry = repository.AsExtendableContentRepository(); + var userArea = extendedContentRepositry.ServiceProvider.GetRequiredService(); + var userContextService = extendedContentRepositry.ServiceProvider.GetRequiredService(); + var executionContextFactory = extendedContentRepositry.ServiceProvider.GetRequiredService(); + + return extendedContentRepositry.WithExecutor(executor => new DomainRepositoryExecutorWithUserAreaContext(executor, userArea, userContextService, executionContextFactory)); + } + + /// + /// Patches a command to modify the current state and then executes it. + /// + /// Type of command to patch and execute. + /// + /// An action to configure or "patch" a command that's been initialized + /// with existing data. + /// + public async Task PatchCommandAsync(Action commandPatcher) + where TCommand : IPatchableCommand + { + var query = new GetPatchableCommandQuery(); + var command = await repository.ExecuteQueryAsync(query); + EntityNotFoundException.ThrowIfNull(command); + + commandPatcher(command); + + await repository.ExecuteCommandAsync(command); + } + + /// + /// Patches a command to modify the current state and then executes it. + /// + /// Type of command to patch and execute. + /// + /// The integer database identifier of the entity associated with + /// patchable command. + /// + /// + /// An action to configure or "patch" a command that's been initialized + /// with existing data. + /// + public async Task PatchCommandAsync(int id, Action commandPatcher) + where TCommand : IPatchableByIdCommand + { + var query = new GetPatchableCommandByIdQuery(id); + var command = await repository.ExecuteQueryAsync(query); - /// - /// Prevents execution completing before a random duration has elapsed by padding the - /// execution time using . This can help mitigate against time-based - /// enumeration attacks by extending the exection duration beyond the expected bounds - /// of the query or command completion time. For example, this could be used to mitigate harvesting - /// of valid usernames from login or forgot password pages by measuring the response times. - /// - /// - /// Repository instance to extend. - /// - /// - /// The parameters to use in extending the duration. - /// - public static TRepository WithRandomDuration( - this TRepository repository, - RandomizedExecutionDuration duration - ) - where TRepository : IDomainRepository - { - var extendedContentRepositry = repository.AsExtendableContentRepository(); - var executionDurationRandomizerScopeManager = extendedContentRepositry.ServiceProvider.GetRequiredService(); + EntityNotFoundException.ThrowIfNull(command, id); + commandPatcher(command); - return (TRepository)extendedContentRepositry.WithExecutor(executor => new DomainRepositoryExecutorWithRandomizedDuration(executor, executionDurationRandomizerScopeManager, duration)); + await repository.ExecuteCommandAsync(command); + } } } diff --git a/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IDomainRepositoryTransactionManagerExtendableExtensions.cs b/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IDomainRepositoryTransactionManagerExtendableExtensions.cs index 944243d0d..64fddb836 100644 --- a/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IDomainRepositoryTransactionManagerExtendableExtensions.cs +++ b/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IDomainRepositoryTransactionManagerExtendableExtensions.cs @@ -1,14 +1,20 @@ -namespace Cofoundry.Domain.Extendable; +namespace Cofoundry.Domain.Extendable; +/// +/// Extension methods for . +/// public static class IDomainRepositoryTransactionManagerExtendableExtensions { - public static IExtendableDomainRepositoryTransactionManager AsExtendableDomainRepositoryTransactionManager(this IDomainRepositoryTransactionManager domainRepositoryTransactionManager) + extension(IDomainRepositoryTransactionManager domainRepositoryTransactionManager) { - if (domainRepositoryTransactionManager is IExtendableDomainRepositoryTransactionManager extendable) + public IExtendableDomainRepositoryTransactionManager AsExtendableDomainRepositoryTransactionManager() { - return extendable; - } + if (domainRepositoryTransactionManager is IExtendableDomainRepositoryTransactionManager extendable) + { + return extendable; + } - throw new Exception($"An {nameof(IDomainRepositoryTransactionManager)} implementation should also implement {nameof(IExtendableDomainRepositoryTransactionManager)} to allow internal/plugin extendibility."); + throw new Exception($"An {nameof(IDomainRepositoryTransactionManager)} implementation should also implement {nameof(IExtendableDomainRepositoryTransactionManager)} to allow internal/plugin extendibility."); + } } } diff --git a/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IExtendableContentRepositoryExtensions.cs b/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IExtendableContentRepositoryExtensions.cs index 58a544088..ca90dc1f4 100644 --- a/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IExtendableContentRepositoryExtensions.cs +++ b/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IExtendableContentRepositoryExtensions.cs @@ -1,16 +1,23 @@ -namespace Cofoundry.Domain.Extendable; +namespace Cofoundry.Domain.Extendable; +/// +/// Content repository extension methods to allow casting to +/// which allows for modular extension via Cofoundry or plugins. +/// public static class IExtendableContentRepositoryExtensions { - /// - /// Casts the repository instance as to - /// provide access to hidden functionality intended for extending a repository with - /// bespoke features. These are advanced feature intended to be used for extension only - /// e.g. internally by Cofoundry, in plugins or custom extensions - /// - public static IExtendableContentRepository AsExtendableContentRepository(this IDomainRepository contentRepository) + extension(IDomainRepository contentRepository) { - return CastToExtendableContentRepository(contentRepository); + /// + /// Casts the repository instance as to + /// provide access to hidden functionality intended for extending a repository with + /// bespoke features. These are advanced feature intended to be used for extension only + /// e.g. internally by Cofoundry, in plugins or custom extensions + /// + public IExtendableContentRepository AsExtendableContentRepository() + { + return CastToExtendableContentRepository(contentRepository); + } } private static IExtendableContentRepository CastToExtendableContentRepository(T contentRepository) diff --git a/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IExtendableContentRepositoryPartExtensions.cs b/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IExtendableContentRepositoryPartExtensions.cs index c973fd1a0..23340d2f5 100644 --- a/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IExtendableContentRepositoryPartExtensions.cs +++ b/src/Cofoundry.Domain/Domain/ContentRepository/Extension/IExtendableContentRepositoryPartExtensions.cs @@ -1,11 +1,17 @@ -namespace Cofoundry.Domain.Extendable; +namespace Cofoundry.Domain.Extendable; +/// +/// Content repository part extension methods to allow casting to +/// which allows for modular extension via Cofoundry or plugins. +/// public static class IExtendableContentRepositoryPartExtensions { - public static IExtendableContentRepositoryPart AsExtendableContentRepositoryPart(this TRepositoryPart contentRepository) - where TRepositoryPart : IContentRepositoryPart + extension(TRepositoryPart contentRepository) where TRepositoryPart : IContentRepositoryPart { - return CastToExtendableContentRepositoryPart(contentRepository); + public IExtendableContentRepositoryPart AsExtendableContentRepositoryPart() + { + return CastToExtendableContentRepositoryPart(contentRepository); + } } private static IExtendableContentRepositoryPart CastToExtendableContentRepositoryPart(T contentRepository) diff --git a/src/Cofoundry.Domain/Domain/ContentRepository/QueryResult/IDomainRepositoryQueryMutatorExtensions.cs b/src/Cofoundry.Domain/Domain/ContentRepository/QueryResult/IDomainRepositoryQueryMutatorExtensions.cs index 4f98edb14..b4ae972a0 100644 --- a/src/Cofoundry.Domain/Domain/ContentRepository/QueryResult/IDomainRepositoryQueryMutatorExtensions.cs +++ b/src/Cofoundry.Domain/Domain/ContentRepository/QueryResult/IDomainRepositoryQueryMutatorExtensions.cs @@ -1,404 +1,349 @@ namespace Cofoundry.Domain; +/// +/// Content repository extensions that allow a user to mutate the results of a query +/// after it is executed. +/// public static class IDomainRepositoryQueryMutatorExtensions { - /// - /// Maps the result of the query using the specified mapper function. The - /// mapping takes place after the original query has been executed. - /// - /// The type of the original query result. - /// The input type to map from. - /// The result type after the mutation has been applied. - /// The chained query mutator to run before this instance is applied. - /// A mapper function to run on the query result. - /// A new query mutator instance that allows for method chaining. - public static IDomainRepositoryQueryMutator Map( - this IDomainRepositoryQueryMutator innerMutator, - Func mapper - ) + extension(IDomainRepositoryQueryMutator innerMutator) { - return new DomainRepositoryQueryMutator( - innerMutator.Query, - async () => - { - var result = await innerMutator.ExecuteAsync(); - - return mapper(result); - }); - } - - /// - /// Maps the result of the query using the specified mapper function. The - /// mapping takes place after the original query has been executed. If the query - /// result is then mapping is skipped and - /// is returned. - /// - /// The type of the original query result. - /// The input type to map from. - /// The result type after the mutation has been applied. - /// The chained query mutator to run before this instance is applied. - /// A mapper function to run on the query result. - /// A new query mutator instance that allows for method chaining. - public static IDomainRepositoryQueryMutator MapWhenNotNull( - this IDomainRepositoryQueryMutator innerMutator, - Func mapper - ) - { - return new DomainRepositoryQueryMutator( - innerMutator.Query, - async () => - { - var result = await innerMutator.ExecuteAsync(); - if (result == null) + /// + /// Maps the result of the query using the specified mapper function. The + /// mapping takes place after the original query has been executed. + /// + /// The result type after the mutation has been applied. + /// A mapper function to run on the query result. + /// A new query mutator instance that allows for method chaining. + public IDomainRepositoryQueryMutator Map(Func mapper) + { + return new DomainRepositoryQueryMutator( + innerMutator.Query, + async () => { - return default; - } + var result = await innerMutator.ExecuteAsync(); - return mapper(result); - }); - } + return mapper(result); + }); + } - /// - /// Maps the result of the query using the specified mapper function. The - /// mapping takes place after the original query has been executed. - /// - /// The type of the original query result. - /// The input type to map from. - /// The result type after the mutation has been applied. - /// The chained query mutator to run before this instance is applied. - /// An async mapper function to run on the query result. - /// A new query mutator instance that allows for method chaining. - public static IDomainRepositoryQueryMutator Map( - this IDomainRepositoryQueryMutator innerMutator, - Func> mapper - ) - { - return new DomainRepositoryQueryMutator( - innerMutator.Query, - async () => - { - var result = await innerMutator.ExecuteAsync(); + /// + /// Maps the result of the query using the specified mapper function. The + /// mapping takes place after the original query has been executed. If the query + /// result is then mapping is skipped and + /// is returned. + /// + /// The result type after the mutation has been applied. + /// A mapper function to run on the query result. + /// A new query mutator instance that allows for method chaining. + public IDomainRepositoryQueryMutator MapWhenNotNull(Func mapper) + { + return new DomainRepositoryQueryMutator( + innerMutator.Query, + async () => + { + var result = await innerMutator.ExecuteAsync(); + if (result == null) + { + return default; + } - return await mapper(result); - }); - } + return mapper(result); + }); + } - /// - /// Maps the result of the query using the specified mapper function. The - /// mapping takes place after the original query has been executed. If the query - /// result is then mapping is skipped and the default value - /// of is returned. - /// - /// The type of the original query result. - /// The input type to map from. - /// The result type after the mutation has been applied. - /// The chained query mutator to run before this instance is applied. - /// An async mapper function to run on the query result. - /// A new query mutator instance that allows for method chaining. - public static IDomainRepositoryQueryMutator MapWhenNotNull( - this IDomainRepositoryQueryMutator innerMutator, - Func> mapper - ) - { - return new DomainRepositoryQueryMutator( - innerMutator.Query, - async () => - { - var result = await innerMutator.ExecuteAsync(); - if (result == null) + /// + /// Maps the result of the query using the specified mapper function. The + /// mapping takes place after the original query has been executed. + /// + /// The result type after the mutation has been applied. + /// An async mapper function to run on the query result. + /// A new query mutator instance that allows for method chaining. + public IDomainRepositoryQueryMutator Map(Func> mapper) + { + return new DomainRepositoryQueryMutator( + innerMutator.Query, + async () => { - return default; - } + var result = await innerMutator.ExecuteAsync(); - return await mapper(result); - }); - } + return await mapper(result); + }); + } - /// - /// Maps each item in the collection result of a query using the specified - /// mapper function, returning a new collection of mapped items. The mapping - /// takes place after the original query has been executed. - /// - /// The type of the original query result. - /// The type of collection item to map from. - /// The result item type after the mutation has been applied. - /// The chained query mutator to run before this instance is applied. - /// - /// A mapper function to run on each item in the query result. - /// - /// A new query mutator instance that allows for method chaining. - public static IDomainRepositoryQueryMutator> MapItem( - this IDomainRepositoryQueryMutator> innerMutator, - Func mapper - ) - { - return new DomainRepositoryQueryMutator>( - innerMutator.Query, - async () => - { - var result = await innerMutator.ExecuteAsync(); + /// + /// Maps the result of the query using the specified mapper function. The + /// mapping takes place after the original query has been executed. If the query + /// result is then mapping is skipped and the default value + /// of is returned. + /// + /// The result type after the mutation has been applied. + /// An async mapper function to run on the query result. + /// A new query mutator instance that allows for method chaining. + public IDomainRepositoryQueryMutator MapWhenNotNull(Func> mapper) + { + return new DomainRepositoryQueryMutator( + innerMutator.Query, + async () => + { + var result = await innerMutator.ExecuteAsync(); + if (result == null) + { + return default; + } - return EnumerableHelper - .Enumerate(result) - .Select(i => mapper(i)) - .ToArray(); - }); + return await mapper(result); + }); + } } - /// - /// Maps each item in the collection result of a query using the specified - /// mapper function, returning a new collection of mapped items. The mapping - /// takes place after the original query has been executed. - /// - /// The type of the original query result. - /// The type of collection item to map from. - /// The result item type after the mutation has been applied. - /// The chained query mutator to run before this instance is applied. - /// - /// A mapper function to run on each item in the query result. - /// - /// A new query mutator instance that allows for method chaining. - public static IDomainRepositoryQueryMutator> MapItem( - this IDomainRepositoryQueryMutator> innerMutator, - Func mapper - ) + extension(IDomainRepositoryQueryMutator> innerMutator) { - return new DomainRepositoryQueryMutator>( - innerMutator.Query, - async () => - { - var result = await innerMutator.ExecuteAsync(); + /// + /// Maps each item in the collection result of a query using the specified + /// mapper function, returning a new collection of mapped items. The mapping + /// takes place after the original query has been executed. + /// + /// The result item type after the mutation has been applied. + /// + /// A mapper function to run on each item in the query result. + /// + /// A new query mutator instance that allows for method chaining. + public IDomainRepositoryQueryMutator> MapItem(Func mapper) + { + return new DomainRepositoryQueryMutator>( + innerMutator.Query, + async () => + { + var result = await innerMutator.ExecuteAsync(); - return EnumerableHelper - .Enumerate(result) - .Select(i => mapper(i)) - .ToList(); - }); + return EnumerableHelper + .Enumerate(result) + .Select(i => mapper(i)) + .ToArray(); + }); + } } - /// - /// Maps each item in the collection result of a query using the specified - /// mapper function, returning a new collection of mapped items. The mapping - /// takes place after the original query has been executed. - /// - /// The type of the original query result. - /// The type of collection item to map from. - /// The result item type after the mutation has been applied. - /// The chained query mutator to run before this instance is applied. - /// - /// An async mapper function to run on each item in the query result. If the item is - /// then mapping is skipped for that item and the value of - /// is returned instead. - /// - /// A new query mutator instance that allows for method chaining. - public static IDomainRepositoryQueryMutator> MapItem( - this IDomainRepositoryQueryMutator> innerMutator, - Func> mapper - ) + extension(IDomainRepositoryQueryMutator> innerMutator) { - return new DomainRepositoryQueryMutator>( - innerMutator.Query, - async () => - { - var innerResult = await innerMutator.ExecuteAsync(); + /// + /// Maps each item in the collection result of a query using the specified + /// mapper function, returning a new collection of mapped items. The mapping + /// takes place after the original query has been executed. + /// + /// The result item type after the mutation has been applied. + /// + /// A mapper function to run on each item in the query result. + /// + /// A new query mutator instance that allows for method chaining. + public IDomainRepositoryQueryMutator> MapItem(Func mapper) + { + return new DomainRepositoryQueryMutator>( + innerMutator.Query, + async () => + { + var result = await innerMutator.ExecuteAsync(); - var result = new List(); + return EnumerableHelper + .Enumerate(result) + .Select(i => mapper(i)) + .ToList(); + }); + } - foreach (var innerItem in EnumerableHelper.Enumerate(innerResult)) + /// + /// Maps each item in the collection result of a query using the specified + /// mapper function, returning a new collection of mapped items. The mapping + /// takes place after the original query has been executed. + /// + /// The result item type after the mutation has been applied. + /// + /// An async mapper function to run on each item in the query result. If the item is + /// then mapping is skipped for that item and the value of + /// is returned instead. + /// + /// A new query mutator instance that allows for method chaining. + public IDomainRepositoryQueryMutator> MapItem(Func> mapper) + { + return new DomainRepositoryQueryMutator>( + innerMutator.Query, + async () => { - var value = await mapper(innerItem); - result.Add(value); - } + var innerResult = await innerMutator.ExecuteAsync(); - return result; - }); - } - - /// - /// - /// Maps each item in the dictionary result of a query using the specified - /// mapper function, returning a new dictionary of mapped items. The mapping - /// takes place after the original query has been executed. - /// - /// - /// Be careful using per-item mapping with async tasks, as running async tasks - /// per-item can affect performance. Always prefer mapping in batch to avoid - /// performance issues. - /// - /// - /// The type of the original query result. - /// The dictionary key type. - /// The type of value in the dictionary to map from. - /// The type to map each value in the dictionary to. - /// The chained query mutator to run before this instance is applied. - /// - /// A mapper function to run on each value in the query result. Always prefer - /// mapping in batch rather than per item if mapping requires data access or other - /// time consuming tasks. - /// - /// A new query mutator instance that allows for method chaining. - public static IDomainRepositoryQueryMutator> MapItem( - this IDomainRepositoryQueryMutator> innerMutator, - Func mapper - ) - where TKey : notnull - { - return new DomainRepositoryQueryMutator>( - innerMutator.Query, - async () => - { - var result = await innerMutator.ExecuteAsync(); + var result = new List(); - return EnumerableHelper - .Enumerate(result) - .Select(i => new + foreach (var innerItem in EnumerableHelper.Enumerate(innerResult)) { - i.Key, - Value = mapper(i.Value) - }).ToImmutableDictionary(i => i.Key, i => i.Value); - }); + var value = await mapper(innerItem); + result.Add(value); + } + + return result; + }); + } } - /// - /// Maps each item in the dictionary result of a query using the specified - /// mapper function, returning a new dictionary of mapped items. The mapping - /// takes place after the original query has been executed. - /// - /// The type of the original query result. - /// The dictionary key type. - /// The type of value in the dictionary to map from. - /// The type to map each value in the dictionary to. - /// The chained query mutator to run before this instance is applied. - /// - /// An async mapper function to run on each item in the query result. - /// - /// A new query mutator instance that allows for method chaining. - public static IDomainRepositoryQueryMutator> MapItem( - this IDomainRepositoryQueryMutator> innerMutator, - Func> mapper - ) - where TKey : notnull + extension(IDomainRepositoryQueryMutator> innerMutator) where TKey : notnull { - return new DomainRepositoryQueryMutator>( - innerMutator.Query, - async () => - { - var innerResult = await innerMutator.ExecuteAsync(); + /// + /// + /// Maps each item in the dictionary result of a query using the specified + /// mapper function, returning a new dictionary of mapped items. The mapping + /// takes place after the original query has been executed. + /// + /// + /// Be careful using per-item mapping with async tasks, as running async tasks + /// per-item can affect performance. Always prefer mapping in batch to avoid + /// performance issues. + /// + /// + /// The type to map each value in the dictionary to. + /// + /// A mapper function to run on each value in the query result. Always prefer + /// mapping in batch rather than per item if mapping requires data access or other + /// time consuming tasks. + /// + /// A new query mutator instance that allows for method chaining. + public IDomainRepositoryQueryMutator> MapItem(Func mapper) + { + return new DomainRepositoryQueryMutator>( + innerMutator.Query, + async () => + { + var result = await innerMutator.ExecuteAsync(); - var result = new Dictionary(innerResult?.Count ?? 0); + return EnumerableHelper + .Enumerate(result) + .Select(i => new + { + i.Key, + Value = mapper(i.Value) + }).ToImmutableDictionary(i => i.Key, i => i.Value); + }); + } - foreach (var innerItem in EnumerableHelper.Enumerate(innerResult)) + /// + /// Maps each item in the dictionary result of a query using the specified + /// mapper function, returning a new dictionary of mapped items. The mapping + /// takes place after the original query has been executed. + /// + /// The type to map each value in the dictionary to. + /// + /// An async mapper function to run on each item in the query result. + /// + /// A new query mutator instance that allows for method chaining. + public IDomainRepositoryQueryMutator> MapItem(Func> mapper) + { + return new DomainRepositoryQueryMutator>( + innerMutator.Query, + async () => { - var value = await mapper(innerItem.Value); - result.Add(innerItem.Key, value); - } + var innerResult = await innerMutator.ExecuteAsync(); + + var result = new Dictionary(innerResult?.Count ?? 0); + + foreach (var innerItem in EnumerableHelper.Enumerate(innerResult)) + { + var value = await mapper(innerItem.Value); + result.Add(innerItem.Key, value); + } - return result; - }); + return result; + }); + } } - /// - /// Filters items in the dictionary result to only those with keys listed in the - /// orderedKeys collection, in the order they appear in that collection. - /// Duplicates may be returned if the ordered keys collections contains - /// them. - /// - /// The type of the original query result. - /// The dictionary key type. - /// The dictionary value type. - /// The chained query mutator to run before this instance is applied. - /// - /// A collection of dictionary keys in the order that you would like the results - /// return in. Duplicate items may be returned if the orderedKeys collection - /// contains duplicates. - /// - /// A new query mutator instance that allows for method chaining. - public static IDomainRepositoryQueryMutator> FilterAndOrderByKeys( - this IDomainRepositoryQueryMutator> innerMutator, - IEnumerable orderedKeys - ) + extension(IDomainRepositoryQueryMutator> innerMutator) { - return new DomainRepositoryQueryMutator>( - innerMutator.Query, - async () => - { - var result = await innerMutator.ExecuteAsync(); - if (result == null) + /// + /// Filters items in the dictionary result to only those with keys listed in the + /// orderedKeys collection, in the order they appear in that collection. + /// Duplicates may be returned if the ordered keys collections contains + /// them. + /// + /// + /// A collection of dictionary keys in the order that you would like the results + /// return in. Duplicate items may be returned if the orderedKeys collection + /// contains duplicates. + /// + /// A new query mutator instance that allows for method chaining. + public IDomainRepositoryQueryMutator> FilterAndOrderByKeys(IEnumerable orderedKeys) + { + return new DomainRepositoryQueryMutator>( + innerMutator.Query, + async () => { - return new List(); - } + var result = await innerMutator.ExecuteAsync(); + if (result == null) + { + return new List(); + } - return result - .FilterAndOrderByKeys(orderedKeys) - .ToArray(); - }); + return result + .FilterAndOrderByKeys(orderedKeys) + .ToArray(); + }); + } } - /// - /// Maps each item in the paged result of a query using the specified - /// mapper function, returning a new PagedQueryResult of mapped items. The mapping - /// takes place after the original query has been executed. - /// - /// The type of the original query result. - /// The type of item to map from. - /// The result item type after the mutation has been applied. - /// The chained query mutator to run before this instance is applied. - /// - /// A mapper function to run on each item in the query result. - /// - /// A new query mutator instance that allows for method chaining. - public static IDomainRepositoryQueryMutator> MapItem( - this IDomainRepositoryQueryMutator> innerMutator, - Func mapper - ) + extension(IDomainRepositoryQueryMutator> innerMutator) { - return new DomainRepositoryQueryMutator>( - innerMutator.Query, - async () => - { - var result = await innerMutator.ExecuteAsync(); + /// + /// Maps each item in the paged result of a query using the specified + /// mapper function, returning a new PagedQueryResult of mapped items. The mapping + /// takes place after the original query has been executed. + /// + /// The result item type after the mutation has been applied. + /// + /// A mapper function to run on each item in the query result. + /// + /// A new query mutator instance that allows for method chaining. + public IDomainRepositoryQueryMutator> MapItem(Func mapper) + { + return new DomainRepositoryQueryMutator>( + innerMutator.Query, + async () => + { + var result = await innerMutator.ExecuteAsync(); - var mappedItems = EnumerableHelper.Enumerate(result.Items) - .Select(i => mapper(i)) - .ToArray(); + var mappedItems = EnumerableHelper.Enumerate(result.Items) + .Select(i => mapper(i)) + .ToArray(); - return result.ChangeType(mappedItems); - }); - } + return result.ChangeType(mappedItems); + }); + } - /// - /// Maps each item in the paged result of a query using the specified - /// mapper function, returning a new PagedQueryResult of mapped items. The mapping - /// takes place after the original query has been executed. - /// - /// The type of the original query result. - /// The type of item to map from. - /// The result item type after the mutation has been applied. - /// The chained query mutator to run before this instance is applied. - /// - /// An async mapper function to run on each item in the query result. - /// - /// A new query mutator instance that allows for method chaining. - public static IDomainRepositoryQueryMutator> MapItem( - this IDomainRepositoryQueryMutator> innerMutator, - Func> mapper - ) - { - return new DomainRepositoryQueryMutator>( - innerMutator.Query, - async () => - { - var innerResult = await innerMutator.ExecuteAsync(); + /// + /// Maps each item in the paged result of a query using the specified + /// mapper function, returning a new PagedQueryResult of mapped items. The mapping + /// takes place after the original query has been executed. + /// + /// The result item type after the mutation has been applied. + /// + /// An async mapper function to run on each item in the query result. + /// + /// A new query mutator instance that allows for method chaining. + public IDomainRepositoryQueryMutator> MapItem(Func> mapper) + { + return new DomainRepositoryQueryMutator>( + innerMutator.Query, + async () => + { + var innerResult = await innerMutator.ExecuteAsync(); - var mappedItems = new List(innerResult.Items.Count); + var mappedItems = new List(innerResult.Items.Count); - foreach (var item in innerResult.Items) - { - var mappedItem = await mapper(item); - mappedItems.Add(mappedItem); - } + foreach (var item in innerResult.Items) + { + var mappedItem = await mapper(item); + mappedItems.Add(mappedItem); + } - return innerResult.ChangeType(mappedItems); - }); + return innerResult.ChangeType(mappedItems); + }); + } } } diff --git a/src/Cofoundry.Domain/Domain/CustomEntities/ContentRepository/ContentRepositoryCustomEntityExtensions.cs b/src/Cofoundry.Domain/Domain/CustomEntities/ContentRepository/ContentRepositoryCustomEntityExtensions.cs index 678848c81..39b445a60 100644 --- a/src/Cofoundry.Domain/Domain/CustomEntities/ContentRepository/ContentRepositoryCustomEntityExtensions.cs +++ b/src/Cofoundry.Domain/Domain/CustomEntities/ContentRepository/ContentRepositoryCustomEntityExtensions.cs @@ -1,27 +1,36 @@ -using Cofoundry.Domain.Extendable; +using Cofoundry.Domain.Extendable; using Cofoundry.Domain.Internal; namespace Cofoundry.Domain; +/// +/// Content repository extension methods for custom entities. +/// public static class ContentRepositoryCustomEntityExtensions { - /// - /// Custom entities are a flexible system for developer defined - /// data structures which can be fully managed in the admin panel - /// with minimal configuration. - /// - public static IContentRepositoryCustomEntityRepository CustomEntities(this IContentRepository contentRepository) + extension(IContentRepository contentRepository) { - return new ContentRepositoryCustomEntityRepository(contentRepository.AsExtendableContentRepository()); + /// + /// Custom entities are a flexible system for developer defined + /// data structures which can be fully managed in the admin panel + /// with minimal configuration. + /// + public IContentRepositoryCustomEntityRepository CustomEntities() + { + return new ContentRepositoryCustomEntityRepository(contentRepository.AsExtendableContentRepository()); + } } - /// - /// Custom entities are a flexible system for developer defined - /// data structures which can be fully managed in the admin panel - /// with minimal configuration. - /// - public static IAdvancedContentRepositoryCustomEntityRepository CustomEntities(this IAdvancedContentRepository contentRepository) + extension(IAdvancedContentRepository contentRepository) { - return new AdvancedContentRepositoryCustomEntityRepository(contentRepository.AsExtendableContentRepository()); + /// + /// Custom entities are a flexible system for developer defined + /// data structures which can be fully managed in the admin panel + /// with minimal configuration. + /// + public IAdvancedContentRepositoryCustomEntityRepository CustomEntities() + { + return new AdvancedContentRepositoryCustomEntityRepository(contentRepository.AsExtendableContentRepository()); + } } } diff --git a/src/Cofoundry.Domain/Domain/CustomEntities/Models/Definition/ICustomEntityDefinitionExtensions.cs b/src/Cofoundry.Domain/Domain/CustomEntities/Models/Definition/ICustomEntityDefinitionExtensions.cs index 4e1a6d529..4267898f8 100644 --- a/src/Cofoundry.Domain/Domain/CustomEntities/Models/Definition/ICustomEntityDefinitionExtensions.cs +++ b/src/Cofoundry.Domain/Domain/CustomEntities/Models/Definition/ICustomEntityDefinitionExtensions.cs @@ -1,56 +1,60 @@ -using System.Reflection; +using System.Reflection; namespace Cofoundry.Domain; +/// +/// Content repository extension methods for custom entity definitions. +/// public static class ICustomEntityDefinitionExtensions { - public static Type GetDataModelType(this TDefition definition) - where TDefition : ICustomEntityDefinition + extension(TDefition definition) where TDefition : ICustomEntityDefinition { - var dataModelType = definition - .GetType() - .GetInterfaces() - .Select(t => t.GetTypeInfo()) - .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICustomEntityDefinition<>)) - .Select(i => i.GetGenericArguments().Single()) - .SingleOrDefault(); - - if (dataModelType == null) + public Type GetDataModelType() { - var message = definition + " does not inherit from ICustomEntityDefinition. Do not inherit from ICustomEntityDefinition directly, but instead use the generic version."; - throw new InvalidCustomEntityDefinitionException(message, definition); - } + var dataModelType = definition + .GetType() + .GetInterfaces() + .Select(t => t.GetTypeInfo()) + .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICustomEntityDefinition<>)) + .Select(i => i.GetGenericArguments().Single()) + .SingleOrDefault(); - return dataModelType; - } + if (dataModelType == null) + { + var message = definition + " does not inherit from ICustomEntityDefinition. Do not inherit from ICustomEntityDefinition directly, but instead use the generic version."; + throw new InvalidCustomEntityDefinitionException(message, definition); + } - /// - /// Gets the combined term descriptions for the custom entity, merging - /// any custom terms with the defaults. - /// - public static IReadOnlyDictionary GetTerms(this TDefition definition) - where TDefition : ICustomEntityDefinition - { - if (definition is ICustomizedTermCustomEntityDefinition customEntityTermDefinition - && customEntityTermDefinition.CustomTerms != null) - { - var terms = customEntityTermDefinition - .CustomTerms - .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + return dataModelType; + } - foreach (var defaultTerm in CustomizableCustomEntityTermKeys.Defaults) + /// + /// Gets the combined term descriptions for the custom entity, merging + /// any custom terms with the defaults. + /// + public IReadOnlyDictionary GetTerms() + { + if (definition is ICustomizedTermCustomEntityDefinition customEntityTermDefinition + && customEntityTermDefinition.CustomTerms != null) { - if (!terms.ContainsKey(defaultTerm.Key)) + var terms = customEntityTermDefinition + .CustomTerms + .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + + foreach (var defaultTerm in CustomizableCustomEntityTermKeys.Defaults) { - terms.Add(defaultTerm.Key, defaultTerm.Value); + if (!terms.ContainsKey(defaultTerm.Key)) + { + terms.Add(defaultTerm.Key, defaultTerm.Value); + } } - } - return terms; - } - else - { - return CustomizableCustomEntityTermKeys.Defaults; + return terms; + } + else + { + return CustomizableCustomEntityTermKeys.Defaults; + } } } } diff --git a/src/Cofoundry.Domain/Domain/CustomEntities/Permissions/IPermissionSetBuilderCustomEntityExtensions.cs b/src/Cofoundry.Domain/Domain/CustomEntities/Permissions/IPermissionSetBuilderCustomEntityExtensions.cs index b9cdde860..21ef597c9 100644 --- a/src/Cofoundry.Domain/Domain/CustomEntities/Permissions/IPermissionSetBuilderCustomEntityExtensions.cs +++ b/src/Cofoundry.Domain/Domain/CustomEntities/Permissions/IPermissionSetBuilderCustomEntityExtensions.cs @@ -4,56 +4,50 @@ namespace Cofoundry.Domain; +/// +/// extension methods for custom entities. +/// public static class IPermissionSetBuilderCustomEntityExtensions { - /// - /// Configure the builder to include all permissions for a specific custom entity type. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder IncludeCustomEntity(this IPermissionSetBuilder builder) - where TCustomEntityDefinition : ICustomEntityDefinition + extension(IPermissionSetBuilder builder) { - return Run(builder, null, true); - } + /// + /// Configure the builder to include all permissions for a specific custom entity type. + /// + public IPermissionSetBuilder IncludeCustomEntity() + where TCustomEntityDefinition : ICustomEntityDefinition + { + return Run(builder, null, true); + } - /// - /// Configure the builder to include permissions for a custom entity type. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to include. - public static IPermissionSetBuilder IncludeCustomEntity(this IPermissionSetBuilder builder, Action configure) - where TCustomEntityDefinition : ICustomEntityDefinition - { - return Run(builder, configure, true); - } + /// + /// Configure the builder to include permissions for a custom entity type. + /// + /// A configuration action to select which permissions to include. + public IPermissionSetBuilder IncludeCustomEntity(Action configure) + where TCustomEntityDefinition : ICustomEntityDefinition + { + return Run(builder, configure, true); + } - /// - /// Configure the builder to exclude all permissions for a specific custom entity type. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder ExcludeCustomEntity(this IPermissionSetBuilder builder) - where TCustomEntityDefinition : ICustomEntityDefinition - { - return Run(builder, null, false); - } + /// + /// Configure the builder to exclude all permissions for a specific custom entity type. + /// + public IPermissionSetBuilder ExcludeCustomEntity() + where TCustomEntityDefinition : ICustomEntityDefinition + { + return Run(builder, null, false); + } - /// - /// Configure the builder to exclude permissions for a custom entity type. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to exclude. - public static IPermissionSetBuilder ExcludeCustomEntity(this IPermissionSetBuilder builder, Action configure) - where TCustomEntityDefinition : ICustomEntityDefinition - { - return Run(builder, configure, false); + /// + /// Configure the builder to exclude permissions for a custom entity type. + /// + /// A configuration action to select which permissions to exclude. + public IPermissionSetBuilder ExcludeCustomEntity(Action configure) + where TCustomEntityDefinition : ICustomEntityDefinition + { + return Run(builder, configure, false); + } } private static IPermissionSetBuilder Run(IPermissionSetBuilder builder, Action? configure, bool isIncludeOperation) diff --git a/src/Cofoundry.Domain/Domain/Dashboards/Permissions/IPermissionSetBuilderDashboardExtensions.cs b/src/Cofoundry.Domain/Domain/Dashboards/Permissions/IPermissionSetBuilderDashboardExtensions.cs index b34222637..99838873a 100644 --- a/src/Cofoundry.Domain/Domain/Dashboards/Permissions/IPermissionSetBuilderDashboardExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Dashboards/Permissions/IPermissionSetBuilderDashboardExtensions.cs @@ -2,52 +2,46 @@ namespace Cofoundry.Domain; +/// +/// extension methods for the admin dashboard. +/// public static class IPermissionSetBuilderDashboardExtensions { - /// - /// Configure the builder to include all permissions for the admin dashboard. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder IncludeDashboard(this IPermissionSetBuilder builder) + extension(IPermissionSetBuilder builder) { - return Run(builder, null, true); - } + /// + /// Configure the builder to include all permissions for the admin dashboard. + /// + public IPermissionSetBuilder IncludeDashboard() + { + return Run(builder, null, true); + } - /// - /// Configure the builder to include permissions for the admin dashboard. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to include. - public static IPermissionSetBuilder IncludeDashboard(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, true); - } + /// + /// Configure the builder to include permissions for the admin dashboard. + /// + /// A configuration action to select which permissions to include. + public IPermissionSetBuilder IncludeDashboard(Action configure) + { + return Run(builder, configure, true); + } - /// - /// Configure the builder to exclude all permissions for the admin dashboard. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder ExcludeDashboard(this IPermissionSetBuilder builder) - { - return Run(builder, null, false); - } + /// + /// Configure the builder to exclude all permissions for the admin dashboard. + /// + public IPermissionSetBuilder ExcludeDashboard() + { + return Run(builder, null, false); + } - /// - /// Configure the builder to exclude permissions for the admin dashboard. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to exclude. - public static IPermissionSetBuilder ExcludeDashboard(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, false); + /// + /// Configure the builder to exclude permissions for the admin dashboard. + /// + /// A configuration action to select which permissions to exclude. + public IPermissionSetBuilder ExcludeDashboard(Action configure) + { + return Run(builder, configure, false); + } } private static IPermissionSetBuilder Run(IPermissionSetBuilder builder, Action? configure, bool isIncludeOperation) diff --git a/src/Cofoundry.Domain/Domain/DocumentAssets/ContentRepositoryExtensions/ContentRepositoryDocumentAssetExtensions.cs b/src/Cofoundry.Domain/Domain/DocumentAssets/ContentRepositoryExtensions/ContentRepositoryDocumentAssetExtensions.cs index 1e8f85b98..8b004e425 100644 --- a/src/Cofoundry.Domain/Domain/DocumentAssets/ContentRepositoryExtensions/ContentRepositoryDocumentAssetExtensions.cs +++ b/src/Cofoundry.Domain/Domain/DocumentAssets/ContentRepositoryExtensions/ContentRepositoryDocumentAssetExtensions.cs @@ -1,23 +1,32 @@ -using Cofoundry.Domain.Extendable; +using Cofoundry.Domain.Extendable; using Cofoundry.Domain.Internal; namespace Cofoundry.Domain; +/// +/// Content repository extension methods for document assets. +/// public static class ContentRepositoryDocumentAssetExtensions { - /// - /// Queries and commands relating to document assets. - /// - public static IContentRepositoryDocumentAssetRepository DocumentAssets(this IContentRepository contentRepository) + extension(IContentRepository contentRepository) { - return new ContentRepositoryDocumentAssetRepository(contentRepository.AsExtendableContentRepository()); + /// + /// Queries and commands relating to document assets. + /// + public IContentRepositoryDocumentAssetRepository DocumentAssets() + { + return new ContentRepositoryDocumentAssetRepository(contentRepository.AsExtendableContentRepository()); + } } - /// - /// Queries and commands relating to document assets. - /// - public static IAdvancedContentRepositoryDocumentAssetRepository DocumentAssets(this IAdvancedContentRepository contentRepository) + extension(IAdvancedContentRepository contentRepository) { - return new AdvancedContentRepositoryDocumentAssetRepository(contentRepository.AsExtendableContentRepository()); + /// + /// Queries and commands relating to document assets. + /// + public IAdvancedContentRepositoryDocumentAssetRepository DocumentAssets() + { + return new AdvancedContentRepositoryDocumentAssetRepository(contentRepository.AsExtendableContentRepository()); + } } } diff --git a/src/Cofoundry.Domain/Domain/DocumentAssets/Permissions/IPermissionSetBuilderDocumentAssetExtensions.cs b/src/Cofoundry.Domain/Domain/DocumentAssets/Permissions/IPermissionSetBuilderDocumentAssetExtensions.cs index 04c92bac4..7a103d54d 100644 --- a/src/Cofoundry.Domain/Domain/DocumentAssets/Permissions/IPermissionSetBuilderDocumentAssetExtensions.cs +++ b/src/Cofoundry.Domain/Domain/DocumentAssets/Permissions/IPermissionSetBuilderDocumentAssetExtensions.cs @@ -2,52 +2,46 @@ namespace Cofoundry.Domain; +/// +/// extension methods for document assets. +/// public static class IPermissionSetBuilderDocumentAssetExtensions { - /// - /// Configure the builder to include all permissions for document assets. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder IncludeDocumentAsset(this IPermissionSetBuilder builder) + extension(IPermissionSetBuilder builder) { - return Run(builder, null, true); - } + /// + /// Configure the builder to include all permissions for document assets. + /// + public IPermissionSetBuilder IncludeDocumentAsset() + { + return Run(builder, null, true); + } - /// - /// Configure the builder to include permissions for document assets. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to include. - public static IPermissionSetBuilder IncludeDocumentAsset(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, true); - } + /// + /// Configure the builder to include permissions for document assets. + /// + /// A configuration action to select which permissions to include. + public IPermissionSetBuilder IncludeDocumentAsset(Action configure) + { + return Run(builder, configure, true); + } - /// - /// Configure the builder to exclude all permissions for document assets. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder ExcludeDocumentAsset(this IPermissionSetBuilder builder) - { - return Run(builder, null, false); - } + /// + /// Configure the builder to exclude all permissions for document assets. + /// + public IPermissionSetBuilder ExcludeDocumentAsset() + { + return Run(builder, null, false); + } - /// - /// Configure the builder to exclude permissions for document assets. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to exclude. - public static IPermissionSetBuilder ExcludeDocumentAsset(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, false); + /// + /// Configure the builder to exclude permissions for document assets. + /// + /// A configuration action to select which permissions to exclude. + public IPermissionSetBuilder ExcludeDocumentAsset(Action configure) + { + return Run(builder, configure, false); + } } private static IPermissionSetBuilder Run(IPermissionSetBuilder builder, Action? configure, bool isIncludeOperation) diff --git a/src/Cofoundry.Domain/Domain/ImageAssets/ContentRepository/ContentRepositoryImageAssetExtensions.cs b/src/Cofoundry.Domain/Domain/ImageAssets/ContentRepository/ContentRepositoryImageAssetExtensions.cs index b44bc6099..22959d4be 100644 --- a/src/Cofoundry.Domain/Domain/ImageAssets/ContentRepository/ContentRepositoryImageAssetExtensions.cs +++ b/src/Cofoundry.Domain/Domain/ImageAssets/ContentRepository/ContentRepositoryImageAssetExtensions.cs @@ -1,23 +1,32 @@ -using Cofoundry.Domain.Extendable; +using Cofoundry.Domain.Extendable; using Cofoundry.Domain.Internal; namespace Cofoundry.Domain; +/// +/// Content repository extension methods for image assets. +/// public static class ContentRepositoryImageAssetExtensions { - /// - /// Queries and commands relating to image assets. - /// - public static IContentRepositoryImageAssetRepository ImageAssets(this IContentRepository contentRepository) + extension(IContentRepository contentRepository) { - return new ContentRepositoryImageAssetRepository(contentRepository.AsExtendableContentRepository()); + /// + /// Queries and commands relating to image assets. + /// + public IContentRepositoryImageAssetRepository ImageAssets() + { + return new ContentRepositoryImageAssetRepository(contentRepository.AsExtendableContentRepository()); + } } - /// - /// Queries and commands relating to image assets. - /// - public static IAdvancedContentRepositoryImageAssetRepository ImageAssets(this IAdvancedContentRepository contentRepository) + extension(IAdvancedContentRepository contentRepository) { - return new AdvancedContentRepositoryImageAssetRepository(contentRepository.AsExtendableContentRepository()); + /// + /// Queries and commands relating to image assets. + /// + public IAdvancedContentRepositoryImageAssetRepository ImageAssets() + { + return new AdvancedContentRepositoryImageAssetRepository(contentRepository.AsExtendableContentRepository()); + } } } diff --git a/src/Cofoundry.Domain/Domain/ImageAssets/Models/Resizing/IImageResizeSettingsExtensions.cs b/src/Cofoundry.Domain/Domain/ImageAssets/Models/Resizing/IImageResizeSettingsExtensions.cs index a9fed863b..868ca8b1a 100644 --- a/src/Cofoundry.Domain/Domain/ImageAssets/Models/Resizing/IImageResizeSettingsExtensions.cs +++ b/src/Cofoundry.Domain/Domain/ImageAssets/Models/Resizing/IImageResizeSettingsExtensions.cs @@ -2,67 +2,73 @@ namespace Cofoundry.Domain; +/// +/// Extension methods for . +/// public static class IImageResizeSettingsExtensions { - /// - /// Determines if the settings indicate that an image asset should - /// be resized. If width and hight are not specified or the dimensions - /// in the settings are the same as the image then false will be returned. - /// - /// - /// Settings instance to query. - /// - /// The asset to check. Cannot be null. - public static bool RequiresResizing(this IImageResizeSettings settings, IImageAssetRenderable asset) + extension(IImageResizeSettings settings) { - ArgumentNullException.ThrowIfNull(settings); - ArgumentNullException.ThrowIfNull(asset); - - if ((settings.Width < 1 && settings.Height < 1) - || (settings.Width == asset.Width && settings.Height == asset.Height)) + /// + /// Determines if the settings indicate that an image asset should + /// be resized. If width and hight are not specified or the dimensions + /// in the settings are the same as the image then false will be returned. + /// + /// + /// Settings instance to query. + /// + /// The asset to check. Cannot be null. + public bool RequiresResizing(IImageAssetRenderable asset) { - return false; - } + ArgumentNullException.ThrowIfNull(settings); + ArgumentNullException.ThrowIfNull(asset); - return true; - } + if ((settings.Width < 1 && settings.Height < 1) + || (settings.Width == asset.Width && settings.Height == asset.Height)) + { + return false; + } - /// - /// Indicates if the resize width has been specified i.e. is greater than 0. - /// - /// - /// Settings instance to query. - /// - public static bool IsWidthSet(this IImageResizeSettings settings) - { - return settings.Width > 0; - } + return true; + } - /// - /// Indicates if the resize height has been specified i.e. is greater than 0. - /// - /// - /// Settings instance to query. - /// - public static bool IsHeightSet(this IImageResizeSettings settings) - { - return settings.Height > 0; - } + /// + /// Indicates if the resize width has been specified i.e. is greater than 0. + /// + /// + /// Settings instance to query. + /// + public bool IsWidthSet() + { + return settings.Width > 0; + } - /// - /// Creates a short string unique to the settings which can be used - /// as a file name. - /// - /// - /// Settings instance to map parameters from. - /// - public static string CreateCacheFileName(this IImageResizeSettings settings) - { - ArgumentNullException.ThrowIfNull(settings); + /// + /// Indicates if the resize height has been specified i.e. is greater than 0. + /// + /// + /// Settings instance to query. + /// + public bool IsHeightSet() + { + return settings.Height > 0; + } + + /// + /// Creates a short string unique to the settings which can be used + /// as a file name. + /// + /// + /// Settings instance to map parameters from. + /// + public string CreateCacheFileName() + { + ArgumentNullException.ThrowIfNull(settings); - var fileName = $"w{settings.Width}h{settings.Height}c{settings.Mode}s{settings.Scale}bg{settings.BackgroundColor}a{settings.Anchor}"; - fileName = WebUtility.UrlEncode(fileName); + var fileName = $"w{settings.Width}h{settings.Height}c{settings.Mode}s{settings.Scale}bg{settings.BackgroundColor}a{settings.Anchor}"; + fileName = WebUtility.UrlEncode(fileName); - return fileName; + return fileName; + } } } diff --git a/src/Cofoundry.Domain/Domain/ImageAssets/Permissions/IPermissionSetBuilderImageAssetExtensions.cs b/src/Cofoundry.Domain/Domain/ImageAssets/Permissions/IPermissionSetBuilderImageAssetExtensions.cs index a68ffae9e..cfb1cdc11 100644 --- a/src/Cofoundry.Domain/Domain/ImageAssets/Permissions/IPermissionSetBuilderImageAssetExtensions.cs +++ b/src/Cofoundry.Domain/Domain/ImageAssets/Permissions/IPermissionSetBuilderImageAssetExtensions.cs @@ -2,52 +2,46 @@ namespace Cofoundry.Domain; +/// +/// Content repository extension methods for image assets. +/// public static class IPermissionSetBuilderImageAssetExtensions { - /// - /// Configure the builder to include all permissions for image assets. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder IncludeImageAsset(this IPermissionSetBuilder builder) + extension(IPermissionSetBuilder builder) { - return Run(builder, null, true); - } + /// + /// Configure the builder to include all permissions for image assets. + /// + public IPermissionSetBuilder IncludeImageAsset() + { + return Run(builder, null, true); + } - /// - /// Configure the builder to include permissions for image assets. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to include. - public static IPermissionSetBuilder IncludeImageAsset(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, true); - } + /// + /// Configure the builder to include permissions for image assets. + /// + /// A configuration action to select which permissions to include. + public IPermissionSetBuilder IncludeImageAsset(Action configure) + { + return Run(builder, configure, true); + } - /// - /// Configure the builder to exclude all permissions for image assets. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder ExcludeImageAsset(this IPermissionSetBuilder builder) - { - return Run(builder, null, false); - } + /// + /// Configure the builder to exclude all permissions for image assets. + /// + public IPermissionSetBuilder ExcludeImageAsset() + { + return Run(builder, null, false); + } - /// - /// Configure the builder to exclude permissions for image assets. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to exclude. - public static IPermissionSetBuilder ExcludeImageAsset(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, false); + /// + /// Configure the builder to exclude permissions for image assets. + /// + /// A configuration action to select which permissions to exclude. + public IPermissionSetBuilder ExcludeImageAsset(Action configure) + { + return Run(builder, configure, false); + } } private static IPermissionSetBuilder Run(IPermissionSetBuilder builder, Action? configure, bool isIncludeOperation) diff --git a/src/Cofoundry.Domain/Domain/ModelMetadata/Attributes/ModelMetadataExtensions.cs b/src/Cofoundry.Domain/Domain/ModelMetadata/Attributes/ModelMetadataExtensions.cs index 209c92727..b9c9a4d5b 100644 --- a/src/Cofoundry.Domain/Domain/ModelMetadata/Attributes/ModelMetadataExtensions.cs +++ b/src/Cofoundry.Domain/Domain/ModelMetadata/Attributes/ModelMetadataExtensions.cs @@ -3,105 +3,93 @@ namespace Cofoundry.Domain; /// -/// Helpers to make it easier to work with the ModelMetaData class +/// Extension methods to make it easier to work with the ModelMetaData class /// public static class ModelMetadataExtensions { - /// - /// Adds a value to the AdditionalValues collection if the specified condition is true. - /// - /// - /// Meta data to add to. - /// - /// Result of a condition which will indicate whether to add the value or not - /// The name of the property (key) to add to the collection. - /// The value to add to the collection. - /// ModelMetadata instance for method chaining - public static DisplayMetadata AddAdditionalValueIf(this DisplayMetadata modelMetaData, bool condition, string property, object value) + extension(DisplayMetadata modelMetaData) { - if (condition) + /// + /// Adds a value to the AdditionalValues collection if the specified condition is true. + /// + /// Result of a condition which will indicate whether to add the value or not + /// The name of the property (key) to add to the collection. + /// The value to add to the collection. + /// ModelMetadata instance for method chaining + public DisplayMetadata AddAdditionalValueIf(bool condition, string property, object value) { - modelMetaData.AdditionalValues.Add(property, value); - } + if (condition) + { + modelMetaData.AdditionalValues.Add(property, value); + } - return modelMetaData; - } + return modelMetaData; + } - /// - /// Adds a value to the AdditionalValues collection if the value is not null - /// - /// - /// Meta data to add to. - /// - /// The name of the property (key) to add to the collection. - /// The value to add to the collection. - /// ModelMetadata instance for method chaining - public static DisplayMetadata AddAdditionalValueIfNotNull(this DisplayMetadata modelMetaData, string property, object? value) - { - if (value != null) + /// + /// Adds a value to the AdditionalValues collection if the value is not null + /// + /// The name of the property (key) to add to the collection. + /// The value to add to the collection. + /// ModelMetadata instance for method chaining + public DisplayMetadata AddAdditionalValueIfNotNull(string property, object? value) { - modelMetaData.AdditionalValues.Add(property, value); - } + if (value != null) + { + modelMetaData.AdditionalValues.Add(property, value); + } - return modelMetaData; - } + return modelMetaData; + } - /// - /// Adds a value to the AdditionalValues collection if the value is not null or empty (default value) - /// - /// - /// Meta data to add to. - /// - /// The name of the property (key) to add to the collection. - /// The value to add to the collection. - /// ModelMetadata instance for method chaining - public static DisplayMetadata AddAdditionalValueIfNotEmpty(this DisplayMetadata modelMetaData, string property, T? value) - { - if (value != null && !EqualityComparer.Default.Equals(value, default)) + /// + /// Adds a value to the AdditionalValues collection if the value is not null or empty (default value) + /// + /// The name of the property (key) to add to the collection. + /// The value to add to the collection. + /// ModelMetadata instance for method chaining + public DisplayMetadata AddAdditionalValueIfNotEmpty(string property, T? value) { - modelMetaData.AdditionalValues.Add(property, value); - } + if (value != null && !EqualityComparer.Default.Equals(value, default)) + { + modelMetaData.AdditionalValues.Add(property, value); + } - return modelMetaData; - } + return modelMetaData; + } - /// - /// Adds a collection value to the AdditionalValues collection if the collection is not null or empty - /// - /// - /// Meta data to add to. - /// - /// The name of the property (key) to add to the collection. - /// The collection value to add to the collection. - /// ModelMetadata instance for method chaining - public static DisplayMetadata AddAdditionalValueIfNotEmpty(this DisplayMetadata modelMetaData, string property, IReadOnlyCollection? value) - { - if (value != null && value.Count != 0) + /// + /// Adds a collection value to the AdditionalValues collection if the collection is not null or empty + /// + /// The name of the property (key) to add to the collection. + /// The collection value to add to the collection. + /// ModelMetadata instance for method chaining + public DisplayMetadata AddAdditionalValueIfNotEmpty(string property, IReadOnlyCollection? value) { - modelMetaData.AdditionalValues.Add(property, value); - } + if (value != null && value.Count != 0) + { + modelMetaData.AdditionalValues.Add(property, value); + } - return modelMetaData; - } + return modelMetaData; + } - /// - /// Adds a value to the AdditionalValues collection with a formatted validation message taken from a - /// ValidationAttribute. Intended to be used as a shortcut for adding validation messages associated with - /// ValidationAttributes in an implementation of IMetadataAttribute - /// - /// - /// Meta data to add to. - /// - /// The name of the property (key) to add to the collection. - /// The value to add to the collection. - /// The attribute from which the validation message will be extracted. - /// ModelMetadata instance for method chaining - public static DisplayMetadata AddAdditionalValueWithValidationMessage(this DisplayMetadata modelMetaData, string key, object value, ValidationAttribute attribute) - { - var name = modelMetaData.DisplayName?.Invoke() ?? string.Empty; - modelMetaData.AdditionalValues.Add(key, value); - modelMetaData.AdditionalValues.Add(key + "ValMsg", attribute.FormatErrorMessage(name)); + /// + /// Adds a value to the AdditionalValues collection with a formatted validation message taken from a + /// ValidationAttribute. Intended to be used as a shortcut for adding validation messages associated with + /// ValidationAttributes in an implementation of IMetadataAttribute + /// + /// The name of the property (key) to add to the collection. + /// The value to add to the collection. + /// The attribute from which the validation message will be extracted. + /// ModelMetadata instance for method chaining + public DisplayMetadata AddAdditionalValueWithValidationMessage(string key, object value, ValidationAttribute attribute) + { + var name = modelMetaData.DisplayName?.Invoke() ?? string.Empty; + modelMetaData.AdditionalValues.Add(key, value); + modelMetaData.AdditionalValues.Add(key + "ValMsg", attribute.FormatErrorMessage(name)); - return modelMetaData; + return modelMetaData; + } } } diff --git a/src/Cofoundry.Domain/Domain/PageBlockTypes/ContentRepository/ContentRepositoryPageBlockTypeExtensions.cs b/src/Cofoundry.Domain/Domain/PageBlockTypes/ContentRepository/ContentRepositoryPageBlockTypeExtensions.cs index e28bfa762..6f8be535a 100644 --- a/src/Cofoundry.Domain/Domain/PageBlockTypes/ContentRepository/ContentRepositoryPageBlockTypeExtensions.cs +++ b/src/Cofoundry.Domain/Domain/PageBlockTypes/ContentRepository/ContentRepositoryPageBlockTypeExtensions.cs @@ -1,19 +1,25 @@ -using Cofoundry.Domain.Extendable; +using Cofoundry.Domain.Extendable; using Cofoundry.Domain.Internal; namespace Cofoundry.Domain; +/// +/// Content repository extension methods for page content blocks. +/// public static class ContentRepositoryPageBlockTypeExtensions { - /// - /// Page block types represent a type of content that can be inserted into a content - /// region of a page which could be simple content like 'RawHtml', 'Image' or - /// 'PlainText'. Custom and more complex block types can be defined by a - /// developer. Block types are typically created when the application - /// starts up in the auto-update process. - /// - public static IAdvancedContentRepositoryPageBlockTypeRepository PageBlockTypes(this IAdvancedContentRepository contentRepository) + extension(IAdvancedContentRepository contentRepository) { - return new ContentRepositoryPageBlockTypeRepository(contentRepository.AsExtendableContentRepository()); + /// + /// Page block types represent a type of content that can be inserted into a content + /// region of a page which could be simple content like 'RawHtml', 'Image' or + /// 'PlainText'. Custom and more complex block types can be defined by a + /// developer. Block types are typically created when the application + /// starts up in the auto-update process. + /// + public IAdvancedContentRepositoryPageBlockTypeRepository PageBlockTypes() + { + return new ContentRepositoryPageBlockTypeRepository(contentRepository.AsExtendableContentRepository()); + } } } diff --git a/src/Cofoundry.Domain/Domain/PageDirectories/ContentRepository/ContentRepositoryPageDirectoryExtensions.cs b/src/Cofoundry.Domain/Domain/PageDirectories/ContentRepository/ContentRepositoryPageDirectoryExtensions.cs index 9ffcf8ea7..77e836aa3 100644 --- a/src/Cofoundry.Domain/Domain/PageDirectories/ContentRepository/ContentRepositoryPageDirectoryExtensions.cs +++ b/src/Cofoundry.Domain/Domain/PageDirectories/ContentRepository/ContentRepositoryPageDirectoryExtensions.cs @@ -1,23 +1,32 @@ -using Cofoundry.Domain.Extendable; +using Cofoundry.Domain.Extendable; using Cofoundry.Domain.Internal; namespace Cofoundry.Domain; +/// +/// Content repository extension methods for page directories. +/// public static class ContentRepositoryPageDirectoryExtensions { - /// - /// PageDirectories represent a folder in the dynamic web page hierarchy. - /// - public static IContentRepositoryPageDirectoryRepository PageDirectories(this IContentRepository contentRepository) + extension(IContentRepository contentRepository) { - return new ContentRepositoryPageDirectoryRepository(contentRepository.AsExtendableContentRepository()); + /// + /// PageDirectories represent a folder in the dynamic web page hierarchy. + /// + public IContentRepositoryPageDirectoryRepository PageDirectories() + { + return new ContentRepositoryPageDirectoryRepository(contentRepository.AsExtendableContentRepository()); + } } - /// - /// PageDirectories represent a folder in the dynamic web page hierarchy. - /// - public static IAdvancedContentRepositoryPageDirectoryRepository PageDirectories(this IAdvancedContentRepository contentRepository) + extension(IAdvancedContentRepository contentRepository) { - return new AdvancedContentRepositoryPageDirectoryRepository(contentRepository.AsExtendableContentRepository()); + /// + /// PageDirectories represent a folder in the dynamic web page hierarchy. + /// + public IAdvancedContentRepositoryPageDirectoryRepository PageDirectories() + { + return new AdvancedContentRepositoryPageDirectoryRepository(contentRepository.AsExtendableContentRepository()); + } } } diff --git a/src/Cofoundry.Domain/Domain/PageDirectories/Permissions/IPermissionSetBuilderPageDirectoryExtensions.cs b/src/Cofoundry.Domain/Domain/PageDirectories/Permissions/IPermissionSetBuilderPageDirectoryExtensions.cs index 0044af35c..8451116f6 100644 --- a/src/Cofoundry.Domain/Domain/PageDirectories/Permissions/IPermissionSetBuilderPageDirectoryExtensions.cs +++ b/src/Cofoundry.Domain/Domain/PageDirectories/Permissions/IPermissionSetBuilderPageDirectoryExtensions.cs @@ -2,52 +2,46 @@ namespace Cofoundry.Domain; +/// +/// extension methods for page directories. +/// public static class IPermissionSetBuilderPageDirectoryExtensions { - /// - /// Configure the builder to include all permissions for page directories. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder IncludePageDirectory(this IPermissionSetBuilder builder) + extension(IPermissionSetBuilder builder) { - return Run(builder, null, true); - } + /// + /// Configure the builder to include all permissions for page directories. + /// + public IPermissionSetBuilder IncludePageDirectory() + { + return Run(builder, null, true); + } - /// - /// Configure the builder to include permissions for page directory entities. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to include. - public static IPermissionSetBuilder IncludePageDirectory(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, true); - } + /// + /// Configure the builder to include permissions for page directory entities. + /// + /// A configuration action to select which permissions to include. + public IPermissionSetBuilder IncludePageDirectory(Action configure) + { + return Run(builder, configure, true); + } - /// - /// Configure the builder to exclude all permissions for page directories. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder ExcludePageDirectory(this IPermissionSetBuilder builder) - { - return Run(builder, null, false); - } + /// + /// Configure the builder to exclude all permissions for page directories. + /// + public IPermissionSetBuilder ExcludePageDirectory() + { + return Run(builder, null, false); + } - /// - /// Configure the builder to exclude permissions for page directory entities. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to exclude. - public static IPermissionSetBuilder ExcludePageDirectory(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, false); + /// + /// Configure the builder to exclude permissions for page directory entities. + /// + /// A configuration action to select which permissions to exclude. + public IPermissionSetBuilder ExcludePageDirectory(Action configure) + { + return Run(builder, configure, false); + } } private static IPermissionSetBuilder Run(IPermissionSetBuilder builder, Action? configure, bool isIncludeOperation) diff --git a/src/Cofoundry.Domain/Domain/PageTemplates/Permissions/IPermissionSetBuilderPageTemplateExtensions.cs b/src/Cofoundry.Domain/Domain/PageTemplates/Permissions/IPermissionSetBuilderPageTemplateExtensions.cs index 262312091..dd1a2d556 100644 --- a/src/Cofoundry.Domain/Domain/PageTemplates/Permissions/IPermissionSetBuilderPageTemplateExtensions.cs +++ b/src/Cofoundry.Domain/Domain/PageTemplates/Permissions/IPermissionSetBuilderPageTemplateExtensions.cs @@ -2,52 +2,46 @@ namespace Cofoundry.Domain; +/// +/// extension methods for page templates. +/// public static class IPermissionSetBuilderPageTemplateExtensions { - /// - /// Configure the builder to include all permissions for page templates. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder IncludePageTemplate(this IPermissionSetBuilder builder) + extension(IPermissionSetBuilder builder) { - return Run(builder, null, true); - } + /// + /// Configure the builder to include all permissions for page templates. + /// + public IPermissionSetBuilder IncludePageTemplate() + { + return Run(builder, null, true); + } - /// - /// Configure the builder to include permissions for page templates. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to include. - public static IPermissionSetBuilder IncludePageTemplate(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, true); - } + /// + /// Configure the builder to include permissions for page templates. + /// + /// A configuration action to select which permissions to include. + public IPermissionSetBuilder IncludePageTemplate(Action configure) + { + return Run(builder, configure, true); + } - /// - /// Configure the builder to exclude all permissions for page templates. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder ExcludePageTemplate(this IPermissionSetBuilder builder) - { - return Run(builder, null, false); - } + /// + /// Configure the builder to exclude all permissions for page templates. + /// + public IPermissionSetBuilder ExcludePageTemplate() + { + return Run(builder, null, false); + } - /// - /// Configure the builder to exclude permissions for page templates. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to exclude. - public static IPermissionSetBuilder ExcludePageTemplate(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, false); + /// + /// Configure the builder to exclude permissions for page templates. + /// + /// A configuration action to select which permissions to exclude. + public IPermissionSetBuilder ExcludePageTemplate(Action configure) + { + return Run(builder, configure, false); + } } private static IPermissionSetBuilder Run(IPermissionSetBuilder builder, Action? configure, bool isIncludeOperation) diff --git a/src/Cofoundry.Domain/Domain/Pages/ContentRepository/ContentRepositoryPageExtensions.cs b/src/Cofoundry.Domain/Domain/Pages/ContentRepository/ContentRepositoryPageExtensions.cs index 6a4b6332e..9c9a24a9a 100644 --- a/src/Cofoundry.Domain/Domain/Pages/ContentRepository/ContentRepositoryPageExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Pages/ContentRepository/ContentRepositoryPageExtensions.cs @@ -1,31 +1,40 @@ -using Cofoundry.Domain.Extendable; +using Cofoundry.Domain.Extendable; using Cofoundry.Domain.Internal; namespace Cofoundry.Domain; +/// +/// Content repository extension methods for pages. +/// public static class ContentRepositoryPageExtensions { - /// - /// Pages represent the dynamically navigable pages of your website. Each page uses a template - /// which defines the regions of content that users can edit. Pages are a versioned entity and - /// therefore have many page version records. At one time a page may only have one draft - /// version, but can have many published versions; the latest published version is the one that - /// is rendered when the page is published. - /// - public static IContentRepositoryPageRepository Pages(this IContentRepository contentRepository) + extension(IContentRepository contentRepository) { - return new ContentRepositoryPageRepository(contentRepository.AsExtendableContentRepository()); + /// + /// Pages represent the dynamically navigable pages of your website. Each page uses a template + /// which defines the regions of content that users can edit. Pages are a versioned entity and + /// therefore have many page version records. At one time a page may only have one draft + /// version, but can have many published versions; the latest published version is the one that + /// is rendered when the page is published. + /// + public IContentRepositoryPageRepository Pages() + { + return new ContentRepositoryPageRepository(contentRepository.AsExtendableContentRepository()); + } } - /// - /// Pages represent the dynamically navigable pages of your website. Each page uses a template - /// which defines the regions of content that users can edit. Pages are a versioned entity and - /// therefore have many page version records. At one time a page may only have one draft - /// version, but can have many published versions; the latest published version is the one that - /// is rendered when the page is published. - /// - public static IAdvancedContentRepositoryPageRepository Pages(this IAdvancedContentRepository contentRepository) + extension(IAdvancedContentRepository contentRepository) { - return new AdvancedContentRepositoryPageRepository(contentRepository.AsExtendableContentRepository()); + /// + /// Pages represent the dynamically navigable pages of your website. Each page uses a template + /// which defines the regions of content that users can edit. Pages are a versioned entity and + /// therefore have many page version records. At one time a page may only have one draft + /// version, but can have many published versions; the latest published version is the one that + /// is rendered when the page is published. + /// + public IAdvancedContentRepositoryPageRepository Pages() + { + return new AdvancedContentRepositoryPageRepository(contentRepository.AsExtendableContentRepository()); + } } } diff --git a/src/Cofoundry.Domain/Domain/Pages/Mapping/PageBlockTypeDisplayModelMapper/PageBlockTypeDisplayModelMapperInputExtensions.cs b/src/Cofoundry.Domain/Domain/Pages/Mapping/PageBlockTypeDisplayModelMapper/PageBlockTypeDisplayModelMapperInputExtensions.cs index d0afcdda3..ba08e01d9 100644 --- a/src/Cofoundry.Domain/Domain/Pages/Mapping/PageBlockTypeDisplayModelMapper/PageBlockTypeDisplayModelMapperInputExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Pages/Mapping/PageBlockTypeDisplayModelMapper/PageBlockTypeDisplayModelMapperInputExtensions.cs @@ -5,145 +5,112 @@ namespace Cofoundry.Domain; /// public static class PageBlockTypeDisplayModelMapperInputExtensions { - /// - /// Filters all inputs returning distinct values of the selected property - /// on the data model. - /// - /// DataModel type. - /// Selected property type. - /// Mapper input to select data from. - /// Selector for the property to extract values from. - /// IEnumerable containing the distinct (non duplicate) results of the selection. - public static IEnumerable SelectDistinctModelValues( - this IEnumerable> input, - Func selector - ) - where TDataModel : IPageBlockTypeDataModel + extension(IEnumerable> input) where TDataModel : IPageBlockTypeDataModel { - var results = input - .Select(i => i.DataModel) - .Select(selector) - .Distinct(); + /// + /// Filters all inputs returning distinct values of the selected property + /// on the data model. + /// + /// Selected property type. + /// Selector for the property to extract values from. + /// IEnumerable containing the distinct (non duplicate) results of the selection. + public IEnumerable SelectDistinctModelValues(Func selector) + { + var results = input + .Select(i => i.DataModel) + .Select(selector) + .Distinct(); - return results; - } + return results; + } - /// - /// Filters all inputs returning distinct values of the selected property - /// on the data model, removing any null, empty or whitespace only strings from - /// the results. - /// - /// DataModel type. - /// Selected property type. - /// Mapper input to select data from. - /// Selector for the property to extract values from. - /// IEnumerable containing the distinct (non duplicate) results of the selection. - public static IEnumerable SelectDistinctModelValuesWithoutEmpty( - this IEnumerable> input, - Func selector - ) - where TDataModel : IPageBlockTypeDataModel - { - var results = input - .SelectDistinctModelValues(selector) - .Where(v => !string.IsNullOrWhiteSpace(v)); + /// + /// Filters all inputs returning distinct values of the selected property + /// on the data model, removing any null, empty or whitespace only strings from + /// the results. + /// + /// Selected property type. + /// Selector for the property to extract values from. + /// IEnumerable containing the distinct (non duplicate) results of the selection. + public IEnumerable SelectDistinctModelValuesWithoutEmpty(Func selector) + { + var results = input + .SelectDistinctModelValues(selector) + .Where(v => !string.IsNullOrWhiteSpace(v)); - return results; - } + return results; + } - /// - /// Filters all inputs returning distinct values of the selected property - /// on the data model, removing any default(TProperty) values from - /// the results, e.g. for numeric types this will remove 0. - /// - /// DataModel type. - /// Selected property type. - /// Mapper input to select data from. - /// Selector for the property to extract values from. - /// IEnumerable containing the distinct (non duplicate) results of the selection. - public static IEnumerable SelectDistinctModelValuesWithoutEmpty( - this IEnumerable> input, - Func selector - ) - where TDataModel : IPageBlockTypeDataModel - where TProperty : struct - { - var results = input - .SelectDistinctModelValues(selector) - .Where(v => !v.Equals(default(TProperty))); + /// + /// Filters all inputs returning distinct values of the selected property + /// on the data model, removing any default(TProperty) values from + /// the results, e.g. for numeric types this will remove 0. + /// + /// Selected property type. + /// Selector for the property to extract values from. + /// IEnumerable containing the distinct (non duplicate) results of the selection. + public IEnumerable SelectDistinctModelValuesWithoutEmpty(Func selector) + where TProperty : struct + { + var results = input + .SelectDistinctModelValues(selector) + .Where(v => !v.Equals(default(TProperty))); - return results; - } + return results; + } - /// - /// Filters all inputs returning distinct values of the selected property - /// on the data model, removing any null or default(TProperty) values from - /// the results, e.g. for nullable numeric types this will remove null and 0. - /// - /// DataModel type. - /// Selected property type. - /// Mapper input to select data from. - /// Selector for the property to extract values from. - /// IEnumerable containing the distinct (non duplicate) results of the selection. - public static IEnumerable SelectDistinctModelValuesWithoutEmpty( - this IEnumerable> input, - Func selector - ) - where TDataModel : IPageBlockTypeDataModel - where TProperty : struct - { - var results = input - .SelectDistinctModelValues(selector) - .Where(v => v.HasValue && !v.Value.Equals(default(TProperty))) - .Select(v => v!.Value); + /// + /// Filters all inputs returning distinct values of the selected property + /// on the data model, removing any null or default(TProperty) values from + /// the results, e.g. for nullable numeric types this will remove null and 0. + /// + /// Selected property type. + /// Selector for the property to extract values from. + /// IEnumerable containing the distinct (non duplicate) results of the selection. + public IEnumerable SelectDistinctModelValuesWithoutEmpty(Func selector) + where TProperty : struct + { + var results = input + .SelectDistinctModelValues(selector) + .Where(v => v.HasValue && !v.Value.Equals(default(TProperty))) + .Select(v => v!.Value); - return results; - } + return results; + } - /// - /// Filters all inputs returning distinct values of the selected property - /// on the data model, removing any null values from the results. - /// - /// DataModel type. - /// Selected property type. - /// Mapper input to select data from. - /// Selector for the property to extract values from. - /// IEnumerable containing the distinct (non duplicate) results of the selection. - public static IEnumerable GetDistinctModelValuesWithoutNulls( - this IEnumerable> input, - Func selector - ) - where TDataModel : IPageBlockTypeDataModel - where TProperty : class - { - var results = input - .SelectDistinctModelValues(selector) - .Where(v => v != null); + /// + /// Filters all inputs returning distinct values of the selected property + /// on the data model, removing any null values from the results. + /// + /// Selected property type. + /// Selector for the property to extract values from. + /// IEnumerable containing the distinct (non duplicate) results of the selection. + public IEnumerable GetDistinctModelValuesWithoutNulls(Func selector) + where TProperty : class + { + var results = input + .SelectDistinctModelValues(selector) + .Where(v => v != null); - return results; - } + return results; + } - /// - /// Filters all inputs returning distinct values of the selected property - /// on the data model. - /// - /// DataModel type. - /// Selected property type. - /// Mapper input to select data from. - /// Selector for the property to extract values from. - /// IEnumerable containing the distinct (non duplicate) results of the selection. - public static IEnumerable SelectManyDistinctModelValues( - this IEnumerable> input, - Func> selector - ) - where TDataModel : IPageBlockTypeDataModel - { - var results = input - .Select(i => i.DataModel) - .Where(i => selector(i) != null) - .SelectMany(selector) - .Distinct(); + /// + /// Filters all inputs returning distinct values of the selected property + /// on the data model. + /// + /// Selected property type. + /// Selector for the property to extract values from. + /// IEnumerable containing the distinct (non duplicate) results of the selection. + public IEnumerable SelectManyDistinctModelValues(Func> selector) + { + var results = input + .Select(i => i.DataModel) + .Where(i => selector(i) != null) + .SelectMany(selector) + .Distinct(); - return results; + return results; + } } } diff --git a/src/Cofoundry.Domain/Domain/Pages/Models/PageRouteExtensions.cs b/src/Cofoundry.Domain/Domain/Pages/Models/PageRouteExtensions.cs index dece39746..fc72621bc 100644 --- a/src/Cofoundry.Domain/Domain/Pages/Models/PageRouteExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Pages/Models/PageRouteExtensions.cs @@ -1,16 +1,19 @@ -namespace Cofoundry.Domain; +namespace Cofoundry.Domain; +/// +/// Extensions for filtering collections of . +/// public static class PageRouteExtensions { - public static IEnumerable FilterByDirectory( - this IEnumerable routes, - PageDirectoryRoute directory, - int? localeId = null - ) + extension(IEnumerable routes) { - return routes - .Where(r => (r.PageDirectory == null && directory == null) || r.PageDirectory == directory) - .Where(r => (r.Locale == null && !localeId.HasValue) || (r.Locale != null && r.Locale.LocaleId == localeId)) - ; + public IEnumerable FilterByDirectory( + PageDirectoryRoute directory, + int? localeId = null) + { + return routes + .Where(r => (r.PageDirectory == null && directory == null) || r.PageDirectory == directory) + .Where(r => (r.Locale == null && !localeId.HasValue) || (r.Locale != null && r.Locale.LocaleId == localeId)); + } } } diff --git a/src/Cofoundry.Domain/Domain/Pages/Permissions/IPermissionSetBuilderPageExtensions.cs b/src/Cofoundry.Domain/Domain/Pages/Permissions/IPermissionSetBuilderPageExtensions.cs index cb4eaa65b..9e96188f6 100644 --- a/src/Cofoundry.Domain/Domain/Pages/Permissions/IPermissionSetBuilderPageExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Pages/Permissions/IPermissionSetBuilderPageExtensions.cs @@ -2,52 +2,46 @@ namespace Cofoundry.Domain; +/// +/// extension methods for pages. +/// public static class IPermissionSetBuilderPageExtensions { - /// - /// Configure the builder to include all permissions for pages. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder IncludePage(this IPermissionSetBuilder builder) + extension(IPermissionSetBuilder builder) { - return Run(builder, null, true); - } + /// + /// Configure the builder to include all permissions for pages. + /// + public IPermissionSetBuilder IncludePage() + { + return Run(builder, null, true); + } - /// - /// Configure the builder to include permissions for pages. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to include. - public static IPermissionSetBuilder IncludePage(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, true); - } + /// + /// Configure the builder to include permissions for pages. + /// + /// A configuration action to select which permissions to include. + public IPermissionSetBuilder IncludePage(Action configure) + { + return Run(builder, configure, true); + } - /// - /// Configure the builder to exclude all permissions for pages. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder ExcludePage(this IPermissionSetBuilder builder) - { - return Run(builder, null, false); - } + /// + /// Configure the builder to exclude all permissions for pages. + /// + public IPermissionSetBuilder ExcludePage() + { + return Run(builder, null, false); + } - /// - /// Configure the builder to exclude permissions for pages. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to exclude. - public static IPermissionSetBuilder ExcludePage(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, false); + /// + /// Configure the builder to exclude permissions for pages. + /// + /// A configuration action to select which permissions to exclude. + public IPermissionSetBuilder ExcludePage(Action configure) + { + return Run(builder, configure, false); + } } private static IPermissionSetBuilder Run(IPermissionSetBuilder builder, Action? configure, bool isIncludeOperation) diff --git a/src/Cofoundry.Domain/Domain/PasswordPolicies/Configuration/IExtendablePasswordPolicyBuilderExtensions.cs b/src/Cofoundry.Domain/Domain/PasswordPolicies/Configuration/IExtendablePasswordPolicyBuilderExtensions.cs index 9364a705b..1cbd9cbc2 100644 --- a/src/Cofoundry.Domain/Domain/PasswordPolicies/Configuration/IExtendablePasswordPolicyBuilderExtensions.cs +++ b/src/Cofoundry.Domain/Domain/PasswordPolicies/Configuration/IExtendablePasswordPolicyBuilderExtensions.cs @@ -1,19 +1,24 @@ -namespace Cofoundry.Domain.Extendable; +namespace Cofoundry.Domain.Extendable; +/// +/// Extension methods for extending . +/// public static class IExtendablePasswordPolicyBuilderExtensions { - /// - /// Casts the to - /// , allowing access to extensibility - /// points to developers making extension methods. - /// - public static IExtendablePasswordPolicyBuilder AsExtendable(this IPasswordPolicyBuilder passwordPolicyBuilder) + extension(IPasswordPolicyBuilder passwordPolicyBuilder) { - if (passwordPolicyBuilder is IExtendablePasswordPolicyBuilder extendableBuiler) + /// + /// Casts the policy builder to , allowing access + /// to extensibility points to developers making extension methods. + /// + public IExtendablePasswordPolicyBuilder AsExtendable() { - return extendableBuiler; - } + if (passwordPolicyBuilder is IExtendablePasswordPolicyBuilder extendableBuiler) + { + return extendableBuiler; + } - throw new Exception($"An {nameof(IPasswordPolicyBuilder)} implementation should also implement {nameof(IExtendablePasswordPolicyBuilder)} to allow internal/plugin extendability."); + throw new Exception($"An {nameof(IPasswordPolicyBuilder)} implementation should also implement {nameof(IExtendablePasswordPolicyBuilder)} to allow internal/plugin extendability."); + } } } diff --git a/src/Cofoundry.Domain/Domain/PasswordPolicies/Configuration/IPasswordPolicyBuilderExtensions.cs b/src/Cofoundry.Domain/Domain/PasswordPolicies/Configuration/IPasswordPolicyBuilderExtensions.cs index efbd406be..213478c10 100644 --- a/src/Cofoundry.Domain/Domain/PasswordPolicies/Configuration/IPasswordPolicyBuilderExtensions.cs +++ b/src/Cofoundry.Domain/Domain/PasswordPolicies/Configuration/IPasswordPolicyBuilderExtensions.cs @@ -2,182 +2,187 @@ namespace Cofoundry.Domain; +/// +/// Extension methods for . +/// public static class IPasswordPolicyBuilderExtensions { - /// - /// Adds the Cofoundry defaults to the policy, making use of any settings - /// defined in through configuration sources - /// e.g. appsettings.json. - /// - /// - /// Builder to set defaults on. - /// - public static IPasswordPolicyBuilder UseDefaults(this IPasswordPolicyBuilder builder) + extension(IPasswordPolicyBuilder builder) { - return builder.UseDefaults(null); - } - - /// - /// Adds the Cofoundry defaults to the policy, using the specified - /// options transformer to layer additional configuration on top of - /// those defined in configuration sources e.g. appsettings.json. - /// - /// - /// Builder to set defaults on. - /// - /// - /// Transformer to configure any additional settings on top of the - /// default options. - /// - public static IPasswordPolicyBuilder UseDefaults( - this IPasswordPolicyBuilder builder, - Action? passwordOptionsConfig = null - ) - { - var options = GetPasswordOptions(builder); - - if (passwordOptionsConfig != null) + /// + /// Adds the Cofoundry defaults to the policy, making use of any settings + /// defined in through configuration sources + /// e.g. appsettings.json. + /// + /// + /// Builder to set defaults on. + /// + public IPasswordPolicyBuilder UseDefaults() { - options = options.Clone(); - passwordOptionsConfig(options); + return builder.UseDefaults(null); } - builder - .SetDescription($"Passwords must be between {options.MinLength} and {options.MaxLength} characters.") - .ValidateMinLength(options.MinLength) - .ValidateMaxLength(options.MaxLength) - .ValidateMinUniqueCharacters(options.MinUniqueCharacters) - .ValidateNotCurrentPassword() - .ValidateNotPersonalData() - .ValidateNotSequential() - ; - - return builder; - } + /// + /// Adds the Cofoundry defaults to the policy, using the specified + /// options transformer to layer additional configuration on top of + /// those defined in configuration sources e.g. appsettings.json. + /// + /// + /// Builder to set defaults on. + /// + /// + /// Transformer to configure any additional settings on top of the + /// default options. + /// + public IPasswordPolicyBuilder UseDefaults( + Action? passwordOptionsConfig = null + ) + { + var options = GetPasswordOptions(builder); + + if (passwordOptionsConfig != null) + { + options = options.Clone(); + passwordOptionsConfig(options); + } + + builder + .SetDescription($"Passwords must be between {options.MinLength} and {options.MaxLength} characters.") + .ValidateMinLength(options.MinLength) + .ValidateMaxLength(options.MaxLength) + .ValidateMinUniqueCharacters(options.MinUniqueCharacters) + .ValidateNotCurrentPassword() + .ValidateNotPersonalData() + .ValidateNotSequential() + ; + + return builder; + } - /// - /// Adds an attribute to the policy. Attributes are loosely mapped to - /// HTML attributes for password inputs. Expressing these attributes here allows - /// a developer to dynamically map policy requirements to an input field. The - /// constants can be used as keys for known - /// attributes. - /// - /// - /// Builder to add to. - /// - /// - /// The attribute name e.g. "minlength". The constants - /// can be used for known attribute keys. - /// - /// The value of the attribute as an integer e.g. 10. - public static IPasswordPolicyBuilder AddAttribute(this IPasswordPolicyBuilder builder, string attribute, int value) - { - return builder.AddAttribute(attribute, value.ToString(CultureInfo.InvariantCulture)); - } + /// + /// Adds an attribute to the policy. Attributes are loosely mapped to + /// HTML attributes for password inputs. Expressing these attributes here allows + /// a developer to dynamically map policy requirements to an input field. The + /// constants can be used as keys for known + /// attributes. + /// + /// + /// Builder to add to. + /// + /// + /// The attribute name e.g. "minlength". The constants + /// can be used for known attribute keys. + /// + /// The value of the attribute as an integer e.g. 10. + public IPasswordPolicyBuilder AddAttribute(string attribute, int value) + { + return builder.AddAttribute(attribute, value.ToString(CultureInfo.InvariantCulture)); + } - /// - /// Validate that a password meets a minimum length. See - /// https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html#implement-proper-password-strength-controls - /// for up to date information on best practice password lengths. - /// - /// - /// Builder to add rules to. - /// - /// - /// The inclusive minimum length that the password should be. Must be between 6 and 2048 - /// characters. - /// - public static IPasswordPolicyBuilder ValidateMinLength(this IPasswordPolicyBuilder builder, int minLength) - { - builder - .AddValidatorWithConfig(minLength) - .AddAttribute(PasswordPolicyAttributes.MinLength, minLength); + /// + /// Validate that a password meets a minimum length. See + /// https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html#implement-proper-password-strength-controls + /// for up to date information on best practice password lengths. + /// + /// + /// Builder to add rules to. + /// + /// + /// The inclusive minimum length that the password should be. Must be between 6 and 2048 + /// characters. + /// + public IPasswordPolicyBuilder ValidateMinLength(int minLength) + { + builder + .AddValidatorWithConfig(minLength) + .AddAttribute(PasswordPolicyAttributes.MinLength, minLength); - return builder; - } + return builder; + } - /// - /// Validate that a password meets a maximum length. See - /// https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html#implement-proper-password-strength-controls - /// for up to date information on best practice password lengths. - /// - /// - /// Builder to add rules to. - /// - /// - /// The inclusive maximum length that the password should be. Must be between 6 and 2048 - /// characters. - /// - public static IPasswordPolicyBuilder ValidateMaxLength(this IPasswordPolicyBuilder builder, int maxLength) - { - builder - .AddValidatorWithConfig(maxLength) - .AddAttribute(PasswordPolicyAttributes.MaxLength, maxLength); + /// + /// Validate that a password meets a maximum length. See + /// https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html#implement-proper-password-strength-controls + /// for up to date information on best practice password lengths. + /// + /// + /// Builder to add rules to. + /// + /// + /// The inclusive maximum length that the password should be. Must be between 6 and 2048 + /// characters. + /// + public IPasswordPolicyBuilder ValidateMaxLength(int maxLength) + { + builder + .AddValidatorWithConfig(maxLength) + .AddAttribute(PasswordPolicyAttributes.MaxLength, maxLength); - return builder; - } + return builder; + } - /// - /// Prevents groups of repeated characters in a password by validating that a minimum number of - /// unique characters e.g. the password "YYZ-YYZ-YYZ" contains 3 unique characters. - /// - /// - /// Builder to add rules to. - /// - /// - /// The inclusive minimum number of unique characters to allow e.g. if the minimum was 4 then - /// "abcabcabcabc" would be an invalid password. - /// - public static IPasswordPolicyBuilder ValidateMinUniqueCharacters(this IPasswordPolicyBuilder builder, int minUniqueCharacters) - { - builder.AddValidatorWithConfig(minUniqueCharacters); + /// + /// Prevents groups of repeated characters in a password by validating that a minimum number of + /// unique characters e.g. the password "YYZ-YYZ-YYZ" contains 3 unique characters. + /// + /// + /// Builder to add rules to. + /// + /// + /// The inclusive minimum number of unique characters to allow e.g. if the minimum was 4 then + /// "abcabcabcabc" would be an invalid password. + /// + public IPasswordPolicyBuilder ValidateMinUniqueCharacters(int minUniqueCharacters) + { + builder.AddValidatorWithConfig(minUniqueCharacters); - return builder; - } + return builder; + } - /// - /// Validates that a password does not match either their username - /// or email address, based on a case-insenstivie equality comparison. - /// - /// - /// Builder to add rules to. - /// - public static IPasswordPolicyBuilder ValidateNotPersonalData(this IPasswordPolicyBuilder builder) - { - builder.AddValidator(); + /// + /// Validates that a password does not match either their username + /// or email address, based on a case-insenstivie equality comparison. + /// + /// + /// Builder to add rules to. + /// + public IPasswordPolicyBuilder ValidateNotPersonalData() + { + builder.AddValidator(); - return builder; - } + return builder; + } - /// - /// Validates that a password does not exactly match a users current password - /// if one is supplied. A current password is only supplied when a password - /// is authenticated and changed in the same command and therefore is only - /// validated in these conditions. - /// - /// - /// Builder to add rules to. - /// - public static IPasswordPolicyBuilder ValidateNotCurrentPassword(this IPasswordPolicyBuilder builder) - { - builder.AddValidator(); + /// + /// Validates that a password does not exactly match a users current password + /// if one is supplied. A current password is only supplied when a password + /// is authenticated and changed in the same command and therefore is only + /// validated in these conditions. + /// + /// + /// Builder to add rules to. + /// + public IPasswordPolicyBuilder ValidateNotCurrentPassword() + { + builder.AddValidator(); - return builder; - } + return builder; + } - /// - /// Validates that a password is not a sequence or reverse-sequence of characters - /// e.g. "abcdefghij" or "987654321". This is case-sensitive and is done simply - /// by comparing character codes. - /// - /// - /// Builder to add rules to. - /// - public static IPasswordPolicyBuilder ValidateNotSequential(this IPasswordPolicyBuilder builder) - { - builder.AddValidator(); + /// + /// Validates that a password is not a sequence or reverse-sequence of characters + /// e.g. "abcdefghij" or "987654321". This is case-sensitive and is done simply + /// by comparing character codes. + /// + /// + /// Builder to add rules to. + /// + public IPasswordPolicyBuilder ValidateNotSequential() + { + builder.AddValidator(); - return builder; + return builder; + } } private static PasswordOptions GetPasswordOptions(IPasswordPolicyBuilder builder) diff --git a/src/Cofoundry.Domain/Domain/PasswordPolicies/ContentRepositoryExtensions/ContentRepositoryPasswordPolicyExtensions.cs b/src/Cofoundry.Domain/Domain/PasswordPolicies/ContentRepositoryExtensions/ContentRepositoryPasswordPolicyExtensions.cs index f4c6678c2..5b460c6ac 100644 --- a/src/Cofoundry.Domain/Domain/PasswordPolicies/ContentRepositoryExtensions/ContentRepositoryPasswordPolicyExtensions.cs +++ b/src/Cofoundry.Domain/Domain/PasswordPolicies/ContentRepositoryExtensions/ContentRepositoryPasswordPolicyExtensions.cs @@ -1,16 +1,22 @@ -using Cofoundry.Domain.Extendable; +using Cofoundry.Domain.Extendable; using Cofoundry.Domain.Internal; namespace Cofoundry.Domain; +/// +/// Content repository extension methods for password policies. +/// public static class ContentRepositoryPasswordPolicyExtensions { - /// - /// Queries relating to user area password policies. - /// - public static IAdvancedContentRepositoryPasswordPolicyRepository PasswordPolicies(this IAdvancedContentRepositoryUserAreaRepository contentRepository) + extension(IAdvancedContentRepositoryUserAreaRepository contentRepository) { - var extendableContentRepository = contentRepository.AsExtendableContentRepositoryPart().ExtendableContentRepository; - return new ContentRepositoryPasswordPolicyRepository(extendableContentRepository); + /// + /// Queries relating to user area password policies. + /// + public IAdvancedContentRepositoryPasswordPolicyRepository PasswordPolicies() + { + var extendableContentRepository = contentRepository.AsExtendableContentRepositoryPart().ExtendableContentRepository; + return new ContentRepositoryPasswordPolicyRepository(extendableContentRepository); + } } } diff --git a/src/Cofoundry.Domain/Domain/RewriteRules/ContentRepository/ContentRepositoryRewriteRuleExtensions.cs b/src/Cofoundry.Domain/Domain/RewriteRules/ContentRepository/ContentRepositoryRewriteRuleExtensions.cs index 57621eab3..93af4cf88 100644 --- a/src/Cofoundry.Domain/Domain/RewriteRules/ContentRepository/ContentRepositoryRewriteRuleExtensions.cs +++ b/src/Cofoundry.Domain/Domain/RewriteRules/ContentRepository/ContentRepositoryRewriteRuleExtensions.cs @@ -1,16 +1,22 @@ -using Cofoundry.Domain.Extendable; +using Cofoundry.Domain.Extendable; using Cofoundry.Domain.Internal; namespace Cofoundry.Domain; +/// +/// Content repository extension methods for rewrite rules. +/// public static class ContentRepositoryRewriteRuleExtensions { - /// - /// Rewrite rules can be used to redirect users from one url to another. - /// This functionality is incomplete and subject to change. - /// - public static IAdvancedContentRepositoryRewriteRuleRepository RewriteRules(this IAdvancedContentRepository contentRepository) + extension(IAdvancedContentRepository contentRepository) { - return new ContentRepositoryRewriteRuleRepository(contentRepository.AsExtendableContentRepository()); + /// + /// Rewrite rules can be used to redirect users from one url to another. + /// This functionality is incomplete and subject to change. + /// + public IAdvancedContentRepositoryRewriteRuleRepository RewriteRules() + { + return new ContentRepositoryRewriteRuleRepository(contentRepository.AsExtendableContentRepository()); + } } } diff --git a/src/Cofoundry.Domain/Domain/RewriteRules/Permissions/IPermissionSetBuilderRewriteRuleExtensions.cs b/src/Cofoundry.Domain/Domain/RewriteRules/Permissions/IPermissionSetBuilderRewriteRuleExtensions.cs index a95fa1986..06e2154b8 100644 --- a/src/Cofoundry.Domain/Domain/RewriteRules/Permissions/IPermissionSetBuilderRewriteRuleExtensions.cs +++ b/src/Cofoundry.Domain/Domain/RewriteRules/Permissions/IPermissionSetBuilderRewriteRuleExtensions.cs @@ -2,52 +2,46 @@ namespace Cofoundry.Domain; +/// +/// extension methods for rewrite rules. +/// public static class IPermissionSetBuilderRewriteRuleExtensions { - /// - /// Configure the builder to include all permissions for rewrite rules. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder IncludeRewriteRule(this IPermissionSetBuilder builder) + extension(IPermissionSetBuilder builder) { - return Run(builder, null, true); - } + /// + /// Configure the builder to include all permissions for rewrite rules. + /// + public IPermissionSetBuilder IncludeRewriteRule() + { + return Run(builder, null, true); + } - /// - /// Configure the builder to include permissions for rewrite rules. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to include. - public static IPermissionSetBuilder IncludeRewriteRule(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, true); - } + /// + /// Configure the builder to include permissions for rewrite rules. + /// + /// A configuration action to select which permissions to include. + public IPermissionSetBuilder IncludeRewriteRule(Action configure) + { + return Run(builder, configure, true); + } - /// - /// Configure the builder to exclude all permissions for rewrite rules. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder ExcludeRewriteRule(this IPermissionSetBuilder builder) - { - return Run(builder, null, false); - } + /// + /// Configure the builder to exclude all permissions for rewrite rules. + /// + public IPermissionSetBuilder ExcludeRewriteRule() + { + return Run(builder, null, false); + } - /// - /// Configure the builder to exclude permissions for rewrite rules. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to exclude. - public static IPermissionSetBuilder ExcludeRewriteRule(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, false); + /// + /// Configure the builder to exclude permissions for rewrite rules. + /// + /// A configuration action to select which permissions to exclude. + public IPermissionSetBuilder ExcludeRewriteRule(Action configure) + { + return Run(builder, configure, false); + } } private static IPermissionSetBuilder Run(IPermissionSetBuilder builder, Action? configure, bool isIncludeOperation) diff --git a/src/Cofoundry.Domain/Domain/Roles/ContentRepositoryExtensions/ContentRepositoryRoleExtensions.cs b/src/Cofoundry.Domain/Domain/Roles/ContentRepositoryExtensions/ContentRepositoryRoleExtensions.cs index e5ab6c182..d4f1e25d8 100644 --- a/src/Cofoundry.Domain/Domain/Roles/ContentRepositoryExtensions/ContentRepositoryRoleExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Roles/ContentRepositoryExtensions/ContentRepositoryRoleExtensions.cs @@ -1,27 +1,36 @@ -using Cofoundry.Domain.Extendable; +using Cofoundry.Domain.Extendable; using Cofoundry.Domain.Internal; namespace Cofoundry.Domain; +/// +/// Content repository extension methods for roles. +/// public static class ContentRepositoryRoleExtensions { - /// - /// Queries and commands relating to roles from the Cofoundry identity - /// system. Roles are an assignable collection of permissions. Every user has to be assigned - /// to one role. - /// - public static IContentRepositoryRoleRepository Roles(this IContentRepository contentRepository) + extension(IContentRepository contentRepository) { - return new ContentRepositoryRoleRepository(contentRepository.AsExtendableContentRepository()); + /// + /// Queries and commands relating to roles from the Cofoundry identity + /// system. Roles are an assignable collection of permissions. Every user has to be assigned + /// to one role. + /// + public IContentRepositoryRoleRepository Roles() + { + return new ContentRepositoryRoleRepository(contentRepository.AsExtendableContentRepository()); + } } - /// - /// Queries and commands relating to roles from the Cofoundry identity - /// system. Roles are an assignable collection of permissions. Every user has to be assigned - /// to one role. - /// - public static IAdvancedContentRepositoryRoleRepository Roles(this IAdvancedContentRepository contentRepository) + extension(IAdvancedContentRepository contentRepository) { - return new ContentRepositoryRoleRepository(contentRepository.AsExtendableContentRepository()); + /// + /// Queries and commands relating to roles from the Cofoundry identity + /// system. Roles are an assignable collection of permissions. Every user has to be assigned + /// to one role. + /// + public IAdvancedContentRepositoryRoleRepository Roles() + { + return new ContentRepositoryRoleRepository(contentRepository.AsExtendableContentRepository()); + } } } diff --git a/src/Cofoundry.Domain/Domain/Roles/Initialization/IExtendablePermissionSetBuilderExtensions.cs b/src/Cofoundry.Domain/Domain/Roles/Initialization/IExtendablePermissionSetBuilderExtensions.cs index b62727fb8..c981aa37e 100644 --- a/src/Cofoundry.Domain/Domain/Roles/Initialization/IExtendablePermissionSetBuilderExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Roles/Initialization/IExtendablePermissionSetBuilderExtensions.cs @@ -1,20 +1,26 @@ -namespace Cofoundry.Domain.Extendable; +namespace Cofoundry.Domain.Extendable; +/// +/// Extensions for extending . +/// public static class IExtendablePermissionSetBuilderExtensions { - /// - /// Casts the builder instance as to - /// provide access to hidden functionality intended for extending a builder with - /// bespoke features. These are advanced feature intended to be used for extension only - /// e.g. internally by Cofoundry, in plugins or custom extensions - /// - public static IExtendablePermissionSetBuilder AsExtendableBuilder(this IPermissionSetBuilder builder) + extension(IPermissionSetBuilder builder) { - if (builder is IExtendablePermissionSetBuilder extendableBuilder) + /// + /// Casts the builder instance as to + /// provide access to hidden functionality intended for extending a builder with + /// bespoke features. These are advanced feature intended to be used for extension only + /// e.g. internally by Cofoundry, in plugins or custom extensions + /// + public IExtendablePermissionSetBuilder AsExtendableBuilder() { - return extendableBuilder; - } + if (builder is IExtendablePermissionSetBuilder extendableBuilder) + { + return extendableBuilder; + } - throw new Exception($"An {nameof(IPermissionSetBuilder)} implementation should also implement {nameof(IExtendablePermissionSetBuilder)} to allow internal/plugin extendibility."); + throw new Exception($"An {nameof(IPermissionSetBuilder)} implementation should also implement {nameof(IExtendablePermissionSetBuilder)} to allow internal/plugin extendibility."); + } } } diff --git a/src/Cofoundry.Domain/Domain/Roles/Initialization/IPermissionSetBuilderExtensions.cs b/src/Cofoundry.Domain/Domain/Roles/Initialization/IPermissionSetBuilderExtensions.cs index 59dab452d..21997dd93 100644 --- a/src/Cofoundry.Domain/Domain/Roles/Initialization/IPermissionSetBuilderExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Roles/Initialization/IPermissionSetBuilderExtensions.cs @@ -1,22 +1,28 @@ -namespace Cofoundry.Domain; +namespace Cofoundry.Domain; +/// +/// Extensions for . +/// public static class IPermissionSetBuilderExtensions { - /// - /// Configure the builder to include the permissions configured for - /// the , which usually is a good base - /// to start from before adding additional permissions. - /// - public static IPermissionSetBuilder ApplyAnonymousRoleConfiguration(this IPermissionSetBuilder builder) + extension(IPermissionSetBuilder builder) { - return builder.ApplyRoleConfiguration(); - } + /// + /// Configure the builder to include the permissions configured for + /// the , which usually is a good base + /// to start from before adding additional permissions. + /// + public IPermissionSetBuilder ApplyAnonymousRoleConfiguration() + { + return builder.ApplyRoleConfiguration(); + } - /// - /// Configure the builder to include all permissions. - /// - public static IPermissionSetBuilder IncludeAll(this IPermissionSetBuilder builder) - { - return builder.Include(p => p); + /// + /// Configure the builder to include all permissions. + /// + public IPermissionSetBuilder IncludeAll() + { + return builder.Include(p => p); + } } } diff --git a/src/Cofoundry.Domain/Domain/Roles/Models/IPermissionCollectionExtensions.cs b/src/Cofoundry.Domain/Domain/Roles/Models/IPermissionCollectionExtensions.cs index bc7fb5530..bc7f30330 100644 --- a/src/Cofoundry.Domain/Domain/Roles/Models/IPermissionCollectionExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Roles/Models/IPermissionCollectionExtensions.cs @@ -1,5 +1,8 @@ namespace Cofoundry.Domain; +/// +/// Extensions for filtering collections of . +/// public static class IPermissionCollectionExtensions { /// @@ -13,258 +16,231 @@ public static class IPermissionCollectionExtensions { CommonPermissionTypes.DeletePermissionCode } }; - /// - /// Filters a collection of permissions to only include types. - /// - /// The collection of permissions to filter - /// Filtered collection cast to - public static IEnumerable FilterToEntityPermissions(this IEnumerable permissionsToFilter) - { - return permissionsToFilter - .Where(p => p is IEntityPermission) - .Cast(); - } - - /// - /// Filters a collection of permissions to only include permissions for a specific entity type. - /// - /// The collection of permissions to filter - /// The definition code of the entity to filter on e.g. - /// Filtered collection cast to - public static IEnumerable FilterToEntityPermissions(this IEnumerable permissionsToFilter, string entityDefinitionCode) - { - return permissionsToFilter - .Where(p => p is IEntityPermission) - .Cast() - .Where(p => p.EntityDefinition?.EntityDefinitionCode == entityDefinitionCode); - } - - /// - /// Filters a collection of permissions to only include permissions for a specific permission type - /// - /// The collection of permissions to filter - /// The code of the permission type to filter on - /// Filtered collection of permissions - public static IEnumerable FilterByPermissionCode(this IEnumerable permissionsToFilter, string permissionCode) - { - return permissionsToFilter.Where(p => p.PermissionType.Code == permissionCode); - } - - /// - /// Filters a collection of permissions to only include permissions that are or inherit from a specific permission type - /// - /// The type of permission to filter on. - /// The collection of permissions to filter - /// Filtered collection of permissions - public static IEnumerable FilterByType(this IEnumerable permissionsToFilter) - { - return permissionsToFilter.Where(p => p is TPermission); - } - - /// - /// Filters a collection of permissions to only include permissions that use the Read common permission type - /// - /// The collection of permissions to filter - /// Filtered collection of permissions - public static IEnumerable FilterToReadPermissions(this IEnumerable permissionsToFilter) - { - return permissionsToFilter - .FilterByPermissionCode(CommonPermissionTypes.ReadPermissionCode); - } - - /// - /// Filters a collection of permissions to only include permissions that use the Update common permission type - /// - /// The collection of permissions to filter - /// Filtered collection of permissions - public static IEnumerable FilterToUpdatePermissions(this IEnumerable permissionsToFilter) - { - return permissionsToFilter - .FilterByPermissionCode(CommonPermissionTypes.UpdatePermissionCode); - } - - /// - /// Filters a collection of permissions to only include permissions that use the Create common permission type - /// - /// The collection of permissions to filter - /// Filtered collection of permissions - public static IEnumerable FilterToCreatePermissions(this IEnumerable permissionsToFilter) - { - return permissionsToFilter - .FilterByPermissionCode(CommonPermissionTypes.CreatePermissionCode); - } - - /// - /// Filters a collection of permissions to only include permissions that use the Delete common permission type - /// - /// The collection of permissions to filter - /// Filtered collection of permissions - public static IEnumerable FilterToDeletePermissions(this IEnumerable permissionsToFilter) - { - return permissionsToFilter - .FilterByPermissionCode(CommonPermissionTypes.DeletePermissionCode); - } - - /// - /// Filters a collection of permissions to only include permissions that use common - /// permission types associated with writing data which can include the "Create", "Update" and "Delete" - /// permissions as well as the more generic "Write" permission. - /// - /// The collection of permissions to filter - /// Filtered collection of permissions - public static IEnumerable FilterToWritePermissions(this IEnumerable permissionsToFilter) - { - return permissionsToFilter - .Where(p => _writePermissionTypeCodes.Contains(p.PermissionType.Code)); - } - - /// - /// Filters a collection of permissions to only include permissions that permit - /// access to sections in the admin panel. Specifically permissions that use the - /// admin module common permission type code and the dashboard permission type code. - /// - /// The collection of permissions to filter - /// Filtered collection of permissions - public static IEnumerable FilterToAdminModulePermissions(this IEnumerable permissionsToFilter) - { - return permissionsToFilter - .Where(p => p.PermissionType.Code == CommonPermissionTypes.AdminModulePermissionCode - || p.PermissionType.Code == DashboardAdminModulePermission.PermissionTypeCode); - } - - /// - /// The anonymous role by default can read any entity except for users. - /// This is because user read permission means 'all users' not just 'current user' - /// and is associated with user management. - /// - /// The collection of permissions to filter - /// Filtered collection of permissions - public static IEnumerable FilterToAnonymousRoleDefaults(this IEnumerable permissionsToFilter) - { - return permissionsToFilter - .FilterToReadPermissions() - .ExceptUserManagementPermissions(); - } - - /// - /// Removes the specified permission from the collection. - /// - /// IPermission type to remove - /// The collection of permissions to filter - /// Filtered collection of permissions - public static IEnumerable ExceptPermission(this IEnumerable permissionsToFilter) - { - return permissionsToFilter - .Where(p => p is not TPermission); - } - - /// - /// Removes permissions with the specified permission code from the collection. - /// - /// The collection of permissions to filter - /// Code of the permission type to exclude from the collection - /// Filtered collection of permissions - public static IEnumerable ExceptPermissionCode(this IEnumerable permissionsToFilter, string permissionCode) - { - return permissionsToFilter.Where(p => p.PermissionType.Code != permissionCode); - } - - /// - /// Removes permissions with the "Create" common permisison type from the collection. - /// - /// The collection of permissions to filter - /// Filtered collection of permissions - public static IEnumerable ExceptCreatePermissions(this IEnumerable permissionsToFilter) - { - return permissionsToFilter - .ExceptPermissionCode(CommonPermissionTypes.CreatePermissionCode); - } - - /// - /// Removes permissions with the "Update" common permisison type from the collection. - /// - /// The collection of permissions to filter - /// Filtered collection of permissions - public static IEnumerable ExceptUpdatePermissions(this IEnumerable permissionsToFilter) - { - return permissionsToFilter - .ExceptPermissionCode(CommonPermissionTypes.UpdatePermissionCode); - } - - /// - /// Removes permissions with the "Delete" common permisison type from the collection. - /// - /// The collection of permissions to filter - /// Filtered collection of permissions - public static IEnumerable ExceptDeletePermissions(this IEnumerable permissionsToFilter) - { - return permissionsToFilter - .ExceptPermissionCode(CommonPermissionTypes.DeletePermissionCode); - } - - /// - /// Removes permissions with write common permisison types from the collection - /// which can include the "Create", "Update" and "Delete" permissions as well - /// as the more generic "Write" permission. - /// - /// The collection of permissions to filter - /// Filtered collection of permissions - public static IEnumerable ExceptWritePermissions(this IEnumerable permissionsToFilter) - { - return permissionsToFilter - .Where(p => !_writePermissionTypeCodes.Contains(p.PermissionType.Code)); - } - - /// - /// Removes permissions from the collection associated with a specific entity type. - /// - /// Definition type of the entity to remove from the collection - /// The collection of permissions to filter - /// Filtered collection of permissions - public static IEnumerable ExceptEntityPermissions(this IEnumerable permissionsToFilter) - where TEntityDefinition : IEntityDefinition, new() - { - var entityDefiniton = new TEntityDefinition(); - - return permissionsToFilter.ExceptEntityPermissions(entityDefiniton.EntityDefinitionCode); - } - - /// - /// Removes permissions from the collection associated with a specific entity type. - /// - /// The collection of permissions to filter - /// The definition code of the entity to remove e.g. PageEntityDefinition.DefinitionCode - /// - public static IEnumerable ExceptEntityPermissions(this IEnumerable permissionsToFilter, string entityDefinitionCode) - { - return permissionsToFilter - .Where(p => p is not IEntityPermission || ((IEntityPermission)p).EntityDefinition?.EntityDefinitionCode != entityDefinitionCode); - } - - /// - /// Filters a collection of permissions to exclude permissions to - /// access to sections in the admin panel. Specifically permissions that use the - /// admin module common permission type code and the dashboard permission type code. - /// - /// The collection of permissions to filter - /// Filtered collection of permissions - public static IEnumerable ExceptAdminModulePermissions(this IEnumerable permissionsToFilter) - { - return permissionsToFilter - .Where(p => p.PermissionType.Code != CommonPermissionTypes.AdminModulePermissionCode + extension(IEnumerable permissionsToFilter) + { + /// + /// Filters a collection of permissions to only include types. + /// + /// Filtered collection cast to + public IEnumerable FilterToEntityPermissions() + { + return permissionsToFilter + .Where(p => p is IEntityPermission) + .Cast(); + } + + /// + /// Filters a collection of permissions to only include permissions for a specific entity type. + /// + /// The definition code of the entity to filter on e.g. + /// Filtered collection cast to + public IEnumerable FilterToEntityPermissions(string entityDefinitionCode) + { + return permissionsToFilter + .Where(p => p is IEntityPermission) + .Cast() + .Where(p => p.EntityDefinition?.EntityDefinitionCode == entityDefinitionCode); + } + + /// + /// Filters a collection of permissions to only include permissions for a specific permission type + /// + /// The code of the permission type to filter on + /// Filtered collection of permissions + public IEnumerable FilterByPermissionCode(string permissionCode) + { + return permissionsToFilter.Where(p => p.PermissionType.Code == permissionCode); + } + + /// + /// Filters a collection of permissions to only include permissions that are or inherit from a specific permission type + /// + /// The type of permission to filter on. + /// Filtered collection of permissions + public IEnumerable FilterByType() + { + return permissionsToFilter.Where(p => p is TPermission); + } + + /// + /// Filters a collection of permissions to only include permissions that use the Read common permission type + /// + /// Filtered collection of permissions + public IEnumerable FilterToReadPermissions() + { + return permissionsToFilter.FilterByPermissionCode(CommonPermissionTypes.ReadPermissionCode); + } + + /// + /// Filters a collection of permissions to only include permissions that use the Update common permission type + /// + /// Filtered collection of permissions + public IEnumerable FilterToUpdatePermissions() + { + return permissionsToFilter.FilterByPermissionCode(CommonPermissionTypes.UpdatePermissionCode); + } + + /// + /// Filters a collection of permissions to only include permissions that use the Create common permission type + /// + /// Filtered collection of permissions + public IEnumerable FilterToCreatePermissions() + { + return permissionsToFilter.FilterByPermissionCode(CommonPermissionTypes.CreatePermissionCode); + } + + /// + /// Filters a collection of permissions to only include permissions that use the Delete common permission type + /// + /// Filtered collection of permissions + public IEnumerable FilterToDeletePermissions() + { + return permissionsToFilter.FilterByPermissionCode(CommonPermissionTypes.DeletePermissionCode); + } + + /// + /// Filters a collection of permissions to only include permissions that use common + /// permission types associated with writing data which can include the "Create", "Update" and "Delete" + /// permissions as well as the more generic "Write" permission. + /// + /// Filtered collection of permissions + public IEnumerable FilterToWritePermissions() + { + return permissionsToFilter.Where(p => _writePermissionTypeCodes.Contains(p.PermissionType.Code)); + } + + /// + /// Filters a collection of permissions to only include permissions that permit + /// access to sections in the admin panel. Specifically permissions that use the + /// admin module common permission type code and the dashboard permission type code. + /// + /// Filtered collection of permissions + public IEnumerable FilterToAdminModulePermissions() + { + return permissionsToFilter + .Where(p => p.PermissionType.Code == CommonPermissionTypes.AdminModulePermissionCode + || p.PermissionType.Code == DashboardAdminModulePermission.PermissionTypeCode); + } + + /// + /// The anonymous role by default can read any entity except for users. + /// This is because user read permission means 'all users' not just 'current user' + /// and is associated with user management. + /// + /// Filtered collection of permissions + public IEnumerable FilterToAnonymousRoleDefaults() + { + return permissionsToFilter + .FilterToReadPermissions() + .ExceptUserManagementPermissions(); + } + + /// + /// Removes the specified permission from the collection. + /// + /// IPermission type to remove + /// Filtered collection of permissions + public IEnumerable ExceptPermission() + { + return permissionsToFilter.Where(p => p is not TPermission); + } + + /// + /// Removes permissions with the specified permission code from the collection. + /// + /// Code of the permission type to exclude from the collection + /// Filtered collection of permissions + public IEnumerable ExceptPermissionCode(string permissionCode) + { + return permissionsToFilter.Where(p => p.PermissionType.Code != permissionCode); + } + + /// + /// Removes permissions with the "Create" common permisison type from the collection. + /// + /// Filtered collection of permissions + public IEnumerable ExceptCreatePermissions() + { + return permissionsToFilter.ExceptPermissionCode(CommonPermissionTypes.CreatePermissionCode); + } + + /// + /// Removes permissions with the "Update" common permisison type from the collection. + /// + /// Filtered collection of permissions + public IEnumerable ExceptUpdatePermissions() + { + return permissionsToFilter.ExceptPermissionCode(CommonPermissionTypes.UpdatePermissionCode); + } + + /// + /// Removes permissions with the "Delete" common permisison type from the collection. + /// + /// Filtered collection of permissions + public IEnumerable ExceptDeletePermissions() + { + return permissionsToFilter.ExceptPermissionCode(CommonPermissionTypes.DeletePermissionCode); + } + + /// + /// Removes permissions with write common permisison types from the collection + /// which can include the "Create", "Update" and "Delete" permissions as well + /// as the more generic "Write" permission. + /// + /// Filtered collection of permissions + public IEnumerable ExceptWritePermissions() + { + return permissionsToFilter.Where(p => !_writePermissionTypeCodes.Contains(p.PermissionType.Code)); + } + + /// + /// Removes permissions from the collection associated with a specific entity type. + /// + /// Definition type of the entity to remove from the collection + /// Filtered collection of permissions + public IEnumerable ExceptEntityPermissions() + where TEntityDefinition : IEntityDefinition, new() + { + var entityDefiniton = new TEntityDefinition(); + + return permissionsToFilter.ExceptEntityPermissions(entityDefiniton.EntityDefinitionCode); + } + + /// + /// Removes permissions from the collection associated with a specific entity type. + /// + /// The definition code of the entity to remove e.g. PageEntityDefinition.DefinitionCode + /// + public IEnumerable ExceptEntityPermissions(string entityDefinitionCode) + { + return permissionsToFilter.Where(p => + p is not IEntityPermission + || ((IEntityPermission)p).EntityDefinition?.EntityDefinitionCode != entityDefinitionCode); + } + + /// + /// Filters a collection of permissions to exclude permissions to + /// access to sections in the admin panel. Specifically permissions that use the + /// admin module common permission type code and the dashboard permission type code. + /// + /// Filtered collection of permissions + public IEnumerable ExceptAdminModulePermissions() + { + return permissionsToFilter.Where(p => + p.PermissionType.Code != CommonPermissionTypes.AdminModulePermissionCode && p.PermissionType.Code != DashboardAdminModulePermission.PermissionTypeCode); - } - - /// - /// Removes all permissions for managing other user accounts. This does not - /// exclude self-management user permissions. - /// - /// The collection of permissions to filter - /// Filtered collection of permissions - public static IEnumerable ExceptUserManagementPermissions(this IEnumerable permissionsToFilter) - { - return permissionsToFilter - .ExceptEntityPermissions(UserEntityDefinition.DefinitionCode) - .ExceptEntityPermissions(NonCofoundryUserEntityDefinition.DefinitionCode); + } + + /// + /// Removes all permissions for managing other user accounts. This does not + /// exclude self-management user permissions. + /// + /// Filtered collection of permissions + public IEnumerable ExceptUserManagementPermissions() + { + return permissionsToFilter + .ExceptEntityPermissions(UserEntityDefinition.DefinitionCode) + .ExceptEntityPermissions(NonCofoundryUserEntityDefinition.DefinitionCode); + } } } diff --git a/src/Cofoundry.Domain/Domain/Roles/Models/IPermissionExtensions.cs b/src/Cofoundry.Domain/Domain/Roles/Models/IPermissionExtensions.cs index 8c79e04d3..bea081044 100644 --- a/src/Cofoundry.Domain/Domain/Roles/Models/IPermissionExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Roles/Models/IPermissionExtensions.cs @@ -1,16 +1,21 @@ -namespace Cofoundry.Domain; +namespace Cofoundry.Domain; +/// +/// Extensions for . +/// public static class IPermissionExtensions { - /// - /// Creates a unique code that represents this permission by combining the - /// entity definition code and the permission code. This is useful when - /// representing the permission as a unique string identifier. - /// - /// Permission to get the unique code for. - /// A string identifier that uniquely identifies this permission. - public static string GetUniqueIdentifier(this IPermission permission) + extension(IPermission permission) { - return PermissionIdentifierFormatter.GetUniqueIdentifier(permission); + /// + /// Creates a unique code that represents this permission by combining the + /// entity definition code and the permission code. This is useful when + /// representing the permission as a unique string identifier. + /// + /// A string identifier that uniquely identifies this permission. + public string GetUniqueIdentifier() + { + return PermissionIdentifierFormatter.GetUniqueIdentifier(permission); + } } } diff --git a/src/Cofoundry.Domain/Domain/Roles/Permissions/IPermissionSetBuilderRoleExtensions.cs b/src/Cofoundry.Domain/Domain/Roles/Permissions/IPermissionSetBuilderRoleExtensions.cs index d70b1b46f..63d09fcd1 100644 --- a/src/Cofoundry.Domain/Domain/Roles/Permissions/IPermissionSetBuilderRoleExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Roles/Permissions/IPermissionSetBuilderRoleExtensions.cs @@ -2,52 +2,46 @@ namespace Cofoundry.Domain; +/// +/// extension methods for roles. +/// public static class IPermissionSetBuilderRoleExtensions { - /// - /// Configure the builder to include all permissions for roles. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder IncludeRole(this IPermissionSetBuilder builder) + extension(IPermissionSetBuilder builder) { - return Run(builder, null, true); - } + /// + /// Configure the builder to include all permissions for roles. + /// + public IPermissionSetBuilder IncludeRole() + { + return Run(builder, null, true); + } - /// - /// Configure the builder to include permissions for roles. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to include. - public static IPermissionSetBuilder IncludeRole(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, true); - } + /// + /// Configure the builder to include permissions for roles. + /// + /// A configuration action to select which permissions to include. + public IPermissionSetBuilder IncludeRole(Action configure) + { + return Run(builder, configure, true); + } - /// - /// Configure the builder to exclude all permissions for roles. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder ExcludeRole(this IPermissionSetBuilder builder) - { - return Run(builder, null, false); - } + /// + /// Configure the builder to exclude all permissions for roles. + /// + public IPermissionSetBuilder ExcludeRole() + { + return Run(builder, null, false); + } - /// - /// Configure the builder to exclude permissions for roles. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to exclude. - public static IPermissionSetBuilder ExcludeRole(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, false); + /// + /// Configure the builder to exclude permissions for roles. + /// + /// A configuration action to select which permissions to exclude. + public IPermissionSetBuilder ExcludeRole(Action configure) + { + return Run(builder, configure, false); + } } private static IPermissionSetBuilder Run(IPermissionSetBuilder builder, Action? configure, bool isIncludeOperation) diff --git a/src/Cofoundry.Domain/Domain/Settings/Permissions/IPermissionSetBuilderSettingsExtensions.cs b/src/Cofoundry.Domain/Domain/Settings/Permissions/IPermissionSetBuilderSettingsExtensions.cs index 234fecd4e..437a66642 100644 --- a/src/Cofoundry.Domain/Domain/Settings/Permissions/IPermissionSetBuilderSettingsExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Settings/Permissions/IPermissionSetBuilderSettingsExtensions.cs @@ -2,52 +2,46 @@ namespace Cofoundry.Domain; +/// +/// extension methods for settings. +/// public static class IPermissionSetBuilderSettingsExtensions { - /// - /// Configure the builder to include all permissions for settings. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder IncludeSettings(this IPermissionSetBuilder builder) + extension(IPermissionSetBuilder builder) { - return Run(builder, null, true); - } + /// + /// Configure the builder to include all permissions for settings. + /// + public IPermissionSetBuilder IncludeSettings() + { + return Run(builder, null, true); + } - /// - /// Configure the builder to include permissions for settings. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to include. - public static IPermissionSetBuilder IncludeSettings(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, true); - } + /// + /// Configure the builder to include permissions for settings. + /// + /// A configuration action to select which permissions to include. + public IPermissionSetBuilder IncludeSettings(Action configure) + { + return Run(builder, configure, true); + } - /// - /// Configure the builder to exclude all permissions for settings. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder ExcludeSettings(this IPermissionSetBuilder builder) - { - return Run(builder, null, false); - } + /// + /// Configure the builder to exclude all permissions for settings. + /// + public IPermissionSetBuilder ExcludeSettings() + { + return Run(builder, null, false); + } - /// - /// Configure the builder to exclude permissions for settings. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to exclude. - public static IPermissionSetBuilder ExcludeSettings(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, false); + /// + /// Configure the builder to exclude permissions for settings. + /// + /// A configuration action to select which permissions to exclude. + public IPermissionSetBuilder ExcludeSettings(Action configure) + { + return Run(builder, configure, false); + } } private static IPermissionSetBuilder Run(IPermissionSetBuilder builder, Action? configure, bool isIncludeOperation) diff --git a/src/Cofoundry.Domain/Domain/Shared/Models/PublishableEntities/IPublishableEntityExtensions.cs b/src/Cofoundry.Domain/Domain/Shared/Models/PublishableEntities/IPublishableEntityExtensions.cs index 9e7eae2cc..ad00b3f1d 100644 --- a/src/Cofoundry.Domain/Domain/Shared/Models/PublishableEntities/IPublishableEntityExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Shared/Models/PublishableEntities/IPublishableEntityExtensions.cs @@ -1,28 +1,34 @@ -namespace Cofoundry.Domain; +namespace Cofoundry.Domain; +/// +/// Extension methods for . +/// public static class IPublishableEntityExtensions { - /// - /// Determines if the page is published at this moment in time, - /// checking the published status, the publish date and checking - /// to make sure there is a published version. - /// - public static bool IsPublished(this IPublishableEntity entity) + extension(IPublishableEntity entity) { - var isPublished = entity.PublishStatus == PublishStatus.Published - && entity.HasPublishedVersion - && entity.PublishDate <= DateTime.UtcNow; + /// + /// Determines if the page is published at this moment in time, + /// checking the published status, the publish date and checking + /// to make sure there is a published version. + /// + public bool IsPublished() + { + var isPublished = entity.PublishStatus == PublishStatus.Published + && entity.HasPublishedVersion + && entity.PublishDate <= DateTime.UtcNow; - return isPublished; - } + return isPublished; + } - /// - /// Gets the current publish state at the current moment in time. - /// - public static PublishState GetPublishState(this IPublishableEntity entity) - { - var publishState = entity.HasPublishedVersion ? entity.PublishStatus : PublishStatus.Unpublished; + /// + /// Gets the current publish state at the current moment in time. + /// + public PublishState GetPublishState() + { + var publishState = entity.HasPublishedVersion ? entity.PublishStatus : PublishStatus.Unpublished; - return new PublishState(publishState, entity.PublishDate); + return new PublishState(publishState, entity.PublishDate); + } } } diff --git a/src/Cofoundry.Domain/Domain/Shared/Models/PublishableEntities/IVersionRouteExtensions.cs b/src/Cofoundry.Domain/Domain/Shared/Models/PublishableEntities/IVersionRouteExtensions.cs index 34b800787..8c756e1a0 100644 --- a/src/Cofoundry.Domain/Domain/Shared/Models/PublishableEntities/IVersionRouteExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Shared/Models/PublishableEntities/IVersionRouteExtensions.cs @@ -1,60 +1,64 @@ -namespace Cofoundry.Domain; +namespace Cofoundry.Domain; +/// +/// Extension methods for . +/// public static class IVersionRouteExtensions { - /// - /// Determines if there is a published version - /// - public static bool HasPublishedVersion(this IEnumerable versions) - where T : IVersionRoute + extension(IEnumerable versions) where T : IVersionRoute { - return versions.Any(v => v.WorkFlowStatus == WorkFlowStatus.Published); - } - - /// - /// Gets version routing info for the specified PublishStatus query - /// - public static T? GetVersionRouting(this IEnumerable versions, PublishStatusQuery status, int? versionId = null) - where T : IVersionRoute - { - T? result; - - switch (status) + /// + /// Determines if there is a published version + /// + public bool HasPublishedVersion() { - case PublishStatusQuery.Draft: - result = versions - .SingleOrDefault(v => v.WorkFlowStatus == WorkFlowStatus.Draft); - break; - case PublishStatusQuery.Published: - result = versions - .Where(v => v.WorkFlowStatus == WorkFlowStatus.Published) - .OrderByDescending(v => v.CreateDate) - .FirstOrDefault(); - break; - case PublishStatusQuery.Latest: - result = versions - .Where(v => v.WorkFlowStatus == WorkFlowStatus.Draft || v.WorkFlowStatus == WorkFlowStatus.Published) - .OrderByDescending(v => v.WorkFlowStatus == WorkFlowStatus.Draft) - .FirstOrDefault(); - break; - case PublishStatusQuery.PreferPublished: - result = versions - .Where(v => v.WorkFlowStatus == WorkFlowStatus.Draft || v.WorkFlowStatus == WorkFlowStatus.Published) - .OrderByDescending(v => v.WorkFlowStatus == WorkFlowStatus.Published) - .FirstOrDefault(); - break; - case PublishStatusQuery.SpecificVersion: - if (!versionId.HasValue) - { - throw new InvalidOperationException("PublishStatusQuery.SpecificVersion requires a specific VersionId"); - } - result = versions - .SingleOrDefault(v => v.VersionId == versionId); - break; - default: - throw new InvalidOperationException("Unrecognised PublishStatusQuery: " + status); + return versions.Any(v => v.WorkFlowStatus == WorkFlowStatus.Published); } - return result; + /// + /// Gets version routing info for the specified PublishStatus query + /// + public T? GetVersionRouting(PublishStatusQuery status, int? versionId = null) + { + T? result; + + switch (status) + { + case PublishStatusQuery.Draft: + result = versions + .SingleOrDefault(v => v.WorkFlowStatus == WorkFlowStatus.Draft); + break; + case PublishStatusQuery.Published: + result = versions + .Where(v => v.WorkFlowStatus == WorkFlowStatus.Published) + .OrderByDescending(v => v.CreateDate) + .FirstOrDefault(); + break; + case PublishStatusQuery.Latest: + result = versions + .Where(v => v.WorkFlowStatus == WorkFlowStatus.Draft || v.WorkFlowStatus == WorkFlowStatus.Published) + .OrderByDescending(v => v.WorkFlowStatus == WorkFlowStatus.Draft) + .FirstOrDefault(); + break; + case PublishStatusQuery.PreferPublished: + result = versions + .Where(v => v.WorkFlowStatus == WorkFlowStatus.Draft || v.WorkFlowStatus == WorkFlowStatus.Published) + .OrderByDescending(v => v.WorkFlowStatus == WorkFlowStatus.Published) + .FirstOrDefault(); + break; + case PublishStatusQuery.SpecificVersion: + if (!versionId.HasValue) + { + throw new InvalidOperationException("PublishStatusQuery.SpecificVersion requires a specific VersionId"); + } + result = versions + .SingleOrDefault(v => v.VersionId == versionId); + break; + default: + throw new InvalidOperationException("Unrecognised PublishStatusQuery: " + status); + } + + return result; + } } } diff --git a/src/Cofoundry.Domain/Domain/Shared/Models/PublishableEntities/PublishStatusQueryExtensions.cs b/src/Cofoundry.Domain/Domain/Shared/Models/PublishableEntities/PublishStatusQueryExtensions.cs index 96743148f..146a56318 100644 --- a/src/Cofoundry.Domain/Domain/Shared/Models/PublishableEntities/PublishStatusQueryExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Shared/Models/PublishableEntities/PublishStatusQueryExtensions.cs @@ -1,27 +1,33 @@ -namespace Cofoundry.Domain; +namespace Cofoundry.Domain; +/// +/// Extension methods for . +/// public static class PublishStatusQueryExtensions { - /// - /// Turns the PublishStatusQuery used to query an entity into a PublishStatusQuery - /// that can be used to query dependent entities. E.g. PublishStatusQuery.SpecificVersion - /// cannot be used to query a dependent entity and so PublishStatusQuery.Latest is - /// used instead. - /// - /// - /// When working with child entities, the PublishStatusQuery we apply to - /// them is not neccessarily the status used to query the parent. If we are - /// loading a page using the Draft status, then we cannot expect that all - /// dependencies should have a draft version, so we re-write it to Latest. - /// The same applies if we're loading a specific version. - /// - public static PublishStatusQuery ToRelatedEntityQueryStatus(this PublishStatusQuery publishStatusQuery) + extension(PublishStatusQuery publishStatusQuery) { - if (publishStatusQuery == PublishStatusQuery.Draft || publishStatusQuery == PublishStatusQuery.SpecificVersion) + /// + /// Turns the used to query an entity into a + /// that can be used to query dependent entities. + /// E.g. cannot be used to query a + /// dependent entity and so is used instead. + /// + /// + /// When working with child entities, the we apply to + /// them is not neccessarily the status used to query the parent. If we are + /// loading a page using the Draft status, then we cannot expect that all + /// dependencies should have a draft version, so we re-write it to Latest. + /// The same applies if we're loading a specific version. + /// + public PublishStatusQuery ToRelatedEntityQueryStatus() { - publishStatusQuery = PublishStatusQuery.Latest; - } + if (publishStatusQuery == PublishStatusQuery.Draft || publishStatusQuery == PublishStatusQuery.SpecificVersion) + { + publishStatusQuery = PublishStatusQuery.Latest; + } - return publishStatusQuery; + return publishStatusQuery; + } } } diff --git a/src/Cofoundry.Domain/Domain/Shared/Paging/IPageableQueryExtensions.cs b/src/Cofoundry.Domain/Domain/Shared/Paging/IPageableQueryExtensions.cs index 0d2b0b0ed..091d1b8a7 100644 --- a/src/Cofoundry.Domain/Domain/Shared/Paging/IPageableQueryExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Shared/Paging/IPageableQueryExtensions.cs @@ -1,63 +1,59 @@ -namespace Cofoundry.Domain; +namespace Cofoundry.Domain; +/// +/// Extension methods for . +/// public static class IPageableQueryExtensions { - /// - /// Sets the paging bounds of an IPageableQuery, setting a default page - /// size if one isn't provided. - /// - /// Query to set the bounds of. - /// The default page size to apply if one is not set. - /// - /// By default negative page sizes indicate that no paging should apply, but - /// this setting can be used to prevent that behaviour. The default value is - /// false, which means the default page size will be applied if the page size - /// less than 0. If set to true the default page size will only be applied if - /// the page size is 0 i.e. negative page sizes will be permitted. - /// - public static void SetBounds( - this IPageableQuery query, - int defaultSize, - bool allowUnbounded = false - ) + extension(IPageableQuery query) { - ArgumentNullException.ThrowIfNull(query); - - if ((allowUnbounded && query.PageSize == 0) || - (!allowUnbounded && query.PageSize <= 0)) + /// + /// Sets the paging bounds of an , setting a default page + /// size if one isn't provided. + /// + /// The default page size to apply if one is not set. + /// + /// By default negative page sizes indicate that no paging should apply, but + /// this setting can be used to prevent that behaviour. The default value is + /// false, which means the default page size will be applied if the page size + /// less than 0. If set to true the default page size will only be applied if + /// the page size is 0 i.e. negative page sizes will be permitted. + /// + public void SetBounds(int defaultSize, bool allowUnbounded = false) { - query.PageSize = defaultSize; - } - } - - /// - /// Sets the paging bounds of an IPageableQuery, setting a default page - /// size if one isn't provided. This overload treats negative page sizes - /// as 'not set' rather than unbounded. It is assumed that if you're setting - /// a max size that you don't want to allow unbounded queries. - /// - /// Query to set the bounds of. - /// The default page size to apply if one is not set. - /// - /// The maximum page size limit to apply. If the PageSize setting is exceeds - /// this value then the PageSize is set to the maxSize value. - /// - public static void SetBounds( - this IPageableQuery query, - int defaultSize, - int maxSize - ) - { - ArgumentNullException.ThrowIfNull(query); + ArgumentNullException.ThrowIfNull(query); - if (query.PageSize <= 0) - { - query.PageSize = defaultSize; + if ((allowUnbounded && query.PageSize == 0) || + (!allowUnbounded && query.PageSize <= 0)) + { + query.PageSize = defaultSize; + } } - if (query.PageSize > maxSize) + /// + /// Sets the paging bounds of an , setting a default page + /// size if one isn't provided. This overload treats negative page sizes + /// as 'not set' rather than unbounded. It is assumed that if you're setting + /// a max size that you don't want to allow unbounded queries. + /// + /// The default page size to apply if one is not set. + /// + /// The maximum page size limit to apply. If the PageSize setting is exceeds + /// this value then the PageSize is set to the maxSize value. + /// + public void SetBounds(int defaultSize, int maxSize) { - query.PageSize = maxSize; + ArgumentNullException.ThrowIfNull(query); + + if (query.PageSize <= 0) + { + query.PageSize = defaultSize; + } + + if (query.PageSize > maxSize) + { + query.PageSize = maxSize; + } } } } diff --git a/src/Cofoundry.Domain/Domain/Shared/Paging/IPagedQueryResultExtensions.cs b/src/Cofoundry.Domain/Domain/Shared/Paging/IPagedQueryResultExtensions.cs index c2e5bd0d7..7fde4be3e 100644 --- a/src/Cofoundry.Domain/Domain/Shared/Paging/IPagedQueryResultExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Shared/Paging/IPagedQueryResultExtensions.cs @@ -1,14 +1,27 @@ -namespace Cofoundry.Domain; +namespace Cofoundry.Domain; +/// +/// Extension methods for . +/// public static class IPagedQueryResultExtensions { - public static bool IsFirstPage(this IPagedQueryResult source) + extension(IPagedQueryResult source) { - return source.PageNumber <= 1; - } + /// + /// if the result contains the first page of results. Page numbering + /// is 1-based, but the check counts anything less than 1 as the first page. + /// + public bool IsFirstPage() + { + return source.PageNumber <= 1; + } - public static bool IsLastPage(this IPagedQueryResult source) - { - return source.PageCount <= source.PageNumber; + /// + /// if the result is the last page of the result set. + /// + public bool IsLastPage() + { + return source.PageCount <= source.PageNumber; + } } -} \ No newline at end of file +} diff --git a/src/Cofoundry.Domain/Domain/Shared/Paging/PagingQueryExtensions.cs b/src/Cofoundry.Domain/Domain/Shared/Paging/PagingQueryExtensions.cs index 8e8dc0b1c..da5642a4e 100644 --- a/src/Cofoundry.Domain/Domain/Shared/Paging/PagingQueryExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Shared/Paging/PagingQueryExtensions.cs @@ -1,45 +1,50 @@ -namespace Cofoundry.Domain; +namespace Cofoundry.Domain; +/// +/// Extension methods for paging collections via . +/// public static class PagingQueryExtensions { - /// - /// Pages a query based on the parameters of the query. If the page size - /// is set to 0 or less then no paging is applied. - /// - /// Queryable source to apply paging to - /// The paging settings to apply to the source data. - public static IQueryable Page(this IQueryable source, IPageableQuery query) + extension(IQueryable source) { - if (query == null || query.PageSize <= 0) + /// + /// Pages a query based on the parameters of the query. If the page size + /// is set to 0 or less then no paging is applied. + /// + /// The paging settings to apply to the source data. + public IQueryable Page(IPageableQuery query) { - return source; - } - - var pageNumber = query.PageNumber < 1 ? 0 : query.PageNumber - 1; - var itemsToSkip = pageNumber * query.PageSize; + if (query == null || query.PageSize <= 0) + { + return source; + } - return source - .Skip(itemsToSkip) - .Take(query.PageSize); - } + var pageNumber = query.PageNumber < 1 ? 0 : query.PageNumber - 1; + var itemsToSkip = pageNumber * query.PageSize; - /// - /// Converts a query to an instance of PagedQueryResult, executing the query twice, - /// once to get the total count and again to get the results. - /// - public static PagedQueryResult ToPagedResult(this IQueryable source, IPageableQuery query) - { - ArgumentNullException.ThrowIfNull(source); + return source + .Skip(itemsToSkip) + .Take(query.PageSize); + } - var result = new PagedQueryResult + /// + /// Converts a query to an instance of PagedQueryResult, executing the query twice, + /// once to get the total count and again to get the results. + /// + public PagedQueryResult ToPagedResult(IPageableQuery query) { - TotalItems = source.Count(), - Items = source.Page(query).ToArray() - }; + ArgumentNullException.ThrowIfNull(source); + + var result = new PagedQueryResult + { + TotalItems = source.Count(), + Items = source.Page(query).ToArray() + }; - MapPagingData(query, result); + MapPagingData(query, result); - return result; + return result; + } } /// diff --git a/src/Cofoundry.Domain/Domain/UserAreas/ContentRepositoryExtensions/ContentRepositoryUserAreaExtensions.cs b/src/Cofoundry.Domain/Domain/UserAreas/ContentRepositoryExtensions/ContentRepositoryUserAreaExtensions.cs index 6d9af7fd2..e4281c80c 100644 --- a/src/Cofoundry.Domain/Domain/UserAreas/ContentRepositoryExtensions/ContentRepositoryUserAreaExtensions.cs +++ b/src/Cofoundry.Domain/Domain/UserAreas/ContentRepositoryExtensions/ContentRepositoryUserAreaExtensions.cs @@ -1,15 +1,21 @@ -using Cofoundry.Domain.Extendable; +using Cofoundry.Domain.Extendable; using Cofoundry.Domain.Internal; namespace Cofoundry.Domain; +/// +/// Content repository extension methods for user areas. +/// public static class ContentRepositoryUserAreaExtensions { - /// - /// Queries and commands relating to user areas and their configuration. - /// - public static IAdvancedContentRepositoryUserAreaRepository UserAreas(this IAdvancedContentRepository contentRepository) + extension(IAdvancedContentRepository contentRepository) { - return new ContentRepositoryUserAreaRepository(contentRepository.AsExtendableContentRepository()); + /// + /// Queries and commands relating to user areas and their configuration. + /// + public IAdvancedContentRepositoryUserAreaRepository UserAreas() + { + return new ContentRepositoryUserAreaRepository(contentRepository.AsExtendableContentRepository()); + } } } diff --git a/src/Cofoundry.Domain/Domain/UserAreas/Repositories/IUserAreaDefinitionRepositoryExtensions.cs b/src/Cofoundry.Domain/Domain/UserAreas/Repositories/IUserAreaDefinitionRepositoryExtensions.cs index 1544680bd..a1220d46c 100644 --- a/src/Cofoundry.Domain/Domain/UserAreas/Repositories/IUserAreaDefinitionRepositoryExtensions.cs +++ b/src/Cofoundry.Domain/Domain/UserAreas/Repositories/IUserAreaDefinitionRepositoryExtensions.cs @@ -1,17 +1,20 @@ namespace Cofoundry.Domain; +/// +/// Content repository extension methods for user area definitions. +/// public static class IUserAreaDefinitionRepositoryExtensions { - /// - /// Determins if a user area exists with the specified code. - /// - /// - /// Repository to extend. - /// - /// The unique 3 character code that identifies the user area definition. - /// if the user area exists; otherwise . - public static bool Exists(this IUserAreaDefinitionRepository userAreaDefinitionRepository, string? userAreaCode) + extension(IUserAreaDefinitionRepository userAreaDefinitionRepository) { - return !string.IsNullOrEmpty(userAreaCode) && userAreaDefinitionRepository.GetByCode(userAreaCode) != null; + /// + /// Determins if a user area exists with the specified code. + /// + /// The unique 3 character code that identifies the user area definition. + /// if the user area exists; otherwise . + public bool Exists(string? userAreaCode) + { + return !string.IsNullOrEmpty(userAreaCode) && userAreaDefinitionRepository.GetByCode(userAreaCode) != null; + } } } diff --git a/src/Cofoundry.Domain/Domain/Users/ContentRepositoryExtensions/ContentRepositoryUserExtensions.cs b/src/Cofoundry.Domain/Domain/Users/ContentRepositoryExtensions/ContentRepositoryUserExtensions.cs index abacbeea1..d40053083 100644 --- a/src/Cofoundry.Domain/Domain/Users/ContentRepositoryExtensions/ContentRepositoryUserExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Users/ContentRepositoryExtensions/ContentRepositoryUserExtensions.cs @@ -1,27 +1,36 @@ -using Cofoundry.Domain.Extendable; +using Cofoundry.Domain.Extendable; using Cofoundry.Domain.Internal; namespace Cofoundry.Domain; +/// +/// Content repository extension methods for users. +/// public static class ContentRepositoryUserExtensions { - /// - /// Queries and commands relating to users from the Cofoundry identity - /// system. This includes users from both the Cofoundry admin user area - /// and any custom user areas. - /// - public static IContentRepositoryUserRepository Users(this IContentRepository contentRepository) + extension(IContentRepository contentRepository) { - return new ContentRepositoryUserRepository(contentRepository.AsExtendableContentRepository()); + /// + /// Queries and commands relating to users from the Cofoundry identity + /// system. This includes users from both the Cofoundry admin user area + /// and any custom user areas. + /// + public IContentRepositoryUserRepository Users() + { + return new ContentRepositoryUserRepository(contentRepository.AsExtendableContentRepository()); + } } - /// - /// Queries and commands relating to users from the Cofoundry identity - /// system. This includes users from both the Cofoundry admin user area - /// and any custom user areas. - /// - public static IAdvancedContentRepositoryUserRepository Users(this IAdvancedContentRepository contentRepository) + extension(IAdvancedContentRepository contentRepository) { - return new AdvancedContentRepositoryUserRepository(contentRepository.AsExtendableContentRepository()); + /// + /// Queries and commands relating to users from the Cofoundry identity + /// system. This includes users from both the Cofoundry admin user area + /// and any custom user areas. + /// + public IAdvancedContentRepositoryUserRepository Users() + { + return new AdvancedContentRepositoryUserRepository(contentRepository.AsExtendableContentRepository()); + } } } diff --git a/src/Cofoundry.Domain/Domain/Users/Permissions/IPermissionSetBuilderUserExtensions.cs b/src/Cofoundry.Domain/Domain/Users/Permissions/IPermissionSetBuilderUserExtensions.cs index e200c97ef..b368f0059 100644 --- a/src/Cofoundry.Domain/Domain/Users/Permissions/IPermissionSetBuilderUserExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Users/Permissions/IPermissionSetBuilderUserExtensions.cs @@ -2,168 +2,135 @@ namespace Cofoundry.Domain; +/// +/// extension methods for users. +/// public static class IPermissionSetBuilderUserExtensions { - /// - /// Removes permissions for managing user accounts in all user areas, however this does not - /// exclude permissions for managing the currently signed in user account. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder ExcludeUserInAllUserAreas(this IPermissionSetBuilder builder) - { - return builder.Exclude(permissions => permissions.ExceptUserManagementPermissions()); - } - - /// - /// Configure the builder to include all permissions for users in the Cofoundry admin user area. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder IncludeUserInCofoundryAdminUserArea(this IPermissionSetBuilder builder) - { - return Run(builder, configure, true); - - static void configure(CofoundryUserPermissionBuilder c) => c.All(); - } - - /// - /// Configure the builder to include permissions for users in the Cofoundry admin user area. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to include. - public static IPermissionSetBuilder IncludeUserInCofoundryAdminUserArea(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, true); - } - - /// - /// Configure the builder to exclude permissions for users in the Cofoundry admin user area - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to exclude. - public static IPermissionSetBuilder ExcludeUserInCofoundryAdminUserArea(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, false); - } - - /// - /// Configure the builder to exclude all permissions for users in the Cofoundry admin user area. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder ExcludeUserInCofoundryAdminUserArea(this IPermissionSetBuilder builder) - { - return Run(builder, configure, false); - - static void configure(CofoundryUserPermissionBuilder c) => c.All(); - } - - /// - /// Configure the builder to include all permissions for users in a custom user area (excludes the Cofoundry admin user area). - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder IncludeUserInCustomUserArea(this IPermissionSetBuilder builder) - { - return Run(builder, configure, true); - - static void configure(NonCofoundryUserPermissionBuilder c) => c.All(); - } - - /// - /// Configure the builder to include permissions for users in a custom user area (excludes the Cofoundry admin user area). - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to include. - public static IPermissionSetBuilder IncludeUserInCustomUserArea(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, true); - } - - /// - /// Configure the builder to exclude all permissions for users in a custom user area (excludes the Cofoundry admin user area). - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder ExcludeUserInCustomUserArea(this IPermissionSetBuilder builder) - { - return Run(builder, configure, false); - - static void configure(NonCofoundryUserPermissionBuilder c) => c.All(); - } - - /// - /// Configure the builder to exclude permissions for users in a custom user area (excludes the Cofoundry admin user area). - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to exclude. - public static IPermissionSetBuilder ExcludeUserInCustomUserArea(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, false); - } - - /// - /// Configure the builder to include all permissions for the currently signed in user account. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder IncludeCurrentUser(this IPermissionSetBuilder builder) - { - return Run(builder, configure, true); - - static void configure(CurrentUserPermissionBuilder c) => c.All(); - } - - /// - /// Configure the builder to include permissions for the currently signed in user account. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to include. - public static IPermissionSetBuilder IncludeCurrentUser(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, true); - } - - /// - /// Configure the builder to exclude all permissions for the currently signed in user account. - /// - /// - /// Builder to filter on. - /// - public static IPermissionSetBuilder ExcludeCurrentUser(this IPermissionSetBuilder builder) - { - return Run(builder, configure, false); - - static void configure(CurrentUserPermissionBuilder c) => c.All(); - } - - /// - /// Configure the builder to exclude permissions for the currently signed in user account. - /// - /// - /// Builder to filter on. - /// - /// A configuration action to select which permissions to exclude. - public static IPermissionSetBuilder ExcludeCurrentUser(this IPermissionSetBuilder builder, Action configure) - { - return Run(builder, configure, false); + extension(IPermissionSetBuilder builder) + { + /// + /// Removes permissions for managing user accounts in all user areas, however this does not + /// exclude permissions for managing the currently signed in user account. + /// + public IPermissionSetBuilder ExcludeUserInAllUserAreas() + { + return builder.Exclude(permissions => permissions.ExceptUserManagementPermissions()); + } + + /// + /// Configure the builder to include all permissions for users in the Cofoundry admin user area. + /// + public IPermissionSetBuilder IncludeUserInCofoundryAdminUserArea() + { + return Run(builder, configure, true); + + static void configure(CofoundryUserPermissionBuilder c) => c.All(); + } + + /// + /// Configure the builder to include permissions for users in the Cofoundry admin user area. + /// + /// A configuration action to select which permissions to include. + public IPermissionSetBuilder IncludeUserInCofoundryAdminUserArea(Action configure) + { + return Run(builder, configure, true); + } + + /// + /// Configure the builder to exclude permissions for users in the Cofoundry admin user area + /// + /// A configuration action to select which permissions to exclude. + public IPermissionSetBuilder ExcludeUserInCofoundryAdminUserArea(Action configure) + { + return Run(builder, configure, false); + } + + /// + /// Configure the builder to exclude all permissions for users in the Cofoundry admin user area. + /// + public IPermissionSetBuilder ExcludeUserInCofoundryAdminUserArea() + { + return Run(builder, configure, false); + + static void configure(CofoundryUserPermissionBuilder c) => c.All(); + } + + /// + /// Configure the builder to include all permissions for users in a custom user area (excludes the Cofoundry admin user area). + /// + public IPermissionSetBuilder IncludeUserInCustomUserArea() + { + return Run(builder, configure, true); + + static void configure(NonCofoundryUserPermissionBuilder c) => c.All(); + } + + /// + /// Configure the builder to include permissions for users in a custom user area (excludes the Cofoundry admin user area). + /// + /// A configuration action to select which permissions to include. + public IPermissionSetBuilder IncludeUserInCustomUserArea(Action configure) + { + return Run(builder, configure, true); + } + + /// + /// Configure the builder to exclude all permissions for users in a custom user area (excludes the Cofoundry admin user area). + /// + public IPermissionSetBuilder ExcludeUserInCustomUserArea() + { + return Run(builder, configure, false); + + static void configure(NonCofoundryUserPermissionBuilder c) => c.All(); + } + + /// + /// Configure the builder to exclude permissions for users in a custom user area (excludes the Cofoundry admin user area). + /// + /// A configuration action to select which permissions to exclude. + public IPermissionSetBuilder ExcludeUserInCustomUserArea(Action configure) + { + return Run(builder, configure, false); + } + + /// + /// Configure the builder to include all permissions for the currently signed in user account. + /// + public IPermissionSetBuilder IncludeCurrentUser() + { + return Run(builder, configure, true); + + static void configure(CurrentUserPermissionBuilder c) => c.All(); + } + + /// + /// Configure the builder to include permissions for the currently signed in user account. + /// + /// A configuration action to select which permissions to include. + public IPermissionSetBuilder IncludeCurrentUser(Action configure) + { + return Run(builder, configure, true); + } + + /// + /// Configure the builder to exclude all permissions for the currently signed in user account. + /// + public IPermissionSetBuilder ExcludeCurrentUser() + { + return Run(builder, configure, false); + + static void configure(CurrentUserPermissionBuilder c) => c.All(); + } + + /// + /// Configure the builder to exclude permissions for the currently signed in user account. + /// + /// A configuration action to select which permissions to exclude. + public IPermissionSetBuilder ExcludeCurrentUser(Action configure) + { + return Run(builder, configure, false); + } } private static IPermissionSetBuilder Run(IPermissionSetBuilder builder, Action configure, bool isIncludeOperation) diff --git a/src/Cofoundry.Domain/Domain/Users/Services/InMemoryUserSessionService.cs b/src/Cofoundry.Domain/Domain/Users/Services/InMemoryUserSessionService.cs index c2bc494f9..6d0891e37 100644 --- a/src/Cofoundry.Domain/Domain/Users/Services/InMemoryUserSessionService.cs +++ b/src/Cofoundry.Domain/Domain/Users/Services/InMemoryUserSessionService.cs @@ -4,21 +4,22 @@ namespace Cofoundry.Domain.Internal; /// In-memory implementation of IUserSessionService for non-web /// scenarios. /// -/// public class InMemoryUserSessionService : IUserSessionService { private const string AMBIENT_USER_AREA_KEY = "AMBIENT_KEY"; private readonly Dictionary _userIdCache = []; - private readonly object _lock = new(); + private readonly Lock _lock = new(); private string _ambientUserAreaCode; private readonly IUserAreaDefinitionRepository _userAreaDefinitionRepository; private readonly IUserContextCache _userContextCache; + /// + /// DI constructor. + /// public InMemoryUserSessionService( IUserAreaDefinitionRepository userAreaDefinitionRepository, - IUserContextCache userContextCache - ) + IUserContextCache userContextCache) { _userAreaDefinitionRepository = userAreaDefinitionRepository; _userContextCache = userContextCache; @@ -26,17 +27,20 @@ IUserContextCache userContextCache ResetAmbientUserAreaToDefault(); } + /// public int? GetCurrentUserId() { return _userIdCache.GetValueOrDefault(AMBIENT_USER_AREA_KEY); } + /// public Task GetUserIdByUserAreaCodeAsync(string userAreaCode) { var result = GetUserIdByUserAreaCode(userAreaCode); return Task.FromResult(result); } + /// public int? GetUserIdByUserAreaCode(string userAreaCode) { ArgumentNullException.ThrowIfNull(userAreaCode); @@ -44,6 +48,7 @@ IUserContextCache userContextCache return _userIdCache.GetValueOrDefault(userAreaCode); } + /// public Task SignInAsync(string userAreaDefinitionCode, int userId, bool rememberUser) { ArgumentNullException.ThrowIfNull(userAreaDefinitionCode); @@ -66,6 +71,7 @@ public Task SignInAsync(string userAreaDefinitionCode, int userId, bool remember return Task.CompletedTask; } + /// public Task SignOutAsync(string userAreaDefinitionCode) { ArgumentNullException.ThrowIfNull(userAreaDefinitionCode); @@ -115,6 +121,7 @@ public Task SignOutOfAllUserAreasAsync() return Task.CompletedTask; } + /// public Task SetAmbientUserAreaAsync(string userAreaCode) { ArgumentException.ThrowIfNullOrWhiteSpace(userAreaCode); @@ -148,6 +155,7 @@ private bool IsAmbientUserArea(IUserAreaDefinition userArea) return _ambientUserAreaCode == userArea.UserAreaCode; } + /// public Task RefreshAsync(string userAreaCode, int userId) { // No-op: nothing to refresh diff --git a/src/Cofoundry.Domain/Domain/Users/Validators/IEmailAddressValidatorExtensions.cs b/src/Cofoundry.Domain/Domain/Users/Validators/IEmailAddressValidatorExtensions.cs index ee1a217d2..7a017e5d2 100644 --- a/src/Cofoundry.Domain/Domain/Users/Validators/IEmailAddressValidatorExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Users/Validators/IEmailAddressValidatorExtensions.cs @@ -1,20 +1,23 @@ -namespace Cofoundry.Domain; +namespace Cofoundry.Domain; public static class IEmailAddressValidatorExtensions { - /// - /// Validates a user email address, throwing a - /// if any errors are found. By default the validator checks that the format contains only - /// the characters permitted by the configuration settings, - /// as well as checking for uniquness. - /// - public static async Task ValidateAsync(this IEmailAddressValidator emailAddressValidator, IEmailAddressValidationContext context) + extension(IEmailAddressValidator emailAddressValidator) { - var result = await emailAddressValidator.GetErrorsAsync(context); - - if (result.Count != 0) + /// + /// Validates a user email address, throwing a + /// if any errors are found. By default the validator checks that the format contains only + /// the characters permitted by the configuration settings, + /// as well as checking for uniquness. + /// + public async Task ValidateAsync(IEmailAddressValidationContext context) { - throw new ValidationErrorException(result.First()); + var result = await emailAddressValidator.GetErrorsAsync(context); + + if (result.Count != 0) + { + throw new ValidationErrorException(result.First()); + } } } } diff --git a/src/Cofoundry.Domain/Domain/Users/Validators/IUsernameValidatorExtensions.cs b/src/Cofoundry.Domain/Domain/Users/Validators/IUsernameValidatorExtensions.cs index f8da23e45..ffb3b0d43 100644 --- a/src/Cofoundry.Domain/Domain/Users/Validators/IUsernameValidatorExtensions.cs +++ b/src/Cofoundry.Domain/Domain/Users/Validators/IUsernameValidatorExtensions.cs @@ -1,20 +1,23 @@ -namespace Cofoundry.Domain; +namespace Cofoundry.Domain; public static class IUsernameValidatorExtensions { - /// - /// Validates a username, throwing a - /// if any errors are found. By default the validator checks that the - /// format contains only the characters permitted by the - /// configuration settings, as well as checking for uniquness. - /// - public static async Task ValidateAsync(this IUsernameValidator usernameValidator, IUsernameValidationContext context) + extension(IUsernameValidator usernameValidator) { - var result = await usernameValidator.GetErrorsAsync(context); - - if (result.Count != 0) + /// + /// Validates a username, throwing a + /// if any errors are found. By default the validator checks that the + /// format contains only the characters permitted by the + /// configuration settings, as well as checking for uniquness. + /// + public async Task ValidateAsync(IUsernameValidationContext context) { - throw new ValidationErrorException(result.First()); + var result = await usernameValidator.GetErrorsAsync(context); + + if (result.Count != 0) + { + throw new ValidationErrorException(result.First()); + } } } } diff --git a/src/Cofoundry.Domain/Domain/VisualEditor/VisualEditorModeExtensions.cs b/src/Cofoundry.Domain/Domain/VisualEditor/VisualEditorModeExtensions.cs index d737e1e0e..4aef1a436 100644 --- a/src/Cofoundry.Domain/Domain/VisualEditor/VisualEditorModeExtensions.cs +++ b/src/Cofoundry.Domain/Domain/VisualEditor/VisualEditorModeExtensions.cs @@ -1,41 +1,47 @@ -namespace Cofoundry.Domain; +namespace Cofoundry.Domain; +/// +/// Extension methods for . +/// public static class VisualEditorModeExtensions { - /// - /// Converts the user requested VisualEditorMode into the equivalent - /// PublishStatusQuery which can be used for domain querying. - /// - public static PublishStatusQuery ToPublishStatusQuery(this VisualEditorMode visualEditorMode) + extension(VisualEditorMode visualEditorMode) { - return visualEditorMode switch + /// + /// Converts the user requested VisualEditorMode into the equivalent + /// PublishStatusQuery which can be used for domain querying. + /// + public PublishStatusQuery ToPublishStatusQuery() { - VisualEditorMode.Preview or VisualEditorMode.Edit => PublishStatusQuery.Draft, - VisualEditorMode.Any => PublishStatusQuery.Latest, - VisualEditorMode.SpecificVersion => PublishStatusQuery.SpecificVersion, - _ => PublishStatusQuery.Published, - }; - } + return visualEditorMode switch + { + VisualEditorMode.Preview or VisualEditorMode.Edit => PublishStatusQuery.Draft, + VisualEditorMode.Any => PublishStatusQuery.Latest, + VisualEditorMode.SpecificVersion => PublishStatusQuery.SpecificVersion, + _ => PublishStatusQuery.Published, + }; + } - /// - /// Gets the publish status that should be used to query any - /// entities that are not the primary target of the visual - /// editor, e.g. a related entity or entities not directly associated - /// with an entity being edited. - /// - /// - /// In most cases this would be the same for both primary and ambient - /// entity, but in some cases it is different e.g. if the primary - /// entity has been requested as a specific version then ambient entities - /// cannot also be a specific version and should show the latest. - /// - public static PublishStatusQuery ToAmbientEntityPublishStatusQuery(this VisualEditorMode visualEditorMode) - { - if (visualEditorMode == VisualEditorMode.Live) + /// + /// Gets the publish status that should be used to query any + /// entities that are not the primary target of the visual + /// editor, e.g. a related entity or entities not directly associated + /// with an entity being edited. + /// + /// + /// In most cases this would be the same for both primary and ambient + /// entity, but in some cases it is different e.g. if the primary + /// entity has been requested as a specific version then ambient entities + /// cannot also be a specific version and should show the latest. + /// + public PublishStatusQuery ToAmbientEntityPublishStatusQuery() { - return PublishStatusQuery.Published; - } + if (visualEditorMode == VisualEditorMode.Live) + { + return PublishStatusQuery.Published; + } - return PublishStatusQuery.Latest; + return PublishStatusQuery.Latest; + } } } diff --git a/src/Cofoundry.Plugins/Cofoundry.Plugins.Azure/Cofoundry.Plugins.Azure/Cofoundry.Plugins.Azure.csproj b/src/Cofoundry.Plugins/Cofoundry.Plugins.Azure/Cofoundry.Plugins.Azure/Cofoundry.Plugins.Azure.csproj index e96d11477..a1274c413 100644 --- a/src/Cofoundry.Plugins/Cofoundry.Plugins.Azure/Cofoundry.Plugins.Azure/Cofoundry.Plugins.Azure.csproj +++ b/src/Cofoundry.Plugins/Cofoundry.Plugins.Azure/Cofoundry.Plugins.Azure/Cofoundry.Plugins.Azure.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Cofoundry.Plugins/Cofoundry.Plugins.Azure/Cofoundry.Plugins.Azure/IContainerRegisterExtensions.cs b/src/Cofoundry.Plugins/Cofoundry.Plugins.Azure/Cofoundry.Plugins.Azure/IContainerRegisterExtensions.cs index 8a18d6924..7b652a752 100644 --- a/src/Cofoundry.Plugins/Cofoundry.Plugins.Azure/Cofoundry.Plugins.Azure/IContainerRegisterExtensions.cs +++ b/src/Cofoundry.Plugins/Cofoundry.Plugins.Azure/Cofoundry.Plugins.Azure/IContainerRegisterExtensions.cs @@ -1,16 +1,22 @@ -using Cofoundry.Core.DependencyInjection; +using Cofoundry.Core.DependencyInjection; namespace Cofoundry.Plugins.Azure; +/// +/// Extension methods for . +/// public static class IContainerRegisterExtensions { - /// - /// Indicates whether the Cofoundry.Plugins.Azure plugin has been - /// disabled via config settings. - /// - /// True if the azure plugin is disabled; otherwise false. - public static bool IsAzurePluginEnabled(this IContainerConfigurationHelper helper) + extension(IContainerConfigurationHelper helper) { - return !helper.GetValue("Cofoundry:Plugins:Azure:Disabled"); + /// + /// Indicates whether the Cofoundry.Plugins.Azure plugin has been + /// disabled via config settings. + /// + /// True if the azure plugin is disabled; otherwise false. + public bool IsAzurePluginEnabled() + { + return !helper.GetValue("Cofoundry:Plugins:Azure:Disabled"); + } } } diff --git a/src/Cofoundry.Plugins/Cofoundry.Plugins.BackgroundTasks.Hangfire/Cofoundry.Plugins.BackgroundTasks.Hangfire/Startup/HangfireInitializationMiddleware.cs b/src/Cofoundry.Plugins/Cofoundry.Plugins.BackgroundTasks.Hangfire/Cofoundry.Plugins.BackgroundTasks.Hangfire/Startup/HangfireInitializationMiddleware.cs index 4e0ab6ca9..9f1b85fd2 100644 --- a/src/Cofoundry.Plugins/Cofoundry.Plugins.BackgroundTasks.Hangfire/Cofoundry.Plugins.BackgroundTasks.Hangfire/Startup/HangfireInitializationMiddleware.cs +++ b/src/Cofoundry.Plugins/Cofoundry.Plugins.BackgroundTasks.Hangfire/Cofoundry.Plugins.BackgroundTasks.Hangfire/Startup/HangfireInitializationMiddleware.cs @@ -6,12 +6,10 @@ namespace Cofoundry.Plugins.BackgroundTasks.Hangfire; public class HangfireInitializationMiddleware { private static bool _isInitialized; - private static readonly object _isInitializedLock = new(); + private static readonly Lock _isInitializedLock = new(); private readonly RequestDelegate _next; - public HangfireInitializationMiddleware( - RequestDelegate next - ) + public HangfireInitializationMiddleware(RequestDelegate next) { _next = next; } diff --git a/src/Cofoundry.Plugins/Cofoundry.Plugins.Vimeo/Cofoundry.Plugins.Vimeo.Domain/VimeoUrlParser.cs b/src/Cofoundry.Plugins/Cofoundry.Plugins.Vimeo/Cofoundry.Plugins.Vimeo.Domain/VimeoUrlParser.cs index df2776d63..463666539 100644 --- a/src/Cofoundry.Plugins/Cofoundry.Plugins.Vimeo/Cofoundry.Plugins.Vimeo.Domain/VimeoUrlParser.cs +++ b/src/Cofoundry.Plugins/Cofoundry.Plugins.Vimeo/Cofoundry.Plugins.Vimeo.Domain/VimeoUrlParser.cs @@ -11,8 +11,8 @@ public static partial class VimeoUrlParser /// Extracts the ID of a video from a Vimeo URL. /// /// The vimeo video URL. - /// The id of the Vimeo video, or empty string if the id couldn't be extracted - public static string GetId(this string vimeoVideoUrl) + /// The id of the Vimeo video, or empty string if the id couldn't be extracted. + public static string GetId(string vimeoVideoUrl) { var match = VimeoRegex().Match(vimeoVideoUrl); @@ -24,6 +24,6 @@ public static string GetId(this string vimeoVideoUrl) return match.Groups[5].Value; } - [GeneratedRegex(@"^.*(vimeo\.com\/)((channels\/[A-z]+\/)|(groups\/[A-z]+\/videos\/))?([0-9]+)", RegexOptions.IgnoreCase | RegexOptions.Multiline, "en-GB")] + [GeneratedRegex(@"^.*(vimeo\.com\/)((channels\/[A-z]+\/)|(groups\/[A-z]+\/videos\/))?([0-9]+)", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant)] private static partial Regex VimeoRegex(); } diff --git a/src/Cofoundry.Plugins/Cofoundry.Plugins.YouTube/Cofoundry.Plugins.YouTube.Domain/YouTubeUrlParser.cs b/src/Cofoundry.Plugins/Cofoundry.Plugins.YouTube/Cofoundry.Plugins.YouTube.Domain/YouTubeUrlParser.cs index 7aeb9bc44..d8661718a 100644 --- a/src/Cofoundry.Plugins/Cofoundry.Plugins.YouTube/Cofoundry.Plugins.YouTube.Domain/YouTubeUrlParser.cs +++ b/src/Cofoundry.Plugins/Cofoundry.Plugins.YouTube/Cofoundry.Plugins.YouTube.Domain/YouTubeUrlParser.cs @@ -25,6 +25,6 @@ public static string GetId(string youTubeVideoUrl) return match.Groups[1].Value; } - [GeneratedRegex(@"youtu(?:\.be|be\.com)/(?:.*v(?:/|=)|(?:.*/)?)([a-zA-Z0-9-_]+)", RegexOptions.IgnoreCase | RegexOptions.Multiline, "en-GB")] + [GeneratedRegex(@"youtu(?:\.be|be\.com)/(?:.*v(?:/|=)|(?:.*/)?)([a-zA-Z0-9-_]+)", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant)] private static partial Regex YouTubeRegex(); } diff --git a/src/Cofoundry.Web.Admin/Cofoundry.Web.Admin.csproj b/src/Cofoundry.Web.Admin/Cofoundry.Web.Admin.csproj index 1327603d0..e70624c88 100644 --- a/src/Cofoundry.Web.Admin/Cofoundry.Web.Admin.csproj +++ b/src/Cofoundry.Web.Admin/Cofoundry.Web.Admin.csproj @@ -10,13 +10,13 @@ - - - - + + + + - + diff --git a/src/Cofoundry.Web.Admin/Framework/Helpers/SettingsViewHelperExtensions.cs b/src/Cofoundry.Web.Admin/Framework/Helpers/SettingsViewHelperExtensions.cs index 09d361bc1..9e3597b4d 100644 --- a/src/Cofoundry.Web.Admin/Framework/Helpers/SettingsViewHelperExtensions.cs +++ b/src/Cofoundry.Web.Admin/Framework/Helpers/SettingsViewHelperExtensions.cs @@ -1,10 +1,16 @@ -namespace Cofoundry.Web.Admin; +namespace Cofoundry.Web.Admin; +/// +/// Extension methods for . +/// public static class SettingsViewHelperExtensions { - public static async Task GetApplicationNameAsync(this ISettingsViewHelper helper) + extension(ISettingsViewHelper helper) { - var settings = await helper.GetAsync(); - return settings.ApplicationName; + public async Task GetApplicationNameAsync() + { + var settings = await helper.GetAsync(); + return settings.ApplicationName; + } } } diff --git a/src/Cofoundry.Web.Admin/Framework/Routing/AdminRouteBuilderExtensions.cs b/src/Cofoundry.Web.Admin/Framework/Routing/AdminRouteBuilderExtensions.cs index 40bd1ddf4..67d8cba13 100644 --- a/src/Cofoundry.Web.Admin/Framework/Routing/AdminRouteBuilderExtensions.cs +++ b/src/Cofoundry.Web.Admin/Framework/Routing/AdminRouteBuilderExtensions.cs @@ -1,54 +1,58 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; namespace Cofoundry.Web.Admin; +/// +/// extensions for adding admin panel routes. +/// public static class AdminRouteBuilderExtensions { - /// - /// Returns a builder context than can be used to add admin panel routes - /// to the specified MVC controller. Routes specified through this method - /// will automatically be registered with the correct admin panel path, which - /// can be altered via the Cofoundry:Admin:DirectoryName setting. - /// - /// - /// The controller type to add routes for. This type is used to scope the - /// routes to the controller. - /// - /// The route builder to add routes to. - /// - /// The base path of all routes on the controller, without the admin directory - /// or any leading or trailing slashes e.g. "auth", "images", "users/roles" - /// - /// Builder context that can be used to add routes. - public static AdminRouteBuilderContext ForAdminController(this IEndpointRouteBuilder routeBuilder, string basePath) - where TController : Controller + extension(IEndpointRouteBuilder routeBuilder) { - var adminSettings = routeBuilder.ServiceProvider.GetRequiredService(); - return new AdminRouteBuilderContext(adminSettings, routeBuilder, basePath); - } + /// + /// Returns a builder context than can be used to add admin panel routes + /// to the specified MVC controller. Routes specified through this method + /// will automatically be registered with the correct admin panel path, which + /// can be altered via the Cofoundry:Admin:DirectoryName setting. + /// + /// + /// The controller type to add routes for. This type is used to scope the + /// routes to the controller. + /// + /// + /// The base path of all routes on the controller, without the admin directory + /// or any leading or trailing slashes e.g. "auth", "images", "users/roles" + /// + /// Builder context that can be used to add routes. + public AdminRouteBuilderContext ForAdminController(string basePath) + where TController : Controller + { + var adminSettings = routeBuilder.ServiceProvider.GetRequiredService(); + return new AdminRouteBuilderContext(adminSettings, routeBuilder, basePath); + } - /// - /// Returns a builder context than can be used to add admin panel api - /// routes to the specified controller. Routes specified through this method - /// will automatically be registered with the correct admin panel api path, which - /// can be altered via the Cofoundry:Admin:DirectoryName setting. - /// - /// - /// The controller type to add routes for. This type is used to scope the - /// api routes to the controller. - /// - /// The route builder to add routes to. - /// - /// The base path of all routes on the controller, without the admin api directory - /// or any leading or trailing slashes e.g. "auth", "images", "users/roles" - /// - /// Api builder context that can be used to add routes. - public static AdminApiRouteBuilderContext ForAdminApiController(this IEndpointRouteBuilder routeBuilder, string basePath) - where TController : ControllerBase - { - var adminSettings = routeBuilder.ServiceProvider.GetRequiredService(); - return new AdminApiRouteBuilderContext(adminSettings, routeBuilder, basePath); + /// + /// Returns a builder context than can be used to add admin panel api + /// routes to the specified controller. Routes specified through this method + /// will automatically be registered with the correct admin panel api path, which + /// can be altered via the Cofoundry:Admin:DirectoryName setting. + /// + /// + /// The controller type to add routes for. This type is used to scope the + /// api routes to the controller. + /// + /// + /// The base path of all routes on the controller, without the admin api directory + /// or any leading or trailing slashes e.g. "auth", "images", "users/roles" + /// + /// Api builder context that can be used to add routes. + public AdminApiRouteBuilderContext ForAdminApiController(string basePath) + where TController : ControllerBase + { + var adminSettings = routeBuilder.ServiceProvider.GetRequiredService(); + return new AdminApiRouteBuilderContext(adminSettings, routeBuilder, basePath); + } } } diff --git a/src/Cofoundry.Web/App_Start/AddCofoundryStartupExtension.cs b/src/Cofoundry.Web/App_Start/AddCofoundryStartupExtension.cs index a0609ab96..fc6249d19 100644 --- a/src/Cofoundry.Web/App_Start/AddCofoundryStartupExtension.cs +++ b/src/Cofoundry.Web/App_Start/AddCofoundryStartupExtension.cs @@ -8,32 +8,37 @@ namespace Cofoundry.Web; +/// +/// Extension methods for adding Cofoundry via . +/// public static class AddCofoundryStartupExtension { - /// - /// Configures the dependency resolver for Cofoundry and - /// registers all the services, repositories and modules setup for auto-registration. - /// - public static IMvcBuilder AddCofoundry( - this IMvcBuilder mvcBuilder, - IConfiguration configuration, - Action? configBuilder = null - ) + extension(IMvcBuilder mvcBuilder) { - var cofoundryConfig = new AddCofoundryStartupConfiguration(); - configBuilder?.Invoke(cofoundryConfig); - mvcBuilder = EnsureCoreMVCServicesAdded(mvcBuilder); + /// + /// Configures the dependency resolver for Cofoundry and + /// registers all the services, repositories and modules setup for auto-registration. + /// + public IMvcBuilder AddCofoundry( + IConfiguration configuration, + Action? configBuilder = null + ) + { + var cofoundryConfig = new AddCofoundryStartupConfiguration(); + configBuilder?.Invoke(cofoundryConfig); + mvcBuilder = EnsureCoreMVCServicesAdded(mvcBuilder); - AddAdditionalTypes(mvcBuilder); - DiscoverAdditionalApplicationParts(mvcBuilder, cofoundryConfig); + AddAdditionalTypes(mvcBuilder); + DiscoverAdditionalApplicationParts(mvcBuilder, cofoundryConfig); - var typesProvider = new DiscoveredTypesProvider(mvcBuilder.PartManager); - var builder = new DefaultContainerBuilder(mvcBuilder.Services, typesProvider, configuration); - builder.Build(); + var typesProvider = new DiscoveredTypesProvider(mvcBuilder.PartManager); + var builder = new DefaultContainerBuilder(mvcBuilder.Services, typesProvider, configuration); + builder.Build(); - RunAdditionalConfiguration(mvcBuilder); + RunAdditionalConfiguration(mvcBuilder); - return mvcBuilder; + return mvcBuilder; + } } /// diff --git a/src/Cofoundry.Web/App_Start/Hosting/IWebHostBuilderExtensions.cs b/src/Cofoundry.Web/App_Start/Hosting/IWebHostBuilderExtensions.cs index 9138db550..e4f9ab839 100644 --- a/src/Cofoundry.Web/App_Start/Hosting/IWebHostBuilderExtensions.cs +++ b/src/Cofoundry.Web/App_Start/Hosting/IWebHostBuilderExtensions.cs @@ -1,27 +1,33 @@ -using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; namespace Cofoundry.Web; +/// +/// Extension methods for . +/// public static class IWebHostBuilderExtensions { - /// - /// Uses an optional appsettings.local.json configuration file - /// for local developer configuration, only when in the development - /// environment. This local configuration file should not be checked - /// into version control. - /// - public static IWebHostBuilder UseLocalConfigFile(this IWebHostBuilder webHostBuilder) + extension(IWebHostBuilder webHostBuilder) { - webHostBuilder.ConfigureAppConfiguration((hostContext, config) => + /// + /// Uses an optional appsettings.local.json configuration file + /// for local developer configuration, only when in the development + /// environment. This local configuration file should not be checked + /// into version control. + /// + public IWebHostBuilder UseLocalConfigFile() { - if (hostContext.HostingEnvironment.IsDevelopment()) + webHostBuilder.ConfigureAppConfiguration((hostContext, config) => { - config.AddJsonFile("appsettings.local.json", optional: true); - } - }); + if (hostContext.HostingEnvironment.IsDevelopment()) + { + config.AddJsonFile("appsettings.local.json", optional: true); + } + }); - return webHostBuilder; + return webHostBuilder; + } } } diff --git a/src/Cofoundry.Web/App_Start/StartupTasks/ConfigurationTasks/StaticFiles/StaticFileStartupConfigurationTask.cs b/src/Cofoundry.Web/App_Start/StartupTasks/ConfigurationTasks/StaticFiles/StaticFileStartupConfigurationTask.cs index bac1743f2..726cc24be 100644 --- a/src/Cofoundry.Web/App_Start/StartupTasks/ConfigurationTasks/StaticFiles/StaticFileStartupConfigurationTask.cs +++ b/src/Cofoundry.Web/App_Start/StartupTasks/ConfigurationTasks/StaticFiles/StaticFileStartupConfigurationTask.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.StaticFiles; namespace Cofoundry.Web; @@ -47,4 +47,4 @@ private void RegisterStaticFiles(IApplicationBuilder app) app.UseStaticFiles(options); } -} \ No newline at end of file +} diff --git a/src/Cofoundry.Web/App_Start/UseCofoundryStartupExtension.cs b/src/Cofoundry.Web/App_Start/UseCofoundryStartupExtension.cs index ce51cb937..3e93c755c 100644 --- a/src/Cofoundry.Web/App_Start/UseCofoundryStartupExtension.cs +++ b/src/Cofoundry.Web/App_Start/UseCofoundryStartupExtension.cs @@ -3,38 +3,40 @@ namespace Cofoundry.Web; +/// +/// Extension methods for configuring Cofoundry middleware via . +/// public static class UseCofoundryStartupExtension { - /// - /// Registers Cofoundry into the application pipeline and runs all the registered - /// Cofoundry StartupTasks. - /// - /// Application configuration. - /// Additional configuration options. - public static void UseCofoundry( - this IApplicationBuilder application, - Action? configBuilder = null - ) + extension(IApplicationBuilder application) { - var configuration = new UseCofoundryStartupConfiguration(); - configBuilder?.Invoke(configuration); + /// + /// Registers Cofoundry into the application pipeline and runs all the registered + /// Cofoundry StartupTasks. + /// + /// Additional configuration options. + public void UseCofoundry(Action? configBuilder = null) + { + var configuration = new UseCofoundryStartupConfiguration(); + configBuilder?.Invoke(configuration); - using var childContext = application.ApplicationServices.CreateScope(); + using var childContext = application.ApplicationServices.CreateScope(); - var startupTasks = childContext - .ServiceProvider - .GetServices(); + var startupTasks = childContext + .ServiceProvider + .GetServices(); - startupTasks = SortTasksByDependency(startupTasks); + startupTasks = SortTasksByDependency(startupTasks); - if (configuration.StartupTaskFilter != null) - { - startupTasks = configuration.StartupTaskFilter(startupTasks); - } + if (configuration.StartupTaskFilter != null) + { + startupTasks = configuration.StartupTaskFilter(startupTasks); + } - foreach (var startupTask in startupTasks) - { - startupTask.Configure(application); + foreach (var startupTask in startupTasks) + { + startupTask.Configure(application); + } } } diff --git a/src/Cofoundry.Web/Cofoundry.Web.csproj b/src/Cofoundry.Web/Cofoundry.Web.csproj index 38003c52d..3a663f650 100644 --- a/src/Cofoundry.Web/Cofoundry.Web.csproj +++ b/src/Cofoundry.Web/Cofoundry.Web.csproj @@ -11,13 +11,13 @@ - - - - + + + + - + diff --git a/src/Cofoundry.Web/Framework/Extensions/IDomainRepositoryExtensions.cs b/src/Cofoundry.Web/Framework/Extensions/IDomainRepositoryExtensions.cs index 8178a3ccf..7c6ad9483 100644 --- a/src/Cofoundry.Web/Framework/Extensions/IDomainRepositoryExtensions.cs +++ b/src/Cofoundry.Web/Framework/Extensions/IDomainRepositoryExtensions.cs @@ -5,65 +5,59 @@ namespace Cofoundry.Web; +/// +/// Extension methods for . +/// public static class IDomainRepositoryExtensions { - /// - /// Wraps query and command execution with error handling code that pipes validation - /// exceptions and validation query results into model state. Additionally if the - /// model state is invalid prior to execution, then execution will be skipped. - /// If execution is skipped then the default result type value will be returned and - /// should be ignored. - /// - /// - /// Repository instance to extend. - /// - /// The controller instance containing the model state to pipe error to. - public static TRepository WithModelState(this TRepository repository, ControllerBase controller) - where TRepository : IDomainRepository + extension(TRepository repository) where TRepository : IDomainRepository { - ArgumentNullException.ThrowIfNull(controller); + /// + /// Wraps query and command execution with error handling code that pipes validation + /// exceptions and validation query results into model state. Additionally if the + /// model state is invalid prior to execution, then execution will be skipped. + /// If execution is skipped then the default result type value will be returned and + /// should be ignored. + /// + /// The controller instance containing the model state to pipe error to. + public TRepository WithModelState(ControllerBase controller) + { + ArgumentNullException.ThrowIfNull(controller); - var extendedContentRepositry = repository.AsExtendableContentRepository(); - return (TRepository)extendedContentRepositry.WithExecutor(executor => new DomainRepositoryExecutorWithModelState(executor, controller.ModelState, null)); - } + var extendedContentRepositry = repository.AsExtendableContentRepository(); + return (TRepository)extendedContentRepositry.WithExecutor(executor => new DomainRepositoryExecutorWithModelState(executor, controller.ModelState, null)); + } - /// - /// Wraps query and command execution with error handling code that pipes validation - /// exceptions and validation query results into model state. Additionally if the - /// model state is invalid prior to execution, then execution will be skipped. - /// If execution is skipped then the default result type value will be returned and - /// should be ignored. - /// - /// - /// Repository instance to extend. - /// - /// The controller instance containing the model state to pipe error to. - public static TRepository WithModelState(this TRepository repository, Controller controller) - where TRepository : IDomainRepository - { - ArgumentNullException.ThrowIfNull(controller); + /// + /// Wraps query and command execution with error handling code that pipes validation + /// exceptions and validation query results into model state. Additionally if the + /// model state is invalid prior to execution, then execution will be skipped. + /// If execution is skipped then the default result type value will be returned and + /// should be ignored. + /// + /// The controller instance containing the model state to pipe error to. + public TRepository WithModelState(Controller controller) + { + ArgumentNullException.ThrowIfNull(controller); - var extendedContentRepositry = repository.AsExtendableContentRepository(); - return (TRepository)extendedContentRepositry.WithExecutor(executor => new DomainRepositoryExecutorWithModelState(executor, controller.ModelState, controller.ViewData.TemplateInfo)); - } + var extendedContentRepositry = repository.AsExtendableContentRepository(); + return (TRepository)extendedContentRepositry.WithExecutor(executor => new DomainRepositoryExecutorWithModelState(executor, controller.ModelState, controller.ViewData.TemplateInfo)); + } - /// - /// Wraps query and command execution with error handling code that pipes validation - /// exceptions and validation query results into model state. Additionally if the - /// model state is invalid prior to execution, then execution will be skipped. - /// If execution is skipped then the default result type value will be returned and - /// should be ignored. - /// - /// - /// Repository instance to extend. - /// - /// The Razor Pages model instance containing the model state to pipe error to. - public static TRepository WithModelState(this TRepository repository, PageModel pageModel) - where TRepository : IDomainRepository - { - ArgumentNullException.ThrowIfNull(pageModel); + /// + /// Wraps query and command execution with error handling code that pipes validation + /// exceptions and validation query results into model state. Additionally if the + /// model state is invalid prior to execution, then execution will be skipped. + /// If execution is skipped then the default result type value will be returned and + /// should be ignored. + /// + /// The Razor Pages model instance containing the model state to pipe error to. + public TRepository WithModelState(PageModel pageModel) + { + ArgumentNullException.ThrowIfNull(pageModel); - var extendedContentRepositry = repository.AsExtendableContentRepository(); - return (TRepository)extendedContentRepositry.WithExecutor(executor => new DomainRepositoryExecutorWithModelState(executor, pageModel.ModelState, pageModel.ViewData.TemplateInfo)); + var extendedContentRepositry = repository.AsExtendableContentRepository(); + return (TRepository)extendedContentRepositry.WithExecutor(executor => new DomainRepositoryExecutorWithModelState(executor, pageModel.ModelState, pageModel.ViewData.TemplateInfo)); + } } } diff --git a/src/Cofoundry.Web/Framework/Extensions/ITransationScopeExtensions.cs b/src/Cofoundry.Web/Framework/Extensions/ITransationScopeExtensions.cs index 3f4c5e57b..3d816ad4c 100644 --- a/src/Cofoundry.Web/Framework/Extensions/ITransationScopeExtensions.cs +++ b/src/Cofoundry.Web/Framework/Extensions/ITransationScopeExtensions.cs @@ -3,24 +3,27 @@ namespace Cofoundry.Web; +/// +/// Extension methods for . +/// public static class ITransationScopeExtensions { - /// - /// Completes the transaction scope only if the is - /// valid, indicating that no handled or unhandled errors occurred udring execution. - /// - /// - /// Scope instance to complete. - /// - /// - /// The to check for validity, usually accessed via - /// controller.ModelState or similar. - /// - public static async Task CompleteIfValidAsync(this ITransactionScope scope, ModelStateDictionary modelState) + extension(ITransactionScope scope) { - if (modelState.IsValid) + /// + /// Completes the transaction scope only if the is + /// valid, indicating that no handled or unhandled errors occurred udring execution. + /// + /// + /// The to check for validity, usually accessed via + /// controller.ModelState or similar. + /// + public async Task CompleteIfValidAsync(ModelStateDictionary modelState) { - await scope.CompleteAsync(); + if (modelState.IsValid) + { + await scope.CompleteAsync(); + } } } } diff --git a/src/Cofoundry.Web/Framework/Helpers/RedirectUrlHelper.cs b/src/Cofoundry.Web/Framework/Helpers/RedirectUrlHelper.cs index bbc502329..b2d0d7ffc 100644 --- a/src/Cofoundry.Web/Framework/Helpers/RedirectUrlHelper.cs +++ b/src/Cofoundry.Web/Framework/Helpers/RedirectUrlHelper.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; @@ -19,7 +20,7 @@ public class RedirectUrlHelper /// Url to validate. public static bool IsValid(ControllerBase controller, string url) { - return IsValidInternal(controller.Request, controller.Url, url); + return IsValidInternal(controller.Request, url); } /// @@ -31,7 +32,7 @@ public static bool IsValid(ControllerBase controller, string url) /// Url to validate. public static bool IsValid(PageModel pageModel, string url) { - return IsValidInternal(pageModel.Request, pageModel.Url, url); + return IsValidInternal(pageModel.Request, url); } /// @@ -41,7 +42,7 @@ public static bool IsValid(PageModel pageModel, string url) /// Currently executing controller instance to use in validation. public static string? GetAndValidateReturnUrl(ControllerBase controller) { - return GetAndValidateReturnUrlInternal(controller.Request, controller.Url); + return GetAndValidateReturnUrlInternal(controller.Request); } /// @@ -51,22 +52,22 @@ public static bool IsValid(PageModel pageModel, string url) /// Currently executing razor page instance to use in validation. public static string? GetAndValidateReturnUrl(PageModel pageModel) { - return GetAndValidateReturnUrlInternal(pageModel.Request, pageModel.Url); + return GetAndValidateReturnUrlInternal(pageModel.Request); } - private static bool IsValidInternal(HttpRequest request, IUrlHelper urlHelper, string? url) + private static bool IsValidInternal(HttpRequest request, string? url) { var isValid = !string.IsNullOrEmpty(url) - && urlHelper.IsLocalUrl(url) + && RedirectHttpResult.IsLocalUrl(url) && !RelativePathHelper.IsWellFormattedAndEqual(request.Path, url); return isValid; } - private static string? GetAndValidateReturnUrlInternal(HttpRequest request, IUrlHelper urlHelper) + private static string? GetAndValidateReturnUrlInternal(HttpRequest request) { var returnUrl = request.Query["ReturnUrl"].FirstOrDefault(); - return IsValidInternal(request, urlHelper, returnUrl) ? returnUrl : null; + return IsValidInternal(request, returnUrl) ? returnUrl : null; } } diff --git a/src/Cofoundry.Web/Framework/Mvc/ViewHelpers/PageTemplates/PageTemplateHelperExtensions.cs b/src/Cofoundry.Web/Framework/Mvc/ViewHelpers/PageTemplates/PageTemplateHelperExtensions.cs index a9503a5f8..4d87ec0a1 100644 --- a/src/Cofoundry.Web/Framework/Mvc/ViewHelpers/PageTemplates/PageTemplateHelperExtensions.cs +++ b/src/Cofoundry.Web/Framework/Mvc/ViewHelpers/PageTemplates/PageTemplateHelperExtensions.cs @@ -1,23 +1,25 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; namespace Cofoundry.Web; +/// +/// Extension methods for . +/// public static class PageTemplateHelperExtensions { - /// - /// Indictes where to render a region in a custom entity page template. - /// - /// Custom entity display model type. - /// IPageTemplateHelper to extend. - /// The name of the region. This must be unique in a page template. - /// ICustomEntityTemplateRegionTagBuilder to allow for method chaining. - public static ICustomEntityTemplateRegionTagBuilder CustomEntityRegion( - this IPageTemplateHelper> helper, string regionName) - where TModel : ICustomEntityPageDisplayModel + extension(IPageTemplateHelper> helper) where TModel : ICustomEntityPageDisplayModel { - var factory = helper.ViewContext.HttpContext.RequestServices.GetRequiredService(); - var output = factory.Create(helper.ViewContext, helper.Model, regionName); + /// + /// Indictes where to render a region in a custom entity page template. + /// + /// The name of the region. This must be unique in a page template. + /// ICustomEntityTemplateRegionTagBuilder to allow for method chaining. + public ICustomEntityTemplateRegionTagBuilder CustomEntityRegion(string regionName) + { + var factory = helper.ViewContext.HttpContext.RequestServices.GetRequiredService(); + var output = factory.Create(helper.ViewContext, helper.Model, regionName); - return output; + return output; + } } } diff --git a/src/Cofoundry.Web/Framework/WebApi/ApiResponseHelpers/IApiResponseHelperExtensions.cs b/src/Cofoundry.Web/Framework/WebApi/ApiResponseHelpers/IApiResponseHelperExtensions.cs index b99dc5083..dd6624427 100644 --- a/src/Cofoundry.Web/Framework/WebApi/ApiResponseHelpers/IApiResponseHelperExtensions.cs +++ b/src/Cofoundry.Web/Framework/WebApi/ApiResponseHelpers/IApiResponseHelperExtensions.cs @@ -2,18 +2,21 @@ namespace Cofoundry.Web; +/// +/// Extension methods for . +/// public static class IApiResponseHelperExtensions { - /// - /// Formats a command response wrapping it in a SimpleCommandResponse object and setting - /// properties based on the presence of a validation error. - /// - /// - /// to extend. - /// - /// Validation error, if any, to be returned. - public static JsonResult SimpleCommandResponse(this IApiResponseHelper apiResponseHelper, ValidationError validationError) + extension(IApiResponseHelper apiResponseHelper) { - return apiResponseHelper.SimpleCommandResponse([validationError]); + /// + /// Formats a command response wrapping it in a SimpleCommandResponse object and setting + /// properties based on the presence of a validation error. + /// + /// Validation error, if any, to be returned. + public JsonResult SimpleCommandResponse(ValidationError validationError) + { + return apiResponseHelper.SimpleCommandResponse([validationError]); + } } } diff --git a/templates/Cofoundry.Templates/Cofoundry.Templates.Web/Cofoundry.Templates.Web.csproj b/templates/Cofoundry.Templates/Cofoundry.Templates.Web/Cofoundry.Templates.Web.csproj index 3a1b777a3..4a0d3b4e6 100644 --- a/templates/Cofoundry.Templates/Cofoundry.Templates.Web/Cofoundry.Templates.Web.csproj +++ b/templates/Cofoundry.Templates/Cofoundry.Templates.Web/Cofoundry.Templates.Web.csproj @@ -1,6 +1,6 @@ - net8.0 + net10.0 enable enable false diff --git a/test/Cofoundry.Core.Tests/Cofoundry.Core.Tests.csproj b/test/Cofoundry.Core.Tests/Cofoundry.Core.Tests.csproj index 36b88e6f0..34e7ea1cf 100644 --- a/test/Cofoundry.Core.Tests/Cofoundry.Core.Tests.csproj +++ b/test/Cofoundry.Core.Tests/Cofoundry.Core.Tests.csproj @@ -6,13 +6,13 @@ - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/test/Cofoundry.Domain.Tests.Shared/Assertions/DateTimeAssertionsExtensions.cs b/test/Cofoundry.Domain.Tests.Shared/Assertions/DateTimeAssertionsExtensions.cs index 02f50ac85..5fe3de42b 100644 --- a/test/Cofoundry.Domain.Tests.Shared/Assertions/DateTimeAssertionsExtensions.cs +++ b/test/Cofoundry.Domain.Tests.Shared/Assertions/DateTimeAssertionsExtensions.cs @@ -1,24 +1,29 @@ -using FluentAssertions.Primitives; +using FluentAssertions.Primitives; namespace Cofoundry.Domain.Tests.Shared.Assertions; +/// +/// Fluent assertion extensions for . +/// public static class DateTimeAssertionsExtensions { - /// - /// Asserts that the instance is not the - /// default value. - /// - /// - /// A formatted phrase as is supported by System.String.Format(System.String,System.Object[]) - /// explaining why the assertion is needed. If the phrase does not start with the - /// word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in because. - /// - public static AndConstraint NotBeDefault(this DateTimeAssertions parent, string because = "", params object[] becauseArgs) - where TAssertions : DateTimeAssertions + extension(DateTimeAssertions parent) where TAssertions : DateTimeAssertions { - return parent.NotBe(default, because, becauseArgs); + /// + /// Asserts that the instance is not the + /// default value. + /// + /// + /// A formatted phrase as is supported by System.String.Format(System.String,System.Object[]) + /// explaining why the assertion is needed. If the phrase does not start with the + /// word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in because. + /// + public AndConstraint NotBeDefault(string because = "", params object[] becauseArgs) + { + return parent.NotBe(default, because, becauseArgs); + } } } diff --git a/test/Cofoundry.Domain.Tests.Shared/Assertions/HttpResponseMessageAssertions.cs b/test/Cofoundry.Domain.Tests.Shared/Assertions/HttpResponseMessageAssertions.cs index e9bf71c9f..0f8f0d2e7 100644 --- a/test/Cofoundry.Domain.Tests.Shared/Assertions/HttpResponseMessageAssertions.cs +++ b/test/Cofoundry.Domain.Tests.Shared/Assertions/HttpResponseMessageAssertions.cs @@ -1,58 +1,59 @@ -using FluentAssertions.Primitives; +using FluentAssertions.Primitives; namespace Cofoundry.Domain.Tests.Shared.Assertions; public static class HttpResponseMessageAssertionsExtensions { - public static Task> BeDeveloperPageExceptionAsync( - this HttpResponseMessageAssertions messageAssertions, - string because = "", - params object[] becauseArgs - ) + extension(HttpResponseMessageAssertions messageAssertions) { - return messageAssertions.BeDeveloperPageExceptionAsync($"*{typeof(TException).Name}*", because, becauseArgs); - } - - /// - /// Asserts that the response is an error 500 and contains the specified . - /// You can use this to assert that an exception has been thrown, but in the client setup you'll - /// first need to ensure the developer exception page is enabled. Do this during client creation by - /// altering the service collection, calling services.TurnOnDeveloperExceptionPage(). - /// - /// The exception message to check for; supports wildcard matching. - /// - /// A formatted phrase as is supported by System.String.Format(System.String,System.Object[]) - /// explaining why the assertion is needed. If the phrase does not start with the - /// word because, it is prepended automatically. - /// - /// - /// Zero or more objects to format using the placeholders in because. - /// - public static async Task> BeDeveloperPageExceptionAsync( - this HttpResponseMessageAssertions messageAssertions, - string errorMessageWildcardPattern, + public Task> BeDeveloperPageExceptionAsync( string because = "", params object[] becauseArgs ) - { - var success = Execute.Assertion - .BecauseOf(because, becauseArgs) - .Given(() => messageAssertions.Subject.StatusCode) - .ForCondition(s => s == HttpStatusCode.InternalServerError) - .FailWith("Expected {context:response} status to be 500{reason}, but found {0}", messageAssertions.Subject.StatusCode); - - if (success) { - var content = await messageAssertions.Subject.Content.ReadAsStringAsync(); + return messageAssertions.BeDeveloperPageExceptionAsync($"*{typeof(TException).Name}*", because, becauseArgs); + } - Execute.Assertion + /// + /// Asserts that the response is an error 500 and contains the specified . + /// You can use this to assert that an exception has been thrown, but in the client setup you'll + /// first need to ensure the developer exception page is enabled. Do this during client creation by + /// altering the service collection, calling services.TurnOnDeveloperExceptionPage(). + /// + /// The exception message to check for; supports wildcard matching. + /// + /// A formatted phrase as is supported by System.String.Format(System.String,System.Object[]) + /// explaining why the assertion is needed. If the phrase does not start with the + /// word because, it is prepended automatically. + /// + /// + /// Zero or more objects to format using the placeholders in because. + /// + public async Task> BeDeveloperPageExceptionAsync( + string errorMessageWildcardPattern, + string because = "", + params object[] becauseArgs + ) + { + var success = Execute.Assertion .BecauseOf(because, becauseArgs) - .ForCondition(ContainsMatch(content, errorMessageWildcardPattern)) - .FailWith("Expected {context:response} to contain {0}{reason}, but found {1}.", - errorMessageWildcardPattern, content); - } + .Given(() => messageAssertions.Subject.StatusCode) + .ForCondition(s => s == HttpStatusCode.InternalServerError) + .FailWith("Expected {context:response} status to be 500{reason}, but found {0}", messageAssertions.Subject.StatusCode); - return new AndConstraint(messageAssertions); + if (success) + { + var content = await messageAssertions.Subject.Content.ReadAsStringAsync(); + + Execute.Assertion + .BecauseOf(because, becauseArgs) + .ForCondition(ContainsMatch(content, errorMessageWildcardPattern)) + .FailWith("Expected {context:response} to contain {0}{reason}, but found {1}.", + errorMessageWildcardPattern, content); + } + + return new AndConstraint(messageAssertions); + } } private static bool ContainsMatch(string content, string wildcardPattern) diff --git a/test/Cofoundry.Domain.Tests.Shared/Assertions/ThrowsExtensions.cs b/test/Cofoundry.Domain.Tests.Shared/Assertions/ThrowsExtensions.cs index 72a29e70c..112aa004e 100644 --- a/test/Cofoundry.Domain.Tests.Shared/Assertions/ThrowsExtensions.cs +++ b/test/Cofoundry.Domain.Tests.Shared/Assertions/ThrowsExtensions.cs @@ -1,6 +1,6 @@ -using Cofoundry.Core.Validation; -using FluentAssertions.Specialized; using System.ComponentModel.DataAnnotations; +using Cofoundry.Core.Validation; +using FluentAssertions.Specialized; namespace Cofoundry.Domain.Tests.Shared.Assertions; @@ -9,126 +9,119 @@ namespace Cofoundry.Domain.Tests.Shared.Assertions; /// public static class ThrowsExtensions { - /// - /// Asserts that a references all members included in ; no more,no less. - /// - /// The expected type of the exception. - /// The containing the thrown exception. - /// - /// The member (property) names to check for. Each member must - /// be present in the validation exception for the assertion to pass. - /// - /// - /// The modified for continued chaining. - /// - public static ExceptionAssertions WithMemberNames(this ExceptionAssertions parent, params string[] memberNames) - where TException : ValidationException + extension(ExceptionAssertions parent) where TException : ValidationException { - var exception = parent.Which; - var numMatchingMembers = exception - .ValidationResult - .MemberNames - .Where(m => memberNames.Contains(m)) - .Count(); + /// + /// Asserts that a references all members included in ; no more,no less. + /// + /// + /// The member (property) names to check for. Each member must + /// be present in the validation exception for the assertion to pass. + /// + /// + /// The modified for continued chaining. + /// + public ExceptionAssertions WithMemberNames(params string[] memberNames) + { + var exception = parent.Which; + var numMatchingMembers = exception + .ValidationResult + .MemberNames + .Where(m => memberNames.Contains(m)) + .Count(); - var isMatch = numMatchingMembers == memberNames.Length; - var exceptionMemberNames = string.Join(", ", exception.ValidationResult.MemberNames); + var isMatch = numMatchingMembers == memberNames.Length; + var exceptionMemberNames = string.Join(", ", exception.ValidationResult.MemberNames); - Execute.Assertion - .ForCondition(isMatch) - .FailWith("Expected exception with member names {0}{reason}, but found {1}.", string.Join(", ", memberNames), exceptionMemberNames); + Execute.Assertion + .ForCondition(isMatch) + .FailWith("Expected exception with member names {0}{reason}, but found {1}.", string.Join(", ", memberNames), exceptionMemberNames); - return parent; + return parent; + } } - /// - /// Asserts that a references all members included in ; no more,no less. - /// - /// The expected type of the exception. - /// The containing the thrown exception. - /// - /// The member (property) names to check for. Each member must - /// be present in the validation exception for the assertion to pass. - /// - /// - /// The modified for continued chaining. - /// - public static async Task> WithMemberNames(this Task> task, params string[] memberNames) - where TException : ValidationException + extension(Task> task) where TException : ValidationException { - return (await task).WithMemberNames(memberNames); + /// + /// Asserts that a references all members included in ; no more,no less. + /// + /// + /// The member (property) names to check for. Each member must + /// be present in the validation exception for the assertion to pass. + /// + /// + /// The modified for continued chaining. + /// + public async Task> WithMemberNames(params string[] memberNames) + { + return (await task).WithMemberNames(memberNames); + } } - /// - /// Asserts that a references all members included in ; no more,no less. - /// - /// The expected type of the exception. - /// The containing the thrown exception. - /// - /// The member (property) names to check for. Each member must - /// be present in the validation exception for the assertion to pass. - /// - /// - /// The modified for continued chaining. - /// - public static ExceptionAssertions> WithId(this ExceptionAssertions> parent, object id) - where TEntity : class + extension(ExceptionAssertions> parent) where TEntity : class { - var exception = parent.Which; + /// + /// Asserts that a references the expected . + /// + /// The expected entity id contained in the exception. + /// + /// The modified for continued chaining. + /// + public ExceptionAssertions> WithId(object id) + { + var exception = parent.Which; - Execute.Assertion - .ForCondition(id.Equals(exception.Id)) - .FailWith("Expected exception with id {0}{reason}, but found {1}.", id, exception.Id); + Execute.Assertion + .ForCondition(id.Equals(exception.Id)) + .FailWith("Expected exception with id {0}{reason}, but found {1}.", id, exception.Id); - return parent; + return parent; + } } - /// - /// Asserts that a references the expected . - /// - /// The entity type of the . - /// The assertion containing the thrown exception. - /// - /// The expected entity id contained in the exception. - /// - /// - /// The modified assertion for continued chaining. - /// - public static async Task>> WithId(this Task>> task, object id) - where TEntity : class + extension(Task>> task) where TEntity : class { - return (await task).WithId(id); + /// + /// Asserts that a references the expected . + /// + /// The expected entity id contained in the exception. + /// The modified assertion for continued chaining. + public async Task>> WithId(object id) + { + return (await task).WithId(id); + } } - /// - /// Asserts that a has the specified . - /// - /// The expected error code contained in the exception. - /// - /// The modified assertion for continued chaining. - /// - public static ExceptionAssertions WithErrorCode(this ExceptionAssertions parent, string errorCode) - where TException : ValidationErrorException + extension(ExceptionAssertions parent) where TException : ValidationErrorException { - var exception = parent.Which; + /// + /// Asserts that a has the specified . + /// + /// The expected error code contained in the exception. + /// The modified assertion for continued chaining. + public ExceptionAssertions WithErrorCode(string errorCode) + { + var exception = parent.Which; - Execute.Assertion - .ForCondition(errorCode.Equals(exception.ErrorCode)) - .FailWith("Expected exception with ErrorCode {0}{reason}, but found {1}.", errorCode, exception.ErrorCode); + Execute.Assertion + .ForCondition(errorCode.Equals(exception.ErrorCode)) + .FailWith("Expected exception with ErrorCode {0}{reason}, but found {1}.", errorCode, exception.ErrorCode); - return parent; + return parent; + } } - /// - /// Asserts that a has the specified . - /// - /// The expected error code contained in the exception. - /// - /// The modified assertion for continued chaining. - /// - public static async Task> WithErrorCode(this Task> task, string errorCode) - where TException : ValidationErrorException + extension(Task> task) where TException : ValidationErrorException { - return (await task).WithErrorCode(errorCode); + /// + /// Asserts that a has the specified . + /// + /// The expected error code contained in the exception. + /// The modified assertion for continued chaining. + public async Task> WithErrorCode(string errorCode) + { + return (await task).WithErrorCode(errorCode); + } } } diff --git a/test/Cofoundry.Domain.Tests.Shared/Mocks/ServicCollectionExtensions.cs b/test/Cofoundry.Domain.Tests.Shared/Mocks/ServicCollectionExtensions.cs index 547090272..470e26e1c 100644 --- a/test/Cofoundry.Domain.Tests.Shared/Mocks/ServicCollectionExtensions.cs +++ b/test/Cofoundry.Domain.Tests.Shared/Mocks/ServicCollectionExtensions.cs @@ -1,4 +1,4 @@ -using Cofoundry.Domain.CQS; +using Cofoundry.Domain.CQS; namespace Cofoundry.Domain.Tests.Shared.Mocks; @@ -7,77 +7,75 @@ namespace Cofoundry.Domain.Tests.Shared.Mocks; /// public static class ServicCollectionExtensions { - /// - /// Overrides the registered command handler to run a mock handler instead. - /// - /// Command type parameter of the to override e.g. AddPageCommand. - /// to alter. - /// A delegate task to run to in place of the registered command handler. - public static IServiceCollection MockHandler(this IServiceCollection serviceCollection, Action handlerDelegate) - where TCommand : ICommand + extension(IServiceCollection serviceCollection) { - return serviceCollection.AddTransient>(s => new MockCommandHandler(handlerDelegate)); - } + /// + /// Overrides the registered command handler to run a mock handler instead. + /// + /// Command type parameter of the to override e.g. AddPageCommand. + /// A delegate task to run to in place of the registered command handler. + public IServiceCollection MockHandler(Action handlerDelegate) + where TCommand : ICommand + { + return serviceCollection.AddTransient>(s => new MockCommandHandler(handlerDelegate)); + } - /// - /// Overrides the registered command handler to run a mock handler instead. - /// - /// Command type parameter of the to override e.g. AddPageCommand. - /// to alter. - /// A delegate task to run to in place of the registered command handler. - public static IServiceCollection MockHandler(this IServiceCollection serviceCollection, Func asyncHandlerDelegate) - where TCommand : ICommand - { - return serviceCollection.AddTransient>(s => new MockCommandHandler(asyncHandlerDelegate)); - } + /// + /// Overrides the registered command handler to run a mock handler instead. + /// + /// Command type parameter of the to override e.g. AddPageCommand. + /// A delegate task to run to in place of the registered command handler. + public IServiceCollection MockHandler(Func asyncHandlerDelegate) + where TCommand : ICommand + { + return serviceCollection.AddTransient>(s => new MockCommandHandler(asyncHandlerDelegate)); + } - /// - /// Overrides a query handler to return a mock result. - /// - /// Query type parameter of the to override e.g. GetPageDetailsByIdQuery. - /// Query result parameter of the to override e.g. PageDetails. - /// to alter. - /// The result to return from the mock handler. - public static IServiceCollection MockHandler(this IServiceCollection serviceCollection, TResult result) - where TQuery : IQuery - { - return serviceCollection.AddTransient>(s => new MockQueryHandler(result)); - } + /// + /// Overrides a query handler to return a mock result. + /// + /// Query type parameter of the to override e.g. GetPageDetailsByIdQuery. + /// Query result parameter of the to override e.g. PageDetails. + /// The result to return from the mock handler. + public IServiceCollection MockHandler(TResult result) + where TQuery : IQuery + { + return serviceCollection.AddTransient>(s => new MockQueryHandler(result)); + } - /// - /// Overrides a query handler to return a mock result, determined by executing the - /// . - /// - /// Query type parameter of the to override e.g. GetPageDetailsByIdQuery. - /// Query result parameter of the to override e.g. PageDetails. - /// to alter. - /// A delegate task to run to determine the result of the query handler. - public static IServiceCollection MockHandler(this IServiceCollection serviceCollection, Func queryDelegate) - where TQuery : IQuery - { - return serviceCollection.AddTransient>(s => new MockQueryHandler(queryDelegate)); - } + /// + /// Overrides a query handler to return a mock result, determined by executing the + /// . + /// + /// Query type parameter of the to override e.g. GetPageDetailsByIdQuery. + /// Query result parameter of the to override e.g. PageDetails. + /// A delegate task to run to determine the result of the query handler. + public IServiceCollection MockHandler(Func queryDelegate) + where TQuery : IQuery + { + return serviceCollection.AddTransient>(s => new MockQueryHandler(queryDelegate)); + } - /// - /// Overrides a query handler to return a mock result, determined by executing the - /// . - /// - /// Query type parameter of the to override e.g. GetPageDetailsByIdQuery. - /// Query result parameter of the to override e.g. PageDetails. - /// to alter. - /// A delegate task to run to determine the result of the query handler. - public static IServiceCollection MockHandler(this IServiceCollection serviceCollection, Func> asyncQueryDelegate) - where TQuery : IQuery - { - return serviceCollection.AddTransient>(s => new MockQueryHandler(asyncQueryDelegate)); - } + /// + /// Overrides a query handler to return a mock result, determined by executing the + /// . + /// + /// Query type parameter of the to override e.g. GetPageDetailsByIdQuery. + /// Query result parameter of the to override e.g. PageDetails. + /// A delegate task to run to determine the result of the query handler. + public IServiceCollection MockHandler(Func> asyncQueryDelegate) + where TQuery : IQuery + { + return serviceCollection.AddTransient>(s => new MockQueryHandler(asyncQueryDelegate)); + } - /// - /// Turns on the developer exception page so that you can check - /// the details of the exception thrown. - /// - public static IServiceCollection TurnOnDeveloperExceptionPage(this IServiceCollection serviceCollection) - { - return serviceCollection.Configure(c => c.DeveloperExceptionPageMode = DeveloperExceptionPageMode.On); + /// + /// Turns on the developer exception page so that you can check + /// the details of the exception thrown. + /// + public IServiceCollection TurnOnDeveloperExceptionPage() + { + return serviceCollection.Configure(c => c.DeveloperExceptionPageMode = DeveloperExceptionPageMode.On); + } } } diff --git a/test/Cofoundry.Domain.Tests/Cofoundry.Domain.Tests.csproj b/test/Cofoundry.Domain.Tests/Cofoundry.Domain.Tests.csproj index 6e2720726..5acd69196 100644 --- a/test/Cofoundry.Domain.Tests/Cofoundry.Domain.Tests.csproj +++ b/test/Cofoundry.Domain.Tests/Cofoundry.Domain.Tests.csproj @@ -6,10 +6,10 @@ - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -17,7 +17,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/test/Cofoundry.Plugins.Tests/Cofoundry.Plugins.Azure.Tests/Cofoundry.Plugins.Azure.Tests.csproj b/test/Cofoundry.Plugins.Tests/Cofoundry.Plugins.Azure.Tests/Cofoundry.Plugins.Azure.Tests.csproj index e1f84ec72..caf79fc61 100644 --- a/test/Cofoundry.Plugins.Tests/Cofoundry.Plugins.Azure.Tests/Cofoundry.Plugins.Azure.Tests.csproj +++ b/test/Cofoundry.Plugins.Tests/Cofoundry.Plugins.Azure.Tests/Cofoundry.Plugins.Azure.Tests.csproj @@ -5,9 +5,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -15,7 +15,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/test/Cofoundry.Plugins.Tests/Cofoundry.Plugins.Imaging.SkiaSharp.Tests/Cofoundry.Plugins.Imaging.SkiaSharp.Tests.csproj b/test/Cofoundry.Plugins.Tests/Cofoundry.Plugins.Imaging.SkiaSharp.Tests/Cofoundry.Plugins.Imaging.SkiaSharp.Tests.csproj index 2828397e3..d356302f7 100644 --- a/test/Cofoundry.Plugins.Tests/Cofoundry.Plugins.Imaging.SkiaSharp.Tests/Cofoundry.Plugins.Imaging.SkiaSharp.Tests.csproj +++ b/test/Cofoundry.Plugins.Tests/Cofoundry.Plugins.Imaging.SkiaSharp.Tests/Cofoundry.Plugins.Imaging.SkiaSharp.Tests.csproj @@ -1,11 +1,7 @@ - net8.0 - enable - enable Exe - false @@ -19,8 +15,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -28,7 +24,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/test/Cofoundry.Web.Admin.Tests/Cofoundry.Web.Admin.Tests.csproj b/test/Cofoundry.Web.Admin.Tests/Cofoundry.Web.Admin.Tests.csproj index 868a8f83d..bca272399 100644 --- a/test/Cofoundry.Web.Admin.Tests/Cofoundry.Web.Admin.Tests.csproj +++ b/test/Cofoundry.Web.Admin.Tests/Cofoundry.Web.Admin.Tests.csproj @@ -10,8 +10,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -19,7 +19,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/test/Cofoundry.Web.Tests/Cofoundry.Web.Tests.csproj b/test/Cofoundry.Web.Tests/Cofoundry.Web.Tests.csproj index 852136dc5..f5882455d 100644 --- a/test/Cofoundry.Web.Tests/Cofoundry.Web.Tests.csproj +++ b/test/Cofoundry.Web.Tests/Cofoundry.Web.Tests.csproj @@ -6,10 +6,10 @@ - - + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -17,7 +17,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/test/Cofoundry.Web.Tests/Shared/Fixtures/WebApplicationFactoryExtensions.cs b/test/Cofoundry.Web.Tests/Shared/Fixtures/WebApplicationFactoryExtensions.cs index 7c9c9cbb2..3fbfa97a7 100644 --- a/test/Cofoundry.Web.Tests/Shared/Fixtures/WebApplicationFactoryExtensions.cs +++ b/test/Cofoundry.Web.Tests/Shared/Fixtures/WebApplicationFactoryExtensions.cs @@ -5,82 +5,81 @@ namespace Cofoundry.Web.Tests; /// -/// Extensions to cut down on boilerplate when working with +/// Extensions to cut down on boilerplate when working with /// public static class WebApplicationFactoryExtensions { - /// - /// Creates a new configured to override - /// services using the specific delegate. - /// This is a shortcut to running - /// factory.WithWebHostBuilder(b => b.ConfigureTestServices(serviceConfiguration)). - /// - /// Service configuration delegate to run after all other services have been resgistered. - /// A new with the altered configuration. - public static WebApplicationFactory WithServices(this WebApplicationFactory factory, Action serviceConfiguration) - where TEntryPoint : class + extension(WebApplicationFactory factory) where TEntryPoint : class { - return factory.WithWebHostBuilder(b => b.ConfigureTestServices(serviceConfiguration)); - } - - /// - /// Creates a new HttpClient instance for the test application, having - /// configured it with the specified service overrides. - /// - /// Service configuration delegate to run after all other services have been resgistered. - public static HttpClient CreateClientWithServices(this WebApplicationFactory factory, Action serviceConfiguration) - where TEntryPoint : class - { - return factory.WithServices(serviceConfiguration).CreateClient(); - } + /// + /// Creates a new configured to override + /// services using the specific delegate. + /// This is a shortcut to running + /// factory.WithWebHostBuilder(b => b.ConfigureTestServices(serviceConfiguration)). + /// + /// Service configuration delegate to run after all other services have been resgistered. + /// A new with the altered configuration. + public WebApplicationFactory WithServices(Action serviceConfiguration) + { + return factory.WithWebHostBuilder(b => b.ConfigureTestServices(serviceConfiguration)); + } - /// - /// Shortcut to creating a new client with configurable options. The default options - /// allow for redirects and handle cookies. - /// - /// - /// Option configuration for a new instance of . - /// The default options allow for redirects and handle cookies. - /// - public static HttpClient CreateClient(this WebApplicationFactory factory, Action? configureClientOptions) - where TEntryPoint : class - { - var options = new WebApplicationFactoryClientOptions(); - configureClientOptions?.Invoke(options); + /// + /// Creates a new HttpClient instance for the test application, having + /// configured it with the specified service overrides. + /// + /// Service configuration delegate to run after all other services have been resgistered. + public HttpClient CreateClientWithServices(Action serviceConfiguration) + { + return factory.WithServices(serviceConfiguration).CreateClient(); + } - return factory.CreateClient(options); - } + /// + /// Shortcut to creating a new client with configurable options. The default options + /// allow for redirects and handle cookies. + /// + /// + /// Option configuration for a new instance of . + /// The default options allow for redirects and handle cookies. + /// + public HttpClient CreateClient(Action? configureClientOptions) + { + var options = new WebApplicationFactoryClientOptions(); + configureClientOptions?.Invoke(options); - /// - /// - /// Creates a new instance - /// which can be used to create and work with test entities directly - /// through the domain layer with the same API used in the domain - /// integration tests project. - /// - /// - /// Note that although the test app and client instances share the same base - /// service configuration, they don't seem to share the service collection and - /// therefore the same singleton instances, so be aware that features like in-memory - /// caching are not shared. To get around this, the caching services in the client - /// app will be reset when a new client is created. - /// - /// - /// The application should be disposed of when you are done with it. - /// - /// - public static IntegrationTestApplication CreateApp(this WebApplicationFactory factory) - where TEntryPoint : class - { - var seededEntities = factory.Services.GetRequiredService(); + return factory.CreateClient(options); + } - var factoryWithAppDependencies = factory.WithServices(services => + /// + /// + /// Creates a new instance + /// which can be used to create and work with test entities directly + /// through the domain layer with the same API used in the domain + /// integration tests project. + /// + /// + /// Note that although the test app and client instances share the same base + /// service configuration, they don't seem to share the service collection and + /// therefore the same singleton instances, so be aware that features like in-memory + /// caching are not shared. To get around this, the caching services in the client + /// app will be reset when a new client is created. + /// + /// + /// The application should be disposed of when you are done with it. + /// + /// + public IntegrationTestApplication CreateApp() { - IntegrationTestApplicationServiceProviderFactory.ConfigureTestServices(services); - }); + var seededEntities = factory.Services.GetRequiredService(); + + var factoryWithAppDependencies = factory.WithServices(services => + { + IntegrationTestApplicationServiceProviderFactory.ConfigureTestServices(services); + }); - var app = new IntegrationTestApplication(factoryWithAppDependencies.Services, seededEntities); + var app = new IntegrationTestApplication(factoryWithAppDependencies.Services, seededEntities); - return app; + return app; + } } } diff --git a/test/Cofoundry.Web.Tests/Shared/TestWebApp/HttpClientExtensions.cs b/test/Cofoundry.Web.Tests/Shared/TestWebApp/HttpClientExtensions.cs index 5feb0f07e..db1e10954 100644 --- a/test/Cofoundry.Web.Tests/Shared/TestWebApp/HttpClientExtensions.cs +++ b/test/Cofoundry.Web.Tests/Shared/TestWebApp/HttpClientExtensions.cs @@ -4,28 +4,31 @@ namespace Cofoundry.Web.Tests.TestWebApp; public static class HttpClientExtensions { - /// - /// Sends a sign in request to impersonate the specified user on the test - /// server environment. - /// - /// - /// User to impersonate. The user can be associated with any user area. - /// - public static Task ImpersonateUserAsync(this HttpClient httpClient, TestUserInfo userInfo) + extension(HttpClient httpClient) { - return ImpersonateUserAsync(httpClient, userInfo.UserId); - } + /// + /// Sends a sign in request to impersonate the specified user on the test + /// server environment. + /// + /// + /// User to impersonate. The user can be associated with any user area. + /// + public Task ImpersonateUserAsync(TestUserInfo userInfo) + { + return ImpersonateUserAsync(httpClient, userInfo.UserId); + } - /// - /// Sends a sign in request to impersonate the specified user on the test - /// server environment. - /// - /// - /// UserId of the user to impersonate. The user can be associated with - /// any user area. - /// - public static Task ImpersonateUserAsync(this HttpClient httpClient, int userId) - { - return httpClient.PostAsync($"/tests/users/impersonate/{userId}", null); + /// + /// Sends a sign in request to impersonate the specified user on the test + /// server environment. + /// + /// + /// UserId of the user to impersonate. The user can be associated with + /// any user area. + /// + public Task ImpersonateUserAsync(int userId) + { + return httpClient.PostAsync($"/tests/users/impersonate/{userId}", null); + } } }