From 367bca6a66ef6fbb823c491cdf85c3f0a411d959 Mon Sep 17 00:00:00 2001 From: jtkech Date: Sun, 14 Jul 2019 05:42:56 +0200 Subject: [PATCH 01/38] More async calls --- .../Views/Account/ChangePassword.cshtml | 2 +- .../Account/ChangePasswordConfirmation.cshtml | 2 +- .../Views/Account/ExternalLogin.cshtml | 2 +- .../Views/Account/ExternalLogins.cshtml | 2 +- .../Views/Account/Login.cshtml | 2 +- .../Views/Registration/ConfirmEmail.cshtml | 2 +- .../Views/Registration/Register.cshtml | 2 +- .../Views/ResetPassword/ForgotPassword.cshtml | 2 +- .../ForgotPasswordConfirmation.cshtml | 2 +- .../Views/ResetPassword/ResetPassword.cshtml | 2 +- .../ResetPasswordConfirmation.cshtml | 2 +- .../LiquidViewTemplate.cs | 14 +++- .../IViewResultFilter.cs | 10 +++ .../Layout/LayoutAccessor.cs | 3 +- .../OrchardCoreBuilderExtensions.cs | 6 +- .../Razor/IRazorViewExtensionProvider.cs | 4 +- .../Razor/RazorPage.cs | 24 +----- .../Razor/RazorShapeTemplateViewEngine.cs | 31 ++++++-- .../Razor/SiteViewResultFilter.cs | 25 +++++-- .../Razor/ThemeLayoutViewResultFilter.cs | 41 ++++++++++ .../RazorPages/Page.cs | 75 +++++++++++++++---- 21 files changed, 186 insertions(+), 69 deletions(-) create mode 100644 src/OrchardCore/OrchardCore.DisplayManagement/IViewResultFilter.cs create mode 100644 src/OrchardCore/OrchardCore.DisplayManagement/Razor/ThemeLayoutViewResultFilter.cs diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/ChangePassword.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/ChangePassword.cshtml index d8fcc413c98..f14548b6ece 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/ChangePassword.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/ChangePassword.cshtml @@ -1,7 +1,7 @@ @model OrchardCore.Users.ViewModels.ChangePasswordViewModel @{ - ThemeLayout.Metadata.Alternates.Add("Layout__Login"); + ViewLayout = "Layout__Login"; }
diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/ChangePasswordConfirmation.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/ChangePasswordConfirmation.cshtml index d4e30fb973a..d010a3bd8e9 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/ChangePasswordConfirmation.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/ChangePasswordConfirmation.cshtml @@ -1,5 +1,5 @@ @{ - ThemeLayout.Metadata.Alternates.Add("Layout__Login"); + ViewLayout = "Layout__Login"; }

@T["Change Password"]

diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/ExternalLogin.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/ExternalLogin.cshtml index 7f9ea3a3a1f..af29be988c5 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/ExternalLogin.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/ExternalLogin.cshtml @@ -1,7 +1,7 @@ @model OrchardCore.Users.ViewModels.ExternalLoginViewModel @{ - ThemeLayout.Metadata.Alternates.Add("Layout__Login"); + ViewLayout = "Layout__Login"; } diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/ExternalLogins.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/ExternalLogins.cshtml index 9a93a2c4d27..bdd5ea79287 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/ExternalLogins.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/ExternalLogins.cshtml @@ -1,6 +1,6 @@ @model ExternalLoginsViewModel @{ - ThemeLayout.Metadata.Alternates.Add("Layout__Login"); + ViewLayout = "Layout__Login"; ViewData["Title"] = "Manage your external logins"; //ViewData.AddActivePage(ManageNavPages.ExternalLogins); diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/Login.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/Login.cshtml index 879091c0320..21e78a93b48 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/Login.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/Account/Login.cshtml @@ -8,7 +8,7 @@ @inject ISiteService _site @{ - ThemeLayout.Metadata.Alternates.Add("Layout__Login"); + ViewLayout = "Layout__Login"; var userCanRegister = (await _site.GetSiteSettingsAsync()).As().UsersCanRegister; var allowResetPassword = (await _site.GetSiteSettingsAsync()).As().AllowResetPassword; diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/Registration/ConfirmEmail.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/Registration/ConfirmEmail.cshtml index 4f353a6199c..036299ccc5f 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/Registration/ConfirmEmail.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/Registration/ConfirmEmail.cshtml @@ -1,5 +1,5 @@ @{ - ThemeLayout.Metadata.Alternates.Add("Layout__Login"); + ViewLayout = "Layout__Login"; }

@T["Email confirmation"]

diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/Registration/Register.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/Registration/Register.cshtml index 4cca68fe6fb..3710e24a568 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/Registration/Register.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/Registration/Register.cshtml @@ -1,7 +1,7 @@ @model OrchardCore.Users.ViewModels.RegisterViewModel @{ - ThemeLayout.Metadata.Alternates.Add("Layout__Login"); + ViewLayout = "Layout__Login"; }

@T["Register"]

diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/ResetPassword/ForgotPassword.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/ResetPassword/ForgotPassword.cshtml index d9fabf82d41..18bd4895b8b 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/ResetPassword/ForgotPassword.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/ResetPassword/ForgotPassword.cshtml @@ -1,7 +1,7 @@ @model OrchardCore.Users.ViewModels.ForgotPasswordViewModel @{ - ThemeLayout.Metadata.Alternates.Add("Layout__Login"); + ViewLayout = "Layout__Login"; }

@T["Forgot password?"]

diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/ResetPassword/ForgotPasswordConfirmation.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/ResetPassword/ForgotPasswordConfirmation.cshtml index f98a9be4b18..d208b027b36 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/ResetPassword/ForgotPasswordConfirmation.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/ResetPassword/ForgotPasswordConfirmation.cshtml @@ -1,5 +1,5 @@ @{ - ThemeLayout.Metadata.Alternates.Add("Layout__Login"); + ViewLayout = "Layout__Login"; }

@T["Forgot Password confirmation"]

diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/ResetPassword/ResetPassword.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/ResetPassword/ResetPassword.cshtml index 290d2fa15ec..03b2d555a05 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/ResetPassword/ResetPassword.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/ResetPassword/ResetPassword.cshtml @@ -1,7 +1,7 @@ @model OrchardCore.Users.ViewModels.ResetPasswordViewModel @{ - ThemeLayout.Metadata.Alternates.Add("Layout__Login"); + ViewLayout = "Layout__Login"; } diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Views/ResetPassword/ResetPasswordConfirmation.cshtml b/src/OrchardCore.Modules/OrchardCore.Users/Views/ResetPassword/ResetPasswordConfirmation.cshtml index 0ac0d611190..881e31ae5ec 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Views/ResetPassword/ResetPasswordConfirmation.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Users/Views/ResetPassword/ResetPasswordConfirmation.cshtml @@ -1,5 +1,5 @@ @{ - ThemeLayout.Metadata.Alternates.Add("Layout__Login"); + ViewLayout = "Layout__Login"; }

@T["Reset Password"]

diff --git a/src/OrchardCore/OrchardCore.DisplayManagement.Liquid/LiquidViewTemplate.cs b/src/OrchardCore/OrchardCore.DisplayManagement.Liquid/LiquidViewTemplate.cs index 2478d70bc5c..c4a044f0fc6 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement.Liquid/LiquidViewTemplate.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement.Liquid/LiquidViewTemplate.cs @@ -251,7 +251,7 @@ public static async Task ContextualizeAsync(this TemplateContext context, Displa if (viewContext == null) { - var actionContext = GetActionContext(services); + var actionContext = await GetActionContextAsync(services); viewContext = GetViewContext(services, actionContext); // If there was no 'ViewContext' but a 'DisplayContext'. @@ -303,7 +303,7 @@ public static async Task ContextualizeAsync(this TemplateContext context, Displa context.CultureInfo = CultureInfo.CurrentUICulture; } - private static ActionContext GetActionContext(IServiceProvider services) + private async static Task GetActionContextAsync(IServiceProvider services) { var actionContext = services.GetService()?.ActionContext; @@ -320,7 +320,15 @@ private static ActionContext GetActionContext(IServiceProvider services) var pipeline = shellContext?.Pipeline as ShellRequestPipeline; routeData.Routers.Add(pipeline?.Router ?? new RouteCollection()); - return new ActionContext(httpContext, routeData, new ActionDescriptor()); + actionContext = new ActionContext(httpContext, routeData, new ActionDescriptor()); + var filters = httpContext.RequestServices.GetServices(); + + foreach (var filter in filters) + { + await filter.OnResultExecutionAsync(actionContext); + } + + return actionContext; } private static ViewContext GetViewContext(IServiceProvider services, ActionContext actionContext) diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/IViewResultFilter.cs b/src/OrchardCore/OrchardCore.DisplayManagement/IViewResultFilter.cs new file mode 100644 index 00000000000..ff6cedca9ab --- /dev/null +++ b/src/OrchardCore/OrchardCore.DisplayManagement/IViewResultFilter.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace OrchardCore.DisplayManagement +{ + public interface IViewResultFilter + { + Task OnResultExecutionAsync(ActionContext context); + } +} diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Layout/LayoutAccessor.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Layout/LayoutAccessor.cs index 74cd054d693..7195c61e15c 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Layout/LayoutAccessor.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Layout/LayoutAccessor.cs @@ -1,4 +1,3 @@ - using System.Threading.Tasks; namespace OrchardCore.DisplayManagement.Layout @@ -15,7 +14,7 @@ public LayoutAccessor(IShapeFactory shapeFactory) public async Task GetLayoutAsync() { - if(_layout == null) + if (_layout == null) { _layout = await _shapeFactory.CreateAsync("Layout", Arguments.Empty); } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs b/src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs index 1f7ad72e654..009c09c3a71 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs @@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Mvc.ApplicationParts; using Microsoft.AspNetCore.Mvc.Razor.Compilation; using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Localization; using Microsoft.Extensions.Options; using OrchardCore.DisplayManagement; using OrchardCore.DisplayManagement.Descriptors; @@ -43,8 +42,13 @@ public static OrchardCoreBuilder AddTheming(this OrchardCoreBuilder builder) options.Filters.Add(typeof(ModelBinderAccessorFilter)); options.Filters.Add(typeof(NotifyFilter)); options.Filters.Add(typeof(SiteViewResultFilter)); + options.Filters.Add(typeof(ThemeLayoutViewResultFilter)); }); + // Used as services when we create fake view and action contexts. + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); services.AddScoped(); diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/IRazorViewExtensionProvider.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/IRazorViewExtensionProvider.cs index c3e4278f091..ee9c4c62417 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/IRazorViewExtensionProvider.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/IRazorViewExtensionProvider.cs @@ -1,7 +1,7 @@ -namespace OrchardCore.DisplayManagement.Razor +namespace OrchardCore.DisplayManagement.Razor { public interface IRazorViewExtensionProvider { string ViewExtension { get; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorPage.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorPage.cs index 3ba1313d30e..47354629d85 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorPage.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorPage.cs @@ -6,7 +6,6 @@ using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.Extensions.DependencyInjection; -using OrchardCore.DisplayManagement.Layout; using OrchardCore.DisplayManagement.Shapes; using OrchardCore.DisplayManagement.Title; using OrchardCore.Settings; @@ -114,14 +113,7 @@ public dynamic ThemeLayout { if (_themeLayout == null) { - var layoutAccessor = Context.RequestServices.GetService(); - - if (layoutAccessor == null) - { - throw new InvalidOperationException("Could not find a valid layout accessor"); - } - - _themeLayout = layoutAccessor.GetLayoutAsync().GetAwaiter().GetResult(); + _themeLayout = Context.Items[typeof(IShape)]; } return _themeLayout; @@ -228,7 +220,7 @@ public IHtmlContent RenderTitleSegments(string segment, string position = "0", I { Title.AddSegment(new HtmlString(HtmlEncoder.Encode(segment)), position); } - + return Title.GenerateTitle(separator); } @@ -256,7 +248,6 @@ public TagBuilder Tag(dynamic shape, string tag) return Shape.GetTagBuilder(shape, tag); } - // /// In a Razor layout page, renders the portion of a content page that is not within a named zone. /// @@ -364,17 +355,6 @@ public ISite Site if (_site == null) { _site = (ISite)Context.Items[typeof(ISite)]; - - if (_site == null) - { - var siteService = Context.RequestServices.GetService(); - - if (siteService != null) - { - _site = siteService.GetSiteSettingsAsync().GetAwaiter().GetResult(); - Context.Items.Add(typeof(ISite), _site); - } - } } return _site; diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorShapeTemplateViewEngine.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorShapeTemplateViewEngine.cs index 9c415be4049..ac62ef3bdfc 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorShapeTemplateViewEngine.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorShapeTemplateViewEngine.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.Rendering; @@ -24,20 +25,20 @@ namespace OrchardCore.DisplayManagement.Razor { public class RazorShapeTemplateViewEngine : IShapeTemplateViewEngine { - private readonly IOptions _options; + private readonly IOptions _mvcViewOptions; private readonly IHttpContextAccessor _httpContextAccessor; private readonly ViewContextAccessor _viewContextAccessor; private readonly ITempDataProvider _tempDataProvider; private readonly List _templateFileExtensions = new List(new[] { RazorViewEngine.ViewExtension }); public RazorShapeTemplateViewEngine( - IOptions options, + IOptions mvcViewOptions, IEnumerable viewExtensionProviders, IHttpContextAccessor httpContextAccessor, ViewContextAccessor viewContextAccessor, ITempDataProvider tempDataProvider) { - _options = options; + _mvcViewOptions = mvcViewOptions; _httpContextAccessor = httpContextAccessor; _viewContextAccessor = viewContextAccessor; _tempDataProvider = tempDataProvider; @@ -75,7 +76,7 @@ public Task RenderAsync(string relativePath, DisplayContext displa private async Task RenderRazorViewAsync(string viewName, DisplayContext displayContext) { - var viewEngines = _options.Value.ViewEngines; + var viewEngines = _mvcViewOptions.Value.ViewEngines; if (viewEngines.Count == 0) { @@ -94,7 +95,7 @@ private async Task RenderRazorViewAsync(string viewName, DisplayCo public async Task RenderViewToStringAsync(string viewName, object model, IRazorViewEngine viewEngine) { - var actionContext = GetActionContext(); + var actionContext = await GetActionContextAsync(); var view = FindView(actionContext, viewName, viewEngine); using (var output = new StringWriter()) @@ -142,16 +143,32 @@ private IView FindView(ActionContext actionContext, string viewName, IRazorViewE throw new InvalidOperationException(errorMessage); } - private ActionContext GetActionContext() + private async Task GetActionContextAsync() { var httpContext = _httpContextAccessor.HttpContext; + + var actionContext = httpContext.RequestServices.GetService()?.ActionContext; + + if (actionContext != null) + { + return actionContext; + } + var shellContext = httpContext.Features.Get()?.ShellContext; var routeData = new RouteData(); var pipeline = shellContext?.Pipeline as ShellRequestPipeline; routeData.Routers.Add(pipeline?.Router ?? new RouteCollection()); - return new ActionContext(httpContext, routeData, new ActionDescriptor()); + actionContext = new ActionContext(httpContext, routeData, new ActionDescriptor()); + var filters = httpContext.RequestServices.GetServices(); + + foreach (var filter in filters) + { + await filter.OnResultExecutionAsync(actionContext); + } + + return actionContext; } private static IHtmlHelper MakeHtmlHelper(ViewContext viewContext, ViewDataDictionary viewData) diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs index 5027538d50a..35a7278e3d5 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs @@ -1,4 +1,6 @@ using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.DependencyInjection; using OrchardCore.Settings; @@ -8,24 +10,33 @@ namespace OrchardCore.DisplayManagement.Razor /// /// Inject an instance of in the HttpContext items such that /// a View can reuse it when it's executed. - /// TODO: This should be removed once https://github.com/aspnet/Mvc/issues/8241 is implemented /// - public class SiteViewResultFilter : IAsyncResultFilter + public class SiteViewResultFilter : IAsyncResultFilter, IViewResultFilter { public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) { - if (!context.HttpContext.Items.ContainsKey(typeof(ISite))) + await OnResultExecutionAsync(context.HttpContext); + await next(); + } + + // Used when we create fake view and action contexts. + public Task OnResultExecutionAsync(ActionContext context) + { + return OnResultExecutionAsync(context.HttpContext); + } + + private async Task OnResultExecutionAsync(HttpContext context) + { + if (!context.Items.ContainsKey(typeof(ISite))) { - var siteService = context.HttpContext.RequestServices.GetService(); + var siteService = context.RequestServices.GetService(); // siteService can be null during Setup if (siteService != null) { - context.HttpContext.Items.Add(typeof(ISite), await siteService.GetSiteSettingsAsync()); + context.Items.Add(typeof(ISite), await siteService.GetSiteSettingsAsync()); } } - - await next(); } } } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/ThemeLayoutViewResultFilter.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/ThemeLayoutViewResultFilter.cs new file mode 100644 index 00000000000..59808e5b644 --- /dev/null +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/ThemeLayoutViewResultFilter.cs @@ -0,0 +1,41 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.DependencyInjection; +using OrchardCore.DisplayManagement.Layout; + +namespace OrchardCore.DisplayManagement.Razor +{ + /// + /// Inject an instance of the theme layout in the HttpContext items such that + /// a View can reuse it when it's executed. + /// + public class ThemeLayoutViewResultFilter : IAsyncResultFilter, IViewResultFilter + { + public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) + { + await OnResultExecutionAsync(context.HttpContext); + await next(); + } + + // Used when we create fake view and action contexts. + public Task OnResultExecutionAsync(ActionContext context) + { + return OnResultExecutionAsync(context.HttpContext); + } + + private async Task OnResultExecutionAsync(HttpContext context) + { + if (!context.Items.ContainsKey(typeof(IShape))) + { + var layoutAccessor = context.RequestServices.GetService(); + + if (layoutAccessor != null) + { + context.Items.Add(typeof(IShape), await layoutAccessor.GetLayoutAsync()); + } + } + } + } +} diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/RazorPages/Page.cs b/src/OrchardCore/OrchardCore.DisplayManagement/RazorPages/Page.cs index beeef955d7e..5fa182f1bc4 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/RazorPages/Page.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/RazorPages/Page.cs @@ -1,14 +1,15 @@ using System; +using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Mvc.Localization; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.Extensions.DependencyInjection; -using OrchardCore.DisplayManagement.Layout; using OrchardCore.DisplayManagement.Razor; using OrchardCore.DisplayManagement.Shapes; using OrchardCore.DisplayManagement.Title; +using OrchardCore.Settings; namespace OrchardCore.DisplayManagement.RazorPages { @@ -17,6 +18,7 @@ public abstract class Page : Microsoft.AspNetCore.Mvc.RazorPages.Page private dynamic _displayHelper; private IShapeFactory _shapeFactory; private IOrchardDisplayHelper _orchardHelper; + private ISite _site; public override ViewContext ViewContext { @@ -86,6 +88,20 @@ public Task DisplayAsync(dynamic shape) return (Task)_displayHelper(shape); } + public IOrchardDisplayHelper Orchard + { + get + { + if (_orchardHelper == null) + { + EnsureDisplayHelper(); + _orchardHelper = new OrchardDisplayHelper(HttpContext, _displayHelper); + } + + return _orchardHelper; + } + } + private dynamic _themeLayout; public dynamic ThemeLayout { @@ -93,14 +109,7 @@ public dynamic ThemeLayout { if (_themeLayout == null) { - var layoutAccessor = HttpContext.RequestServices.GetService(); - - if (layoutAccessor == null) - { - throw new InvalidOperationException("Could not find a valid layout accessor"); - } - - _themeLayout = layoutAccessor.GetLayoutAsync().GetAwaiter().GetResult(); + _themeLayout = HttpContext.Items[typeof(IShape)]; } return _themeLayout; @@ -112,17 +121,39 @@ public dynamic ThemeLayout } } - public IOrchardDisplayHelper Orchard + public string ViewLayout { get { - if (_orchardHelper == null) + if (ThemeLayout is IShape layout) { - EnsureDisplayHelper(); - _orchardHelper = new OrchardDisplayHelper(HttpContext, _displayHelper); + if (layout.Metadata.Alternates.Count > 0) + { + return layout.Metadata.Alternates.Last(); + } + + return layout.Metadata.Type; } - return _orchardHelper; + return String.Empty; + } + + set + { + if (ThemeLayout is IShape layout) + { + if (layout.Metadata.Alternates.Contains(value)) + { + if (layout.Metadata.Alternates.Last() == value) + { + return; + } + + layout.Metadata.Alternates.Remove(value); + } + + layout.Metadata.Alternates.Add(value); + } } } @@ -214,5 +245,21 @@ public object OrDefault(object text, object other) /// Returns the full path of the current request. /// public string FullRequestPath => HttpContext.Request.PathBase + HttpContext.Request.Path + HttpContext.Request.QueryString; + + /// + /// Gets the instance. + /// + public ISite Site + { + get + { + if (_site == null) + { + _site = (ISite)HttpContext.Items[typeof(ISite)]; + } + + return _site; + } + } } } From 9faea3519b8bc4f54b442d9194b628fcc55d250c Mon Sep 17 00:00:00 2001 From: jtkech Date: Sun, 14 Jul 2019 22:27:12 +0200 Subject: [PATCH 02/38] Little refactoring. --- .../LiquidViewTemplate.cs | 2 +- ...sultFilter.cs => IAsyncViewResultFilter.cs} | 3 ++- .../OrchardCoreBuilderExtensions.cs | 4 ++-- .../Razor/RazorShapeTemplateViewEngine.cs | 2 +- .../Razor/SiteViewResultFilter.cs | 18 ++++++------------ .../Razor/ThemeLayoutViewResultFilter.cs | 18 ++++++------------ 6 files changed, 18 insertions(+), 29 deletions(-) rename src/OrchardCore/OrchardCore.DisplayManagement/{IViewResultFilter.cs => IAsyncViewResultFilter.cs} (63%) diff --git a/src/OrchardCore/OrchardCore.DisplayManagement.Liquid/LiquidViewTemplate.cs b/src/OrchardCore/OrchardCore.DisplayManagement.Liquid/LiquidViewTemplate.cs index c4a044f0fc6..b8bec6fe327 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement.Liquid/LiquidViewTemplate.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement.Liquid/LiquidViewTemplate.cs @@ -321,7 +321,7 @@ private async static Task GetActionContextAsync(IServiceProvider routeData.Routers.Add(pipeline?.Router ?? new RouteCollection()); actionContext = new ActionContext(httpContext, routeData, new ActionDescriptor()); - var filters = httpContext.RequestServices.GetServices(); + var filters = httpContext.RequestServices.GetServices(); foreach (var filter in filters) { diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/IViewResultFilter.cs b/src/OrchardCore/OrchardCore.DisplayManagement/IAsyncViewResultFilter.cs similarity index 63% rename from src/OrchardCore/OrchardCore.DisplayManagement/IViewResultFilter.cs rename to src/OrchardCore/OrchardCore.DisplayManagement/IAsyncViewResultFilter.cs index ff6cedca9ab..c6e4f554118 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/IViewResultFilter.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/IAsyncViewResultFilter.cs @@ -1,9 +1,10 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; namespace OrchardCore.DisplayManagement { - public interface IViewResultFilter + public interface IAsyncViewResultFilter : IAsyncResultFilter { Task OnResultExecutionAsync(ActionContext context); } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs b/src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs index 009c09c3a71..087ef2240fb 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs @@ -46,8 +46,8 @@ public static OrchardCoreBuilder AddTheming(this OrchardCoreBuilder builder) }); // Used as services when we create fake view and action contexts. - services.AddScoped(); - services.AddScoped(); + services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorShapeTemplateViewEngine.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorShapeTemplateViewEngine.cs index ac62ef3bdfc..4ad942dc8b5 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorShapeTemplateViewEngine.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorShapeTemplateViewEngine.cs @@ -161,7 +161,7 @@ private async Task GetActionContextAsync() routeData.Routers.Add(pipeline?.Router ?? new RouteCollection()); actionContext = new ActionContext(httpContext, routeData, new ActionDescriptor()); - var filters = httpContext.RequestServices.GetServices(); + var filters = httpContext.RequestServices.GetServices(); foreach (var filter in filters) { diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs index 35a7278e3d5..0a1035d01d3 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs @@ -1,5 +1,4 @@ using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.DependencyInjection; @@ -11,30 +10,25 @@ namespace OrchardCore.DisplayManagement.Razor /// Inject an instance of in the HttpContext items such that /// a View can reuse it when it's executed. /// - public class SiteViewResultFilter : IAsyncResultFilter, IViewResultFilter + public class SiteViewResultFilter : IAsyncViewResultFilter { public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) { - await OnResultExecutionAsync(context.HttpContext); + await OnResultExecutionAsync(context); await next(); } // Used when we create fake view and action contexts. - public Task OnResultExecutionAsync(ActionContext context) + public async Task OnResultExecutionAsync(ActionContext context) { - return OnResultExecutionAsync(context.HttpContext); - } - - private async Task OnResultExecutionAsync(HttpContext context) - { - if (!context.Items.ContainsKey(typeof(ISite))) + if (!context.HttpContext.Items.ContainsKey(typeof(ISite))) { - var siteService = context.RequestServices.GetService(); + var siteService = context.HttpContext.RequestServices.GetService(); // siteService can be null during Setup if (siteService != null) { - context.Items.Add(typeof(ISite), await siteService.GetSiteSettingsAsync()); + context.HttpContext.Items.Add(typeof(ISite), await siteService.GetSiteSettingsAsync()); } } } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/ThemeLayoutViewResultFilter.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/ThemeLayoutViewResultFilter.cs index 59808e5b644..258195c4847 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/ThemeLayoutViewResultFilter.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/ThemeLayoutViewResultFilter.cs @@ -1,5 +1,4 @@ using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.DependencyInjection; @@ -11,29 +10,24 @@ namespace OrchardCore.DisplayManagement.Razor /// Inject an instance of the theme layout in the HttpContext items such that /// a View can reuse it when it's executed. /// - public class ThemeLayoutViewResultFilter : IAsyncResultFilter, IViewResultFilter + public class ThemeLayoutViewResultFilter : IAsyncViewResultFilter { public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) { - await OnResultExecutionAsync(context.HttpContext); + await OnResultExecutionAsync(context); await next(); } // Used when we create fake view and action contexts. - public Task OnResultExecutionAsync(ActionContext context) + public async Task OnResultExecutionAsync(ActionContext context) { - return OnResultExecutionAsync(context.HttpContext); - } - - private async Task OnResultExecutionAsync(HttpContext context) - { - if (!context.Items.ContainsKey(typeof(IShape))) + if (!context.HttpContext.Items.ContainsKey(typeof(IShape))) { - var layoutAccessor = context.RequestServices.GetService(); + var layoutAccessor = context.HttpContext.RequestServices.GetService(); if (layoutAccessor != null) { - context.Items.Add(typeof(IShape), await layoutAccessor.GetLayoutAsync()); + context.HttpContext.Items.Add(typeof(IShape), await layoutAccessor.GetLayoutAsync()); } } } From d4d57b3fb4056ca177577d560e38d44149d123e3 Mon Sep 17 00:00:00 2001 From: jtkech Date: Sun, 14 Jul 2019 23:43:42 +0200 Subject: [PATCH 03/38] Minor change --- .../OrchardCoreBuilderExtensions.cs | 2 +- .../OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs | 2 +- .../Razor/ThemeLayoutViewResultFilter.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs b/src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs index 087ef2240fb..ab5ecb593b1 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs @@ -45,7 +45,7 @@ public static OrchardCoreBuilder AddTheming(this OrchardCoreBuilder builder) options.Filters.Add(typeof(ThemeLayoutViewResultFilter)); }); - // Used as services when we create fake view and action contexts. + // Used as services when we create a fake 'ActionContext'. services.AddScoped(); services.AddScoped(); diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs index 0a1035d01d3..697b0a69d79 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs @@ -18,7 +18,7 @@ public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultE await next(); } - // Used when we create fake view and action contexts. + // Used as a service when we create a fake 'ActionContext'. public async Task OnResultExecutionAsync(ActionContext context) { if (!context.HttpContext.Items.ContainsKey(typeof(ISite))) diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/ThemeLayoutViewResultFilter.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/ThemeLayoutViewResultFilter.cs index 258195c4847..19fc71da831 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/ThemeLayoutViewResultFilter.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/ThemeLayoutViewResultFilter.cs @@ -18,7 +18,7 @@ public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultE await next(); } - // Used when we create fake view and action contexts. + // Used as a service when we create a fake 'ActionContext'. public async Task OnResultExecutionAsync(ActionContext context) { if (!context.HttpContext.Items.ContainsKey(typeof(IShape))) From 9ed5150f5ba17fb8ca6e413f7fbcd385adfb6fa9 Mon Sep 17 00:00:00 2001 From: jtkech Date: Mon, 15 Jul 2019 00:49:03 +0200 Subject: [PATCH 04/38] More async calls. --- .../OrchardCore.AdminMenu/Permissions.cs | 18 ++++++++++----- .../OrchardCore.Queries/Permissions.cs | 15 +++++++++---- .../Controllers/AdminController.cs | 22 +++++++++++-------- .../Liquid/HasPermissionFilter.cs | 11 +++++++--- .../Permissions/IPermissionProvider.cs | 11 +++++++++- 5 files changed, 54 insertions(+), 23 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.AdminMenu/Permissions.cs b/src/OrchardCore.Modules/OrchardCore.AdminMenu/Permissions.cs index 70c2772293f..f19eebe42dc 100644 --- a/src/OrchardCore.Modules/OrchardCore.AdminMenu/Permissions.cs +++ b/src/OrchardCore.Modules/OrchardCore.AdminMenu/Permissions.cs @@ -1,10 +1,11 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using OrchardCore.Security.Permissions; namespace OrchardCore.AdminMenu { - public class Permissions : IPermissionProvider + public class Permissions : IAsyncPermissionProvider { public static readonly Permission ManageAdminMenu = new Permission("ManageAdminMenu", "Manage the admin menu"); @@ -19,17 +20,22 @@ public Permissions(IAdminMenuService adminMenuService) _adminMenuService = adminMenuService; } - + // Sync version for backward compatibility. public IEnumerable GetPermissions() + { + return GetPermissionsAsync().GetAwaiter().GetResult(); + } + + public async Task> GetPermissionsAsync() { var list = new List { ManageAdminMenu, ViewAdminMenuAll }; - foreach (var adminMenu in _adminMenuService.GetAsync().GetAwaiter().GetResult()) + foreach (var adminMenu in await _adminMenuService.GetAsync()) { list.Add(CreatePermissionForAdminMenu(adminMenu.Name)); - } + } - return list; + return list; } public IEnumerable GetDefaultStereotypes() @@ -57,4 +63,4 @@ public static Permission CreatePermissionForAdminMenu(string name) ); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Queries/Permissions.cs b/src/OrchardCore.Modules/OrchardCore.Queries/Permissions.cs index 45cefd14dcc..b952f121d5c 100644 --- a/src/OrchardCore.Modules/OrchardCore.Queries/Permissions.cs +++ b/src/OrchardCore.Modules/OrchardCore.Queries/Permissions.cs @@ -1,10 +1,11 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using OrchardCore.Security.Permissions; namespace OrchardCore.Queries { - public class Permissions : IPermissionProvider + public class Permissions : IAsyncPermissionProvider { public static readonly Permission ManageQueries = new Permission("ManageQueries", "Manage queries"); public static readonly Permission ExecuteApiAll = new Permission("ExecuteApiAll", "Execute Api - All queries", new[] { ManageQueries }); @@ -18,11 +19,17 @@ public Permissions(IQueryManager queryManager) _queryManager = queryManager; } + // Sync version for backward compatibility. public IEnumerable GetPermissions() + { + return GetPermissionsAsync().GetAwaiter().GetResult(); + } + + public async Task> GetPermissionsAsync() { var list = new List { ManageQueries, ExecuteApiAll }; - foreach(var query in _queryManager.ListQueriesAsync().GetAwaiter().GetResult()) + foreach (var query in await _queryManager.ListQueriesAsync()) { list.Add(CreatePermissionForQuery(query.Name)); } @@ -43,7 +50,7 @@ public IEnumerable GetDefaultStereotypes() } }; } - + public static Permission CreatePermissionForQuery(string name) { return new Permission( @@ -53,4 +60,4 @@ public static Permission CreatePermissionForQuery(string name) ); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Roles/Controllers/AdminController.cs b/src/OrchardCore.Modules/OrchardCore.Roles/Controllers/AdminController.cs index 3afa3504a85..c23be4b8365 100644 --- a/src/OrchardCore.Modules/OrchardCore.Roles/Controllers/AdminController.cs +++ b/src/OrchardCore.Modules/OrchardCore.Roles/Controllers/AdminController.cs @@ -74,7 +74,7 @@ public async Task Index() { RoleEntries = roles.Select(BuildRoleEntry).ToList() }; - + return View(model); } @@ -97,7 +97,7 @@ public async Task Create(CreateRoleViewModel model) if (ModelState.IsValid) { model.RoleName = model.RoleName.Trim(); - + if (await _roleManager.FindByNameAsync(_roleManager.NormalizeKey(model.RoleName)) != null) { ModelState.AddModelError(string.Empty, T["The role is already used."]); @@ -170,13 +170,13 @@ public async Task Edit(string id) return Unauthorized(); } - var role = (Role) await _roleManager.FindByNameAsync(_roleManager.NormalizeKey(id)); + var role = (Role)await _roleManager.FindByNameAsync(_roleManager.NormalizeKey(id)); if (role == null) { return NotFound(); } - var installedPermissions = GetInstalledPermissions(); + var installedPermissions = await GetInstalledPermissionsAsync(); var allPermissions = installedPermissions.SelectMany(x => x.Value); var model = new EditRoleViewModel @@ -198,7 +198,7 @@ public async Task EditPost(string id) return Unauthorized(); } - var role = (Role) await _roleManager.FindByNameAsync(_roleManager.NormalizeKey(id)); + var role = (Role)await _roleManager.FindByNameAsync(_roleManager.NormalizeKey(id)); if (role == null) { @@ -235,14 +235,18 @@ private RoleEntry BuildRoleEntry(string name) }; } - private IDictionary> GetInstalledPermissions() + private async Task>> GetInstalledPermissionsAsync() { var installedPermissions = new Dictionary>(); foreach (var permissionProvider in _permissionProviders) { var feature = _typeFeatureProvider.GetFeatureForDependency(permissionProvider.GetType()); var featureName = feature.Id; - var permissions = permissionProvider.GetPermissions(); + + var permissions = permissionProvider is IAsyncPermissionProvider asyncProvider + ? await asyncProvider.GetPermissionsAsync() + : permissionProvider.GetPermissions(); + foreach (var permission in permissions) { var category = permission.Category; @@ -268,13 +272,13 @@ private async Task> GetEffectivePermissions(Role role, IEnum // Create a fake user to check the actual permissions. If the role is anonymous // IsAuthenticated needs to be false. var fakeUser = new ClaimsPrincipal( - new ClaimsIdentity(new[] { new Claim(ClaimTypes.Role, role.RoleName)}, + new ClaimsIdentity(new[] { new Claim(ClaimTypes.Role, role.RoleName) }, role.RoleName != "Anonymous" ? "FakeAuthenticationType" : null) ); var result = new List(); - foreach(var permission in allPermissions) + foreach (var permission in allPermissions) { if (await _authorizationService.AuthorizeAsync(fakeUser, permission)) { diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Liquid/HasPermissionFilter.cs b/src/OrchardCore.Modules/OrchardCore.Users/Liquid/HasPermissionFilter.cs index 686f7c9de9f..33fe186948e 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Liquid/HasPermissionFilter.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/Liquid/HasPermissionFilter.cs @@ -1,14 +1,14 @@ using System; using System.Collections.Generic; -using System.Security.Claims; using System.Linq; +using System.Security.Claims; using System.Threading.Tasks; using Fluid; using Fluid.Values; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; -using OrchardCore.Security.Permissions; using OrchardCore.Liquid; +using OrchardCore.Security.Permissions; namespace OrchardCore.Users.Liquid { @@ -34,7 +34,12 @@ public async ValueTask ProcessAsync(FluidValue input, FilterArgument foreach (var item in permissionProviders) { - permission = item.GetPermissions().FirstOrDefault(c => c.Name == permissionName); + var permissions = item is IAsyncPermissionProvider asyncItem + ? await asyncItem.GetPermissionsAsync() + : item.GetPermissions(); + + permission = permissions.FirstOrDefault(p => p.Name == permissionName); + if (permission != null) break; } diff --git a/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Security/Permissions/IPermissionProvider.cs b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Security/Permissions/IPermissionProvider.cs index 3dcc72b4803..9c88343c8a3 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Security/Permissions/IPermissionProvider.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Security/Permissions/IPermissionProvider.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Generic; +using System.Threading.Tasks; namespace OrchardCore.Security.Permissions { @@ -12,6 +13,14 @@ public interface IPermissionProvider IEnumerable GetDefaultStereotypes(); } + /// + /// Async version of . + /// + public interface IAsyncPermissionProvider : IPermissionProvider + { + Task> GetPermissionsAsync(); + } + public class PermissionStereotype { public string Name { get; set; } From 8a249adafcee8c89ddc311d2f4aff0bc6a7ad4fb Mon Sep 17 00:00:00 2001 From: jtkech Date: Wed, 17 Jul 2019 05:52:23 +0200 Subject: [PATCH 05/38] Refactoring of home and autoroute to prevent some non async executions. --- .../Drivers/AutoroutePartDisplay.cs | 19 +++- .../Handlers/AutoroutePartHandler.cs | 27 +++-- .../Routing/AutorouteRoute.cs | 99 +++++++++---------- .../Services/AutorouteEntries.cs | 7 ++ .../OrchardCore.Autoroute/Startup.cs | 8 +- .../OrchardCore.Contents/Startup.cs | 17 +++- .../OrchardCore.HomeRoute/HomePageRoute.cs | 59 +++-------- .../HomeRouteMiddleware.cs | 34 +++++++ .../OrchardCore.HomeRoute/Startup.cs | 8 +- .../Routing/AutorouteOptions.cs | 10 ++ .../Settings/HomeRouteFeature.cs | 12 +++ 11 files changed, 182 insertions(+), 118 deletions(-) create mode 100644 src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs create mode 100644 src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Routing/AutorouteOptions.cs create mode 100644 src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Settings/HomeRouteFeature.cs diff --git a/src/OrchardCore.Modules/OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs b/src/OrchardCore.Modules/OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs index a34b3cb2b2a..0d6283c359d 100644 --- a/src/OrchardCore.Modules/OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs +++ b/src/OrchardCore.Modules/OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs @@ -4,12 +4,14 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Options; using OrchardCore.Autoroute.Model; using OrchardCore.Autoroute.Models; using OrchardCore.Autoroute.ViewModels; using OrchardCore.ContentManagement.Display.ContentDisplay; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Records; +using OrchardCore.ContentManagement.Routing; using OrchardCore.DisplayManagement.ModelBinding; using OrchardCore.DisplayManagement.Views; using OrchardCore.Mvc.ModelBinding; @@ -23,6 +25,7 @@ public class AutoroutePartDisplay : ContentPartDisplayDriver public static char[] InvalidCharactersForPath = ":?#[]@!$&'()*+,.;=<>\\|%".ToCharArray(); public const int MaxPathLength = 1024; + private readonly AutorouteOptions _options; private readonly IContentDefinitionManager _contentDefinitionManager; private readonly ISiteService _siteService; private readonly IAuthorizationService _authorizationService; @@ -31,6 +34,7 @@ public class AutoroutePartDisplay : ContentPartDisplayDriver private readonly IStringLocalizer T; public AutoroutePartDisplay( + IOptions options, IContentDefinitionManager contentDefinitionManager, ISiteService siteService, IAuthorizationService authorizationService, @@ -39,6 +43,7 @@ public AutoroutePartDisplay( IStringLocalizer localizer ) { + _options = options.Value; _contentDefinitionManager = contentDefinitionManager; _siteService = siteService; _authorizationService = authorizationService; @@ -51,17 +56,16 @@ public override IDisplayResult Edit(AutoroutePart autoroutePart) { return Initialize("AutoroutePart_Edit", async model => { - model.Path = autoroutePart.Path; model.AutoroutePart = autoroutePart; model.SetHomepage = false; var siteSettings = await _siteService.GetSiteSettingsAsync(); var homeRoute = siteSettings.HomeRoute; - if (homeRoute["area"]?.ToString() == "OrchardCore.Contents" && - homeRoute["controller"]?.ToString() == "Item" && - homeRoute["action"]?.ToString() == "Display" && - autoroutePart.ContentItem.ContentItemId == homeRoute["contentItemId"]?.ToString()) + + if (autoroutePart.ContentItem.ContentItemId == homeRoute?[_options.ContentItemIdKey]?.ToString() && + _options.GlobalRouteValues.All(entry => String.Equals(homeRoute?[entry.Key]?.ToString(), + entry.Value.ToString(), StringComparison.OrdinalIgnoreCase))) { model.IsHomepage = true; } @@ -110,6 +114,11 @@ public override async Task UpdateAsync(AutoroutePart model, IUpd private async Task ValidateAsync(AutoroutePart autoroute, IUpdateModel updater) { + if (autoroute.Path == "/") + { + updater.ModelState.AddModelError(Prefix, nameof(autoroute.Path), T["Your permalink can't be set to the homepage, please use the homepage option instead."]); + } + if (autoroute.Path?.IndexOfAny(InvalidCharactersForPath) > -1 || autoroute.Path?.IndexOf(' ') > -1) { var invalidCharactersForMessage = string.Join(", ", InvalidCharactersForPath.Select(c => $"\"{c}\"")); diff --git a/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs b/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs index 735529785ed..f70009bacf9 100644 --- a/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs +++ b/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs @@ -2,6 +2,8 @@ using System.Linq; using System.Threading.Tasks; using Fluid; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.Options; using OrchardCore.Autoroute.Model; using OrchardCore.Autoroute.Models; using OrchardCore.ContentManagement; @@ -19,23 +21,26 @@ namespace OrchardCore.Autoroute.Handlers public class AutoroutePartHandler : ContentPartHandler { private readonly IAutorouteEntries _entries; + private readonly AutorouteOptions _options; private readonly ILiquidTemplateManager _liquidTemplateManager; private readonly IContentDefinitionManager _contentDefinitionManager; private readonly ISiteService _siteService; private readonly ITagCache _tagCache; - private readonly YesSql.ISession _session; + private readonly ISession _session; public AutoroutePartHandler( IAutorouteEntries entries, + IOptions options, ILiquidTemplateManager liquidTemplateManager, IContentDefinitionManager contentDefinitionManager, ISiteService siteService, ITagCache tagCache, - YesSql.ISession session) + ISession session) { - _contentDefinitionManager = contentDefinitionManager; _entries = entries; + _options = options.Value; _liquidTemplateManager = liquidTemplateManager; + _contentDefinitionManager = contentDefinitionManager; _siteService = siteService; _tagCache = tagCache; _session = session; @@ -51,12 +56,20 @@ public override async Task PublishedAsync(PublishContentContext context, Autorou if (part.SetHomepage) { var site = await _siteService.GetSiteSettingsAsync(); + + if (site.HomeRoute == null) + { + site.HomeRoute = new RouteValueDictionary(); + } + var homeRoute = site.HomeRoute; - homeRoute["area"] = "OrchardCore.Contents"; - homeRoute["controller"] = "Item"; - homeRoute["action"] = "Display"; - homeRoute["contentItemId"] = context.ContentItem.ContentItemId; + foreach (var entry in _options.GlobalRouteValues) + { + homeRoute[entry.Key] = entry.Value; + } + + homeRoute[_options.ContentItemIdKey] = context.ContentItem.ContentItemId; // Once we too the flag into account we can dismiss it. part.SetHomepage = false; diff --git a/src/OrchardCore.Modules/OrchardCore.Autoroute/Routing/AutorouteRoute.cs b/src/OrchardCore.Modules/OrchardCore.Autoroute/Routing/AutorouteRoute.cs index de49628fa50..149f40894c6 100644 --- a/src/OrchardCore.Modules/OrchardCore.Autoroute/Routing/AutorouteRoute.cs +++ b/src/OrchardCore.Modules/OrchardCore.Autoroute/Routing/AutorouteRoute.cs @@ -1,57 +1,73 @@ using System; -using System.Collections.Generic; using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.WebUtilities; -using Microsoft.Extensions.DependencyInjection; -using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Routing; +using OrchardCore.Settings; namespace OrchardCore.Autoroute.Routing { public class AutorouteRoute : IRouter { - private readonly IAutorouteEntries _entries; private readonly IRouter _target; - private static HashSet _keys = new HashSet(new[] { "area", "controller", "action", "contentItemId" }, StringComparer.OrdinalIgnoreCase); + private readonly IAutorouteEntries _entries; + private readonly AutorouteOptions _options; - public AutorouteRoute(IAutorouteEntries entries, IRouter target) + public AutorouteRoute(IRouter target, IAutorouteEntries entries, AutorouteOptions options) { _target = target; _entries = entries; + _options = options; } public VirtualPathData GetVirtualPath(VirtualPathContext context) { - string contentItemId = context.Values["contentItemId"]?.ToString(); + if (_options.GlobalRouteValues.Count == 0) + { + return null; + } + + string contentItemId = context.Values[_options.ContentItemIdKey]?.ToString(); if (string.IsNullOrEmpty(contentItemId)) { return null; } - var displayRouteData = GetContentItemDisplayRoutes(context.HttpContext, contentItemId).Result; + var homeRoute = context.HttpContext.Features.Get()?.HomeRoute; + + if (homeRoute?[_options.ContentItemIdKey]?.ToString() == contentItemId) + { + return null; + } + + foreach (var entry in _options.GlobalRouteValues) + { + if (!String.Equals(context.Values[entry.Key]?.ToString(), entry.Value?.ToString(), StringComparison.OrdinalIgnoreCase)) + { + return null; + } + } - if (string.Equals(context.Values["area"]?.ToString(), displayRouteData?["area"]?.ToString(), StringComparison.OrdinalIgnoreCase) - && string.Equals(context.Values["controller"]?.ToString(), displayRouteData?["controller"]?.ToString(), StringComparison.OrdinalIgnoreCase) - && string.Equals(context.Values["action"]?.ToString(), displayRouteData?["action"]?.ToString(), StringComparison.OrdinalIgnoreCase)) + if (_entries.TryGetPath(contentItemId, out string path)) { - if (_entries.TryGetPath(contentItemId, out string path)) + if (context.Values.Count > _options.GlobalRouteValues.Count + 1) { - if (context.Values.Count > 4) + foreach (var entry in context.Values) { - foreach (var data in context.Values) + if (entry.Key == _options.ContentItemIdKey) { - if (!_keys.Contains(data.Key)) - { - path = QueryHelpers.AddQueryString(path, data.Key, data.Value.ToString()); - } + continue; } - } - return new VirtualPathData(_target, path); + if (!_options.GlobalRouteValues.ContainsKey(entry.Key)) + { + path = QueryHelpers.AddQueryString(path, entry.Key, entry.Value.ToString()); + } + } } + + return new VirtualPathData(_target, path); } return null; @@ -59,49 +75,28 @@ public VirtualPathData GetVirtualPath(VirtualPathContext context) public async Task RouteAsync(RouteContext context) { - var requestPath = context.HttpContext.Request.Path.Value; - - if (_entries.TryGetContentItemId(requestPath, out var contentItemId)) + if (_options.GlobalRouteValues.Count == 0) { - await EnsureRouteData(context, contentItemId); - await _target.RouteAsync(context); - } - } - - private async Task GetContentItemDisplayRoutes(HttpContext context, string contentItemId) - { - if (string.IsNullOrEmpty(contentItemId)) - { - return null; + return; } - var contentManager = context.RequestServices.GetService(); - var contentItem = await contentManager.GetAsync(contentItemId); + var requestPath = context.HttpContext.Request.Path.Value; - if (contentItem == null) + if (_entries.TryGetContentItemId(requestPath, out var contentItemId)) { - return null; + EnsureRouteData(context, contentItemId); + await _target.RouteAsync(context); } - - return (await contentManager.PopulateAspectAsync(contentItem))?.DisplayRouteValues; } - private async Task EnsureRouteData(RouteContext context, string contentItemId) + private void EnsureRouteData(RouteContext context, string contentItemId) { - var displayRoutes = await GetContentItemDisplayRoutes(context.HttpContext, contentItemId); - - if (displayRoutes == null) + foreach (var entry in _options.GlobalRouteValues) { - return; + context.RouteData.Values[entry.Key] = entry.Value; } - foreach (var key in _keys) - { - if (displayRoutes.ContainsKey(key)) - { - context.RouteData.Values[key] = displayRoutes[key]; - } - } + context.RouteData.Values[_options.ContentItemIdKey] = contentItemId; context.RouteData.Routers.Add(_target); } diff --git a/src/OrchardCore.Modules/OrchardCore.Autoroute/Services/AutorouteEntries.cs b/src/OrchardCore.Modules/OrchardCore.Autoroute/Services/AutorouteEntries.cs index 0faf2193450..4ff1ac49853 100644 --- a/src/OrchardCore.Modules/OrchardCore.Autoroute/Services/AutorouteEntries.cs +++ b/src/OrchardCore.Modules/OrchardCore.Autoroute/Services/AutorouteEntries.cs @@ -25,12 +25,19 @@ public bool TryGetPath(string contentItemId, out string path) return _paths.TryGetValue(contentItemId, out path); } + public string HomePageId { get; set; } + public void AddEntries(IEnumerable entries) { lock (this) { foreach (var entry in entries) { + if (_paths.TryGetValue(entry.ContentItemId, out var previousPath)) + { + _contentItemIds.Remove(previousPath); + } + var requestPath = "/" + entry.Path.TrimStart('/'); _paths[entry.ContentItemId] = requestPath; _contentItemIds[requestPath] = entry.ContentItemId; diff --git a/src/OrchardCore.Modules/OrchardCore.Autoroute/Startup.cs b/src/OrchardCore.Modules/OrchardCore.Autoroute/Startup.cs index 5ac175f3dec..498578514d3 100644 --- a/src/OrchardCore.Modules/OrchardCore.Autoroute/Startup.cs +++ b/src/OrchardCore.Modules/OrchardCore.Autoroute/Startup.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OrchardCore.Autoroute.Drivers; using OrchardCore.Autoroute.Handlers; using OrchardCore.Autoroute.Indexing; @@ -68,11 +69,12 @@ public override void Configure(IApplicationBuilder app, IRouteBuilder routes, IS { var entries = serviceProvider.GetRequiredService(); var session = serviceProvider.GetRequiredService(); - var autoroutes = session.QueryIndex(o => o.Published).ListAsync().GetAwaiter().GetResult(); - entries.AddEntries(autoroutes.Select(x => new AutorouteEntry { ContentItemId = x.ContentItemId, Path = x.Path })); + var autoroutes = session.QueryIndex(o => o.Published).ListAsync().GetAwaiter().GetResult(); + entries.AddEntries(autoroutes.Select(o => new AutorouteEntry { ContentItemId = o.ContentItemId, Path = o.Path })); - var autorouteRoute = new AutorouteRoute(entries, routes.DefaultHandler); + var options = serviceProvider.GetRequiredService>().Value; + var autorouteRoute = new AutorouteRoute(routes.DefaultHandler, entries, options); routes.Routes.Insert(0, autorouteRoute); } diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Startup.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Startup.cs index 79d4cd88e78..decb7630290 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Startup.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Startup.cs @@ -8,6 +8,7 @@ using OrchardCore.ContentManagement.Display; using OrchardCore.ContentManagement.Display.ContentDisplay; using OrchardCore.ContentManagement.Handlers; +using OrchardCore.ContentManagement.Routing; using OrchardCore.Contents.AdminNodes; using OrchardCore.Contents.Deployment; using OrchardCore.Contents.Drivers; @@ -72,6 +73,20 @@ public override void ConfigureServices(IServiceCollection services) services.AddTagHelpers(); + services.Configure(options => + { + if (options.GlobalRouteValues.Count == 0) + { + options.GlobalRouteValues = new RouteValueDictionary + { + {"Area", "OrchardCore.Contents"}, + {"Controller", "Item"}, + {"Action", "Display"} + }; + + options.ContentItemIdKey = "contentItemId"; + } + }); } public override void Configure(IApplicationBuilder builder, IRouteBuilder routes, IServiceProvider serviceProvider) @@ -165,7 +180,7 @@ public override void ConfigureServices(IServiceCollection services) services.AddScoped(); services.AddScoped, ContentTypesAdminNodeDriver>(); } - } + } [Feature("OrchardCore.Contents.FileContentDefinition")] public class FileContentDefinitionStartup : StartupBase diff --git a/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomePageRoute.cs b/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomePageRoute.cs index 3c6889472b3..a72494b9a07 100644 --- a/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomePageRoute.cs +++ b/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomePageRoute.cs @@ -1,30 +1,27 @@ using System; using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Primitives; using OrchardCore.Settings; namespace OrchardCore.HomeRoute { public class HomePageRoute : Route { - private RouteValueDictionary _homeRoute; - private IChangeToken _siteServicechangeToken; + private readonly IRouter _target; public HomePageRoute(IRouteBuilder routeBuilder, IInlineConstraintResolver inlineConstraintResolver) : base(routeBuilder.DefaultHandler, "", inlineConstraintResolver) { + _target = routeBuilder.DefaultHandler; } protected override async Task OnRouteMatched(RouteContext context) { - var tokens = GetHomeRouteValues(context.HttpContext); + var homeRoute = context.HttpContext.Features.Get()?.HomeRoute; - if (tokens != null) + if (homeRoute != null) { - foreach (var entry in tokens) + foreach (var entry in homeRoute) { context.RouteData.Values[entry.Key] = entry.Value; } @@ -35,55 +32,23 @@ protected override async Task OnRouteMatched(RouteContext context) public override VirtualPathData GetVirtualPath(VirtualPathContext context) { - var tokens = GetHomeRouteValues(context.HttpContext); + var homeRoute = context.HttpContext.Features.Get()?.HomeRoute; - if (tokens == null || tokens.Count == 0) + if (homeRoute == null || homeRoute.Count == 0) { return null; } // Return null if it doesn't match the home route values - foreach (var entry in tokens) + foreach (var entry in homeRoute) { - object value; - if (string.Equals(entry.Key, "area", StringComparison.OrdinalIgnoreCase)) + if (!String.Equals(context.Values[entry.Key]?.ToString(), entry.Value.ToString(), StringComparison.OrdinalIgnoreCase)) { - if (!context.Values.TryGetValue("area", out value) || !String.Equals(value.ToString(), tokens["area"].ToString(), StringComparison.OrdinalIgnoreCase)) - { - return null; - } + return null; } - else - { - if (!context.Values.TryGetValue(entry.Key, out value) || !String.Equals(value.ToString(), entry.Value.ToString(), StringComparison.OrdinalIgnoreCase)) - { - return null; - } - } - } - - // Remove the values that should not be rendered in the query string - var clonedContext = new VirtualPathContext(context.HttpContext, context.AmbientValues, new RouteValueDictionary(context.Values), context.RouteName); - foreach (var key in tokens.Keys) - { - clonedContext.Values.Remove(key); - } - - var result = base.GetVirtualPath(clonedContext); - - return result; - } - - private RouteValueDictionary GetHomeRouteValues(HttpContext httpContext) - { - if (_siteServicechangeToken == null || _siteServicechangeToken.HasChanged) - { - var siteService = httpContext.RequestServices.GetRequiredService(); - _homeRoute = siteService.GetSiteSettingsAsync().GetAwaiter().GetResult().HomeRoute; - _siteServicechangeToken = siteService.ChangeToken; } - return _homeRoute; + return new VirtualPathData(_target, "/"); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs b/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs new file mode 100644 index 00000000000..45b6e45b027 --- /dev/null +++ b/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs @@ -0,0 +1,34 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using OrchardCore.Settings; + +namespace OrchardCore.HomeRoute +{ + public class HomeRouteMiddleware + { + private readonly RequestDelegate _next; + + public HomeRouteMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task Invoke(HttpContext httpContext) + { + var siteService = httpContext.RequestServices.GetService(); + + if (siteService != null) + { + var homeRoute = (await siteService.GetSiteSettingsAsync()).HomeRoute; + + httpContext.Features.Set(new HomeRouteFeature + { + HomeRoute = homeRoute + }); + } + + await _next.Invoke(httpContext); + } + } +} diff --git a/src/OrchardCore.Modules/OrchardCore.HomeRoute/Startup.cs b/src/OrchardCore.Modules/OrchardCore.HomeRoute/Startup.cs index 275fc6b99d0..0ceff0e69a0 100644 --- a/src/OrchardCore.Modules/OrchardCore.HomeRoute/Startup.cs +++ b/src/OrchardCore.Modules/OrchardCore.HomeRoute/Startup.cs @@ -1,18 +1,20 @@ -using System; +using System; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http; -using OrchardCore.Modules; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; +using OrchardCore.Modules; namespace OrchardCore.HomeRoute { public class Startup : StartupBase { + public override int Order => -100; + public override void Configure(IApplicationBuilder app, IRouteBuilder routes, IServiceProvider serviceProvider) { var inlineConstraintResolver = serviceProvider.GetService(); routes.Routes.Add(new HomePageRoute(routes, inlineConstraintResolver)); + app.UseMiddleware(); } } } diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Routing/AutorouteOptions.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Routing/AutorouteOptions.cs new file mode 100644 index 00000000000..1fab80efb4d --- /dev/null +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Routing/AutorouteOptions.cs @@ -0,0 +1,10 @@ +using Microsoft.AspNetCore.Routing; + +namespace OrchardCore.ContentManagement.Routing +{ + public class AutorouteOptions + { + public RouteValueDictionary GlobalRouteValues { get; set; } = new RouteValueDictionary(); + public string ContentItemIdKey { get; set; } = ""; + } +} diff --git a/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Settings/HomeRouteFeature.cs b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Settings/HomeRouteFeature.cs new file mode 100644 index 00000000000..f23f8df046b --- /dev/null +++ b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Settings/HomeRouteFeature.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Routing; + +namespace OrchardCore.Settings +{ + /// + /// Used to capture the home route values. + /// + public class HomeRouteFeature + { + public RouteValueDictionary HomeRoute { get; set; } + } +} From 51bd80a391ef133a08668504a8425b4715a91dbc Mon Sep 17 00:00:00 2001 From: jtkech Date: Wed, 17 Jul 2019 05:59:53 +0200 Subject: [PATCH 06/38] Remove testing code. --- .../OrchardCore.Autoroute/Services/AutorouteEntries.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Autoroute/Services/AutorouteEntries.cs b/src/OrchardCore.Modules/OrchardCore.Autoroute/Services/AutorouteEntries.cs index 4ff1ac49853..e459e472c30 100644 --- a/src/OrchardCore.Modules/OrchardCore.Autoroute/Services/AutorouteEntries.cs +++ b/src/OrchardCore.Modules/OrchardCore.Autoroute/Services/AutorouteEntries.cs @@ -25,8 +25,6 @@ public bool TryGetPath(string contentItemId, out string path) return _paths.TryGetValue(contentItemId, out path); } - public string HomePageId { get; set; } - public void AddEntries(IEnumerable entries) { lock (this) From 6bf7be391ff33e0ed600a15f29675bb3443c45a0 Mon Sep 17 00:00:00 2001 From: jtkech Date: Wed, 17 Jul 2019 06:58:39 +0200 Subject: [PATCH 07/38] Simpler way to check "IsHomepage" before editing. --- .../OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs b/src/OrchardCore.Modules/OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs index 0d6283c359d..5b27096e147 100644 --- a/src/OrchardCore.Modules/OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs +++ b/src/OrchardCore.Modules/OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs @@ -63,9 +63,7 @@ public override IDisplayResult Edit(AutoroutePart autoroutePart) var siteSettings = await _siteService.GetSiteSettingsAsync(); var homeRoute = siteSettings.HomeRoute; - if (autoroutePart.ContentItem.ContentItemId == homeRoute?[_options.ContentItemIdKey]?.ToString() && - _options.GlobalRouteValues.All(entry => String.Equals(homeRoute?[entry.Key]?.ToString(), - entry.Value.ToString(), StringComparison.OrdinalIgnoreCase))) + if (autoroutePart.ContentItem.ContentItemId == homeRoute?[_options.ContentItemIdKey]?.ToString()) { model.IsHomepage = true; } From 34f9a1d38e27e541ef3162d928802bdcd15327cc Mon Sep 17 00:00:00 2001 From: jtkech Date: Thu, 18 Jul 2019 01:14:58 +0200 Subject: [PATCH 08/38] Some tweaks --- .../HomeRouteMiddleware.cs | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs b/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs index 45b6e45b027..b5018df57ff 100644 --- a/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs +++ b/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.Primitives; using OrchardCore.Settings; namespace OrchardCore.HomeRoute @@ -8,26 +9,29 @@ namespace OrchardCore.HomeRoute public class HomeRouteMiddleware { private readonly RequestDelegate _next; + private readonly ISiteService _siteService; + private IChangeToken _siteServicechangeToken; + private volatile RouteValueDictionary _homeRoute; - public HomeRouteMiddleware(RequestDelegate next) + public HomeRouteMiddleware(RequestDelegate next, ISiteService siteService) { _next = next; + _siteService = siteService; } public async Task Invoke(HttpContext httpContext) { - var siteService = httpContext.RequestServices.GetService(); - - if (siteService != null) + if (_siteServicechangeToken?.HasChanged ?? true) { - var homeRoute = (await siteService.GetSiteSettingsAsync()).HomeRoute; - - httpContext.Features.Set(new HomeRouteFeature - { - HomeRoute = homeRoute - }); + _homeRoute = (await _siteService.GetSiteSettingsAsync()).HomeRoute; + _siteServicechangeToken = _siteService.ChangeToken; } + httpContext.Features.Set(new HomeRouteFeature + { + HomeRoute = _homeRoute + }); + await _next.Invoke(httpContext); } } From a5a493ffd5a609643650f0a90cd904d533e58ee1 Mon Sep 17 00:00:00 2001 From: jtkech Date: Thu, 18 Jul 2019 01:23:40 +0200 Subject: [PATCH 09/38] Minor changes --- .../OrchardCore.HomeRoute/HomeRouteMiddleware.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs b/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs index b5018df57ff..6bd23e148a0 100644 --- a/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs +++ b/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs @@ -10,9 +10,10 @@ public class HomeRouteMiddleware { private readonly RequestDelegate _next; private readonly ISiteService _siteService; - private IChangeToken _siteServicechangeToken; private volatile RouteValueDictionary _homeRoute; + private IChangeToken _changeToken; + // 'HomeRoute' requires a registered 'ISiteService' implementation. public HomeRouteMiddleware(RequestDelegate next, ISiteService siteService) { _next = next; @@ -21,10 +22,11 @@ public HomeRouteMiddleware(RequestDelegate next, ISiteService siteService) public async Task Invoke(HttpContext httpContext) { - if (_siteServicechangeToken?.HasChanged ?? true) + if (_changeToken?.HasChanged ?? true) { + // Assumed to be atomic as we just update a reference type. _homeRoute = (await _siteService.GetSiteSettingsAsync()).HomeRoute; - _siteServicechangeToken = _siteService.ChangeToken; + _changeToken = _siteService.ChangeToken; } httpContext.Features.Set(new HomeRouteFeature From 2fd382285b8641258d0c3b7129cd5beaad356a4a Mon Sep 17 00:00:00 2001 From: jtkech Date: Thu, 18 Jul 2019 01:28:00 +0200 Subject: [PATCH 10/38] Minor change --- .../OrchardCore.HomeRoute/HomeRouteMiddleware.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs b/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs index 6bd23e148a0..6b6e836b528 100644 --- a/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs +++ b/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs @@ -10,7 +10,7 @@ public class HomeRouteMiddleware { private readonly RequestDelegate _next; private readonly ISiteService _siteService; - private volatile RouteValueDictionary _homeRoute; + private RouteValueDictionary _homeRoute; private IChangeToken _changeToken; // 'HomeRoute' requires a registered 'ISiteService' implementation. @@ -24,7 +24,7 @@ public async Task Invoke(HttpContext httpContext) { if (_changeToken?.HasChanged ?? true) { - // Assumed to be atomic as we just update a reference type. + // Assumed to be atomic as we just update reference types. _homeRoute = (await _siteService.GetSiteSettingsAsync()).HomeRoute; _changeToken = _siteService.ChangeToken; } From a977266503d73c536b09d36b5dc9a8b3e40d82e6 Mon Sep 17 00:00:00 2001 From: jtkech Date: Thu, 18 Jul 2019 02:49:36 +0200 Subject: [PATCH 11/38] GetShapeTableAsync() --- .../Views/Admin/EditField.cshtml | 2 +- .../Views/Admin/EditTypePart.cshtml | 2 +- .../BaseDisplayManager.cs | 2 +- .../Descriptors/DefaultShapeTableManager.cs | 11 +++-- .../Descriptors/Interfaces.cs | 3 +- .../Implementation/DefaultHtmlDisplay.cs | 2 +- .../Implementation/DefaultShapeFactory.cs | 2 +- .../DefaultShapeTableManagerTests.cs | 40 +++++++++---------- .../Stubs/TestShapeTableManager.cs | 4 +- 9 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/EditField.cshtml b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/EditField.cshtml index 6f4e46f7377..60db3baf576 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/EditField.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/EditField.cshtml @@ -10,7 +10,7 @@ @{ var theme = await ThemeManager.GetThemeAsync(); - var shapeTable = ShapeTableManager.GetShapeTable(theme?.Id); + var shapeTable = await ShapeTableManager.GetShapeTableAsync(theme?.Id); var editorShapes = shapeTable.ShapeBindings.Keys.Where(x => x.StartsWith(Model.PartFieldDefinition.FieldDefinition.Name + "_Option__", StringComparison.OrdinalIgnoreCase) || x.EndsWith(Model.PartFieldDefinition.FieldDefinition.Name + "_Option", StringComparison.OrdinalIgnoreCase)); var displayShapes = shapeTable.ShapeBindings.Keys.Where(x => x.StartsWith(Model.PartFieldDefinition.FieldDefinition.Name + "_DisplayOption__", StringComparison.OrdinalIgnoreCase) || x.EndsWith(Model.PartFieldDefinition.FieldDefinition.Name + "_Option", StringComparison.OrdinalIgnoreCase)); var returnUrl = ViewData["returnUrl"]?.ToString(); diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/EditTypePart.cshtml b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/EditTypePart.cshtml index e49cc1b1ced..d621f1dc2a5 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/EditTypePart.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/EditTypePart.cshtml @@ -8,7 +8,7 @@ @{ var typePart = Model.TypePartDefinition; var theme = await ThemeManager.GetThemeAsync(); - var shapeTable = ShapeTableManager.GetShapeTable(theme?.Id); + var shapeTable = await ShapeTableManager.GetShapeTableAsync(theme?.Id); var editorShapes = shapeTable.ShapeBindings.Keys.Where(x => x.StartsWith(Model.TypePartDefinition.PartDefinition.Name + "_Option__", StringComparison.OrdinalIgnoreCase) || x.EndsWith(Model.TypePartDefinition.PartDefinition.Name + "_Option", StringComparison.OrdinalIgnoreCase)); } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/BaseDisplayManager.cs b/src/OrchardCore/OrchardCore.DisplayManagement/BaseDisplayManager.cs index eab38566b23..fc325528ec5 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/BaseDisplayManager.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/BaseDisplayManager.cs @@ -33,7 +33,7 @@ protected async Task BindPlacementAsync(IBuildShapeContext context) return; } - var shapeTable = _shapeTableManager.GetShapeTable(theme.Id); + var shapeTable = await _shapeTableManager.GetShapeTableAsync(theme.Id); context.FindPlacement = (shapeType, differentiator, displayType, displayContext) => FindPlacementImpl(shapeTable, shapeType, differentiator, displayType, context); } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/DefaultShapeTableManager.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/DefaultShapeTableManager.cs index bb7447d5974..dc6a4987cd1 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/DefaultShapeTableManager.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/DefaultShapeTableManager.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; @@ -47,7 +48,7 @@ public DefaultShapeTableManager( _memoryCache = memoryCache; } - public ShapeTable GetShapeTable(string themeId) + public async Task GetShapeTableAsync(string themeId) { var cacheKey = $"ShapeTable:{themeId}"; @@ -76,10 +77,8 @@ public ShapeTable GetShapeTable(string themeId) BuildDescriptors(bindingStrategy, builtAlterations); } - var enabledAndOrderedFeatureIds = _shellFeaturesManager - .GetEnabledFeaturesAsync() - .GetAwaiter() - .GetResult() + var enabledAndOrderedFeatureIds = (await _shellFeaturesManager + .GetEnabledFeaturesAsync()) .Select(f => f.Id) .ToList(); @@ -170,4 +169,4 @@ private bool IsBaseTheme(string themeFeatureId, string themeId) .Any(f => f.Id == themeFeatureId); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/Interfaces.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/Interfaces.cs index ba0457c065d..6e5e58655a4 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/Interfaces.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/Interfaces.cs @@ -1,10 +1,11 @@ +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; namespace OrchardCore.DisplayManagement.Descriptors { public interface IShapeTableManager { - ShapeTable GetShapeTable(string themeId); + Task GetShapeTableAsync(string themeId); } public interface IShapeTableProvider diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs index 4f976b1e8c8..5862c63625c 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs @@ -72,7 +72,7 @@ public async Task ExecuteAsync(DisplayContext context) try { var theme = await _themeManager.GetThemeAsync(); - var shapeTable = _shapeTableManager.GetShapeTable(theme?.Id); + var shapeTable = await _shapeTableManager.GetShapeTableAsync(theme?.Id); // Evaluate global Shape Display Events await _shapeDisplayEvents.InvokeAsync(sde => sde.DisplayingAsync(displayContext), _logger); diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultShapeFactory.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultShapeFactory.cs index 9c663a8b5ba..f491d6420a2 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultShapeFactory.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultShapeFactory.cs @@ -49,7 +49,7 @@ private async Task GetShapeTableAsync() if (_scopedShapeTable == null) { var theme = await _themeManager.GetThemeAsync(); - _scopedShapeTable = _shapeTableManager.GetShapeTable(theme?.Id); + _scopedShapeTable = await _shapeTableManager.GetShapeTableAsync(theme?.Id); } return _scopedShapeTable; diff --git a/test/OrchardCore.Tests/DisplayManagement/Decriptors/DefaultShapeTableManagerTests.cs b/test/OrchardCore.Tests/DisplayManagement/Decriptors/DefaultShapeTableManagerTests.cs index 3a867af8b3e..47f97dbf588 100644 --- a/test/OrchardCore.Tests/DisplayManagement/Decriptors/DefaultShapeTableManagerTests.cs +++ b/test/OrchardCore.Tests/DisplayManagement/Decriptors/DefaultShapeTableManagerTests.cs @@ -323,17 +323,17 @@ public void ManagerCanBeResolved() } [Fact] - public void DefaultShapeTableIsReturnedForNullOrEmpty() + public async Task DefaultShapeTableIsReturnedForNullOrEmpty() { var manager = _serviceProvider.GetService(); - var shapeTable1 = manager.GetShapeTable(null); - var shapeTable2 = manager.GetShapeTable(string.Empty); + var shapeTable1 = await manager.GetShapeTableAsync(null); + var shapeTable2 = await manager.GetShapeTableAsync(string.Empty); Assert.NotNull(shapeTable1.Descriptors["Hello"]); Assert.NotNull(shapeTable2.Descriptors["Hello"]); } [Fact] - public void CallbackAlterationsContributeToDescriptor() + public async Task CallbackAlterationsContributeToDescriptor() { Func cb1 = x => { return Task.CompletedTask; }; Func cb2 = x => { return Task.CompletedTask; }; @@ -349,7 +349,7 @@ public void CallbackAlterationsContributeToDescriptor() var manager = _serviceProvider.GetService(); - var foo = manager.GetShapeTable(null).Descriptors["Foo"]; + var foo = (await manager.GetShapeTableAsync(null)).Descriptors["Foo"]; Assert.Same(cb1, foo.CreatingAsync.Single()); Assert.Same(cb2, foo.CreatedAsync.Single()); @@ -357,18 +357,18 @@ public void CallbackAlterationsContributeToDescriptor() Assert.Same(cb4, foo.DisplayedAsync.Single()); } [Fact] - public void DefaultPlacementIsReturnedByDefault() + public async Task DefaultPlacementIsReturnedByDefault() { var manager = _serviceProvider.GetService(); - var hello = manager.GetShapeTable(null).Descriptors["Hello"]; + var hello = (await manager.GetShapeTableAsync(null)).Descriptors["Hello"]; hello.DefaultPlacement = "Header:5"; var result = hello.Placement(null); Assert.Equal("Header:5", result.Location); } [Fact] - public void DescribedPlacementIsReturnedIfNotNull() + public async Task DescribedPlacementIsReturnedIfNotNull() { var shapeDetail = new ShapePlacementContext("Foo", "Detail", "", null); var shapeSummary = new ShapePlacementContext("Foo", "Summary", "", null); @@ -380,7 +380,7 @@ public void DescribedPlacementIsReturnedIfNotNull() .Placement(ctx => ctx.DisplayType == "Summary" ? new PlacementInfo { Location = "" } : null); var manager = _serviceProvider.GetService(); - var hello = manager.GetShapeTable(null).Descriptors["Hello1"]; + var hello = (await manager.GetShapeTableAsync(null)).Descriptors["Hello1"]; var result1 = hello.Placement(shapeDetail); var result2 = hello.Placement(shapeSummary); var result3 = hello.Placement(shapeTitle); @@ -398,7 +398,7 @@ public void DescribedPlacementIsReturnedIfNotNull() } [Fact] - public void TwoArgumentVariationDoesSameThing() + public async Task TwoArgumentVariationDoesSameThing() { var shapeDetail = new ShapePlacementContext("Foo", "Detail", "", null); var shapeSummary = new ShapePlacementContext("Foo", "Summary", "", null); @@ -410,7 +410,7 @@ public void TwoArgumentVariationDoesSameThing() .Placement(ctx => ctx.DisplayType == "Summary", new PlacementInfo { Location = "" }); var manager = _serviceProvider.GetService(); - var hello = manager.GetShapeTable(null).Descriptors["Hello2"]; + var hello = (await manager.GetShapeTableAsync(null)).Descriptors["Hello2"]; var result1 = hello.Placement(shapeDetail); var result2 = hello.Placement(shapeSummary); var result3 = hello.Placement(shapeTitle); @@ -429,7 +429,7 @@ public void TwoArgumentVariationDoesSameThing() // "Path not supported yet" [Fact] - internal void PathConstraintShouldMatch() + internal async Task PathConstraintShouldMatch() { // all path have a trailing / as per the current implementation // todo: (sebros) find a way to 'use' the current implementation in DefaultContentDisplay.BindPlacement instead of emulating it @@ -457,7 +457,7 @@ internal void PathConstraintShouldMatch() .Placement(ctx => true, new PlacementInfo { Location = "Match" }); var manager = _serviceProvider.GetService(); - var hello = manager.GetShapeTable(null).Descriptors["Hello"]; + var hello = (await manager.GetShapeTableAsync(null)).Descriptors["Hello"]; //var result = hello.Placement(new ShapePlacementContext { Path = context }); //if (match) @@ -472,33 +472,33 @@ internal void PathConstraintShouldMatch() } [Fact] - public void OnlyShapesFromTheGivenThemeAreProvided() + public async Task OnlyShapesFromTheGivenThemeAreProvided() { _serviceProvider.GetService(); var manager = _serviceProvider.GetService(); - var table = manager.GetShapeTable("Theme1"); + var table = await manager.GetShapeTableAsync("Theme1"); Assert.True(table.Descriptors.ContainsKey("Theme1Shape")); Assert.False(table.Descriptors.ContainsKey("DerivedShape")); Assert.False(table.Descriptors.ContainsKey("BaseShape")); } [Fact] - public void ShapesFromTheBaseThemeAreProvided() + public async Task ShapesFromTheBaseThemeAreProvided() { _serviceProvider.GetService(); var manager = _serviceProvider.GetService(); - var table = manager.GetShapeTable("DerivedTheme"); + var table = await manager.GetShapeTableAsync("DerivedTheme"); Assert.False(table.Descriptors.ContainsKey("Theme1Shape")); Assert.True(table.Descriptors.ContainsKey("DerivedShape")); Assert.True(table.Descriptors.ContainsKey("BaseShape")); } [Fact] - public void DerivedThemesCanOverrideBaseThemeShapeBindings() + public async Task DerivedThemesCanOverrideBaseThemeShapeBindings() { _serviceProvider.GetService(); var manager = _serviceProvider.GetService(); - var table = manager.GetShapeTable("DerivedTheme"); + var table = await manager.GetShapeTableAsync("DerivedTheme"); Assert.True(table.Bindings.ContainsKey("OverriddenShape")); Assert.Equal("DerivedTheme", table.Descriptors["OverriddenShape"].BindingSource); } @@ -508,4 +508,4 @@ public void Dispose() (_serviceProvider as IDisposable)?.Dispose(); } } -} \ No newline at end of file +} diff --git a/test/OrchardCore.Tests/Stubs/TestShapeTableManager.cs b/test/OrchardCore.Tests/Stubs/TestShapeTableManager.cs index 1e30a1df1ec..2d2ffcc93d1 100644 --- a/test/OrchardCore.Tests/Stubs/TestShapeTableManager.cs +++ b/test/OrchardCore.Tests/Stubs/TestShapeTableManager.cs @@ -20,9 +20,9 @@ public TestShapeTableManager(TestShapeTable defaultShapeTable) _defaultShapeTable = defaultShapeTable; } - public ShapeTable GetShapeTable(string themeId) + public Task GetShapeTableAsync(string themeId) { - return _defaultShapeTable; + return Task.FromResult((ShapeTable)_defaultShapeTable); } } From 6df4c96bffd699b06c9fffb7c702bda2739a2c9a Mon Sep 17 00:00:00 2001 From: jtkech Date: Thu, 18 Jul 2019 06:45:34 +0200 Subject: [PATCH 12/38] Prevents a non async call of themeManager.GetThemeAsync() --- .../ThemeViewLocationExpanderProvider.cs | 18 ++--- .../OrchardCoreBuilderExtensions.cs | 8 +-- .../Razor/RazorPage.cs | 4 +- .../Razor/RazorViewFeature.cs | 26 ++++++++ .../Razor/RazorViewResultFilter.cs | 66 +++++++++++++++++++ .../Razor/SiteViewResultFilter.cs | 36 ---------- .../Razor/ThemeLayoutViewResultFilter.cs | 35 ---------- .../RazorPages/Page.cs | 4 +- 8 files changed, 103 insertions(+), 94 deletions(-) create mode 100644 src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorViewFeature.cs create mode 100644 src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorViewResultFilter.cs delete mode 100644 src/OrchardCore/OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs delete mode 100644 src/OrchardCore/OrchardCore.DisplayManagement/Razor/ThemeLayoutViewResultFilter.cs diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/LocationExpander/ThemeViewLocationExpanderProvider.cs b/src/OrchardCore/OrchardCore.DisplayManagement/LocationExpander/ThemeViewLocationExpanderProvider.cs index f8977641109..a1911db100b 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/LocationExpander/ThemeViewLocationExpanderProvider.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/LocationExpander/ThemeViewLocationExpanderProvider.cs @@ -2,9 +2,8 @@ using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Mvc.Razor; -using Microsoft.Extensions.DependencyInjection; using OrchardCore.DisplayManagement.Extensions; -using OrchardCore.DisplayManagement.Theming; +using OrchardCore.DisplayManagement.Razor; using OrchardCore.Environment.Extensions; using OrchardCore.Mvc.LocationExpander; @@ -24,20 +23,11 @@ public ThemeViewLocationExpanderProvider(IExtensionManager extensionManager) /// public void PopulateValues(ViewLocationExpanderContext context) { - var themeManager = context - .ActionContext - .HttpContext - .RequestServices - .GetService(); + var currentTheme = context.ActionContext.HttpContext.Features.Get()?.Theme; - if (themeManager != null) + if (currentTheme != null) { - var currentTheme = themeManager.GetThemeAsync().GetAwaiter().GetResult(); - - if (currentTheme != null) - { - context.Values["Theme"] = currentTheme.Id; - } + context.Values["Theme"] = currentTheme.Id; } } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs b/src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs index ab5ecb593b1..9cba86acf35 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs @@ -41,13 +41,11 @@ public static OrchardCoreBuilder AddTheming(this OrchardCoreBuilder builder) { options.Filters.Add(typeof(ModelBinderAccessorFilter)); options.Filters.Add(typeof(NotifyFilter)); - options.Filters.Add(typeof(SiteViewResultFilter)); - options.Filters.Add(typeof(ThemeLayoutViewResultFilter)); + options.Filters.Add(typeof(RazorViewResultFilter)); }); - // Used as services when we create a fake 'ActionContext'. - services.AddScoped(); - services.AddScoped(); + // Used as a service when we create a fake 'ActionContext'. + services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorPage.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorPage.cs index 47354629d85..0c96c27b649 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorPage.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorPage.cs @@ -113,7 +113,7 @@ public dynamic ThemeLayout { if (_themeLayout == null) { - _themeLayout = Context.Items[typeof(IShape)]; + _themeLayout = Context.Features.Get()?.ThemeLayout; } return _themeLayout; @@ -354,7 +354,7 @@ public ISite Site { if (_site == null) { - _site = (ISite)Context.Items[typeof(ISite)]; + _site = Context.Features.Get()?.Site; } return _site; diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorViewFeature.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorViewFeature.cs new file mode 100644 index 00000000000..fdab7380555 --- /dev/null +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorViewFeature.cs @@ -0,0 +1,26 @@ +using OrchardCore.Environment.Extensions; +using OrchardCore.Settings; + +namespace OrchardCore.DisplayManagement.Razor +{ + /// + /// Used to capture commonly used data that can be retrieved e.g by a . + /// + public class RazorViewFeature + { + /// + /// The instance. + /// + public ISite Site { get; set; } + + /// + /// The current theme layout. + /// + public IShape ThemeLayout { get; set; } + + /// + /// The current theme. + /// + public IExtensionInfo Theme { get; set; } + } +} diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorViewResultFilter.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorViewResultFilter.cs new file mode 100644 index 00000000000..091520364bb --- /dev/null +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorViewResultFilter.cs @@ -0,0 +1,66 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.DependencyInjection; +using OrchardCore.DisplayManagement.Layout; +using OrchardCore.DisplayManagement.Theming; +using OrchardCore.Settings; + +namespace OrchardCore.DisplayManagement.Razor +{ + /// + /// Inject an instance of the theme layout in the HttpContext items such that + /// a View can reuse it when it's executed. + /// + public class RazorViewResultFilter : IAsyncViewResultFilter + { + public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) + { + await OnResultExecutionAsync(context); + await next(); + } + + // Used as a service when we create a fake 'ActionContext'. + public async Task OnResultExecutionAsync(ActionContext context) + { + var razorViewFeature = context.HttpContext.Features.Get(); + + if (razorViewFeature == null) + { + razorViewFeature = new RazorViewFeature(); + context.HttpContext.Features.Set(razorViewFeature); + } + + if (razorViewFeature.Site == null) + { + var siteService = context.HttpContext.RequestServices.GetService(); + + // siteService can be null during Setup + if (siteService != null) + { + razorViewFeature.Site = await siteService.GetSiteSettingsAsync(); + } + } + + if (razorViewFeature.ThemeLayout == null) + { + var layoutAccessor = context.HttpContext.RequestServices.GetService(); + + if (layoutAccessor != null) + { + razorViewFeature.ThemeLayout = await layoutAccessor.GetLayoutAsync(); + } + } + + if (razorViewFeature.Theme == null) + { + var themeManager = context.HttpContext.RequestServices.GetService(); + + if (themeManager != null) + { + razorViewFeature.Theme = await themeManager.GetThemeAsync(); + } + } + } + } +} diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs deleted file mode 100644 index 697b0a69d79..00000000000 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/SiteViewResultFilter.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Filters; -using Microsoft.Extensions.DependencyInjection; -using OrchardCore.Settings; - -namespace OrchardCore.DisplayManagement.Razor -{ - /// - /// Inject an instance of in the HttpContext items such that - /// a View can reuse it when it's executed. - /// - public class SiteViewResultFilter : IAsyncViewResultFilter - { - public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) - { - await OnResultExecutionAsync(context); - await next(); - } - - // Used as a service when we create a fake 'ActionContext'. - public async Task OnResultExecutionAsync(ActionContext context) - { - if (!context.HttpContext.Items.ContainsKey(typeof(ISite))) - { - var siteService = context.HttpContext.RequestServices.GetService(); - - // siteService can be null during Setup - if (siteService != null) - { - context.HttpContext.Items.Add(typeof(ISite), await siteService.GetSiteSettingsAsync()); - } - } - } - } -} diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/ThemeLayoutViewResultFilter.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/ThemeLayoutViewResultFilter.cs deleted file mode 100644 index 19fc71da831..00000000000 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/ThemeLayoutViewResultFilter.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Filters; -using Microsoft.Extensions.DependencyInjection; -using OrchardCore.DisplayManagement.Layout; - -namespace OrchardCore.DisplayManagement.Razor -{ - /// - /// Inject an instance of the theme layout in the HttpContext items such that - /// a View can reuse it when it's executed. - /// - public class ThemeLayoutViewResultFilter : IAsyncViewResultFilter - { - public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) - { - await OnResultExecutionAsync(context); - await next(); - } - - // Used as a service when we create a fake 'ActionContext'. - public async Task OnResultExecutionAsync(ActionContext context) - { - if (!context.HttpContext.Items.ContainsKey(typeof(IShape))) - { - var layoutAccessor = context.HttpContext.RequestServices.GetService(); - - if (layoutAccessor != null) - { - context.HttpContext.Items.Add(typeof(IShape), await layoutAccessor.GetLayoutAsync()); - } - } - } - } -} diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/RazorPages/Page.cs b/src/OrchardCore/OrchardCore.DisplayManagement/RazorPages/Page.cs index 5fa182f1bc4..04e3de340d2 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/RazorPages/Page.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/RazorPages/Page.cs @@ -109,7 +109,7 @@ public dynamic ThemeLayout { if (_themeLayout == null) { - _themeLayout = HttpContext.Items[typeof(IShape)]; + _themeLayout = HttpContext.Features.Get()?.ThemeLayout; } return _themeLayout; @@ -255,7 +255,7 @@ public ISite Site { if (_site == null) { - _site = (ISite)HttpContext.Items[typeof(ISite)]; + _site = HttpContext.Features.Get()?.Site; } return _site; From 496844c66a0d479c5abefb1a802e00fdcd3d0da2 Mon Sep 17 00:00:00 2001 From: jtkech Date: Thu, 18 Jul 2019 07:15:27 +0200 Subject: [PATCH 13/38] Update a comment. --- .../Razor/RazorViewResultFilter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorViewResultFilter.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorViewResultFilter.cs index 091520364bb..2c9c4eb3df9 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorViewResultFilter.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Razor/RazorViewResultFilter.cs @@ -9,8 +9,8 @@ namespace OrchardCore.DisplayManagement.Razor { /// - /// Inject an instance of the theme layout in the HttpContext items such that - /// a View can reuse it when it's executed. + /// Inject commonly used data through an HttpContext feature such that + /// e.g a can reuse them when it's executed. /// public class RazorViewResultFilter : IAsyncViewResultFilter { From 7cdbe287b8a1662960ac16a0e2b12da4cb71940e Mon Sep 17 00:00:00 2001 From: jtkech Date: Thu, 18 Jul 2019 22:25:53 +0200 Subject: [PATCH 14/38] Make some tests async --- .../GraphQL/ContentItemsFieldTypeTests.cs | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/test/OrchardCore.Tests/Apis/GraphQL/ContentItemsFieldTypeTests.cs b/test/OrchardCore.Tests/Apis/GraphQL/ContentItemsFieldTypeTests.cs index 0aab96425d3..6ba52bfdcac 100644 --- a/test/OrchardCore.Tests/Apis/GraphQL/ContentItemsFieldTypeTests.cs +++ b/test/OrchardCore.Tests/Apis/GraphQL/ContentItemsFieldTypeTests.cs @@ -27,19 +27,25 @@ public class ContentItemsFieldTypeTests : IDisposable protected IStore _prefixedStore; protected string _prefix; protected string _tempFilename; + private Task _initializeTask; public ContentItemsFieldTypeTests() + { + _initializeTask = InitializeAsync(); + } + + private async Task InitializeAsync() { var connectionStringTemplate = @"Data Source={0};Cache=Shared"; _tempFilename = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - _store = StoreFactory.CreateAsync(new Configuration().UseSqLite(String.Format(connectionStringTemplate, _tempFilename))).GetAwaiter().GetResult(); + _store = await StoreFactory.CreateAsync(new Configuration().UseSqLite(String.Format(connectionStringTemplate, _tempFilename))); _prefix = "tp"; - _prefixedStore = StoreFactory.CreateAsync(new Configuration().UseSqLite(String.Format(connectionStringTemplate, _tempFilename + _prefix)).SetTablePrefix(_prefix + "_")).GetAwaiter().GetResult(); + _prefixedStore = await StoreFactory.CreateAsync(new Configuration().UseSqLite(String.Format(connectionStringTemplate, _tempFilename + _prefix)).SetTablePrefix(_prefix + "_")); - CreateTables(_store); - CreateTables(_prefixedStore); + await CreateTablesAsync(_store); + await CreateTablesAsync(_prefixedStore); } public void Dispose() @@ -63,11 +69,11 @@ public void Dispose() } } - private void CreateTables(IStore store) + private async Task CreateTablesAsync(IStore store) { using (var session = store.CreateSession()) { - var builder = new SchemaBuilder(store.Configuration, session.DemandAsync().GetAwaiter().GetResult()); + var builder = new SchemaBuilder(store.Configuration, await session.DemandAsync()); builder.CreateMapIndexTable(nameof(ContentItemIndex), table => table .Column("ContentItemId", c => c.WithLength(26)) @@ -96,10 +102,10 @@ private void CreateTables(IStore store) store.RegisterIndexes(); } - [Fact] public async Task ShouldFilterByContentItemIndex() { + await _initializeTask; _store.RegisterIndexes(); using (var services = new FakeServiceCollection()) @@ -146,6 +152,7 @@ public async Task ShouldFilterByContentItemIndex() [Fact] public async Task ShouldFilterByContentItemIndexWhenSqlTablePrefixIsUsed() { + await _initializeTask; _prefixedStore.RegisterIndexes(); using (var services = new FakeServiceCollection()) @@ -197,6 +204,7 @@ public async Task ShouldFilterByContentItemIndexWhenSqlTablePrefixIsUsed() [Fact] public async Task ShouldBeAbleToUseTheSameIndexForMultipleAliases() { + await _initializeTask; _store.RegisterIndexes(); using (var services = new FakeServiceCollection()) @@ -249,6 +257,7 @@ public async Task ShouldBeAbleToUseTheSameIndexForMultipleAliases() [Fact] public async Task ShouldFilterOnMultipleIndexesOnSameAlias() { + await _initializeTask; _store.RegisterIndexes(); _store.RegisterIndexes(); @@ -307,6 +316,7 @@ public async Task ShouldFilterOnMultipleIndexesOnSameAlias() [Fact] public async Task ShouldFilterPartsWithoutAPrefixWhenThePartHasNoPrefix() { + await _initializeTask; _store.RegisterIndexes(); using (var services = new FakeServiceCollection()) @@ -356,6 +366,7 @@ public async Task ShouldFilterPartsWithoutAPrefixWhenThePartHasNoPrefix() [Fact] public async Task ShouldFilterByCollapsedWhereInputForCollapsedParts() { + await _initializeTask; _store.RegisterIndexes(); using (var services = new FakeServiceCollection()) From a6b1fc21c71767e37ee39f65366b763e28050d36 Mon Sep 17 00:00:00 2001 From: jtkech Date: Fri, 19 Jul 2019 05:32:17 +0200 Subject: [PATCH 15/38] More async --- .../Media/MediaShapes.cs | 5 +- .../OrchardCore.Contents/Shapes.cs | 6 +- .../Shapes/DemoShapeProvider.cs | 9 +- .../Widgets/Services/LiquidShapes.cs | 3 +- .../OrchardCore.Html/Media/MediaShapes.cs | 5 +- .../Services/LiquidShapes.cs | 3 +- .../OrchardCore.Markdown/Media/MediaShapes.cs | 5 +- .../OrchardCore.Menu/MenuShapes.cs | 7 +- .../NavigationShapes.cs | 5 +- .../OrchardCore.Navigation/PagerShapes.cs | 53 ++-- .../Descriptors/DefaultShapeTableManager.cs | 6 +- .../Descriptors/Interfaces.cs | 4 +- .../ShapeAttributeBindingStrategy.cs | 18 +- .../ShapePlacementParsingStrategy.cs | 13 +- .../ShapeTemplateBindingStrategy.cs | 12 +- .../Layout/LayoutShapes.cs | 6 +- .../Shapes/CoreShapes.cs | 236 +++++++++--------- .../DefaultShapeTableManagerTests.cs | 4 +- 18 files changed, 215 insertions(+), 185 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.ContentFields/Media/MediaShapes.cs b/src/OrchardCore.Modules/OrchardCore.ContentFields/Media/MediaShapes.cs index 98151cb0b99..c788232a253 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentFields/Media/MediaShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentFields/Media/MediaShapes.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using OrchardCore.DisplayManagement; using OrchardCore.DisplayManagement.Descriptors; @@ -5,7 +6,7 @@ namespace OrchardCore.ContentFields.Media { public class MediaShapes : IShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public Task DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("HtmlField_Edit") .OnDisplaying(displaying => @@ -17,6 +18,8 @@ public void Discover(ShapeTableBuilder builder) editor.Metadata.Wrappers.Add("Media_Wrapper__HtmlField"); } }); + + return Task.CompletedTask; } } } diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Shapes.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Shapes.cs index 41d9efabf56..83e847a1d4c 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Shapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Shapes.cs @@ -1,8 +1,8 @@ using System; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Display; -using OrchardCore.DisplayManagement; using OrchardCore.DisplayManagement.Descriptors; using OrchardCore.DisplayManagement.ModelBinding; @@ -10,7 +10,7 @@ namespace OrchardCore.Contents { public class Shapes : IShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public Task DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("Content") .OnDisplaying(displaying => @@ -78,6 +78,8 @@ public void Discover(ShapeTableBuilder builder) content.Add(displayShape); }); + + return Task.CompletedTask; } /// diff --git a/src/OrchardCore.Modules/OrchardCore.Demo/Shapes/DemoShapeProvider.cs b/src/OrchardCore.Modules/OrchardCore.Demo/Shapes/DemoShapeProvider.cs index 0174b70cd8c..66db075f2be 100644 --- a/src/OrchardCore.Modules/OrchardCore.Demo/Shapes/DemoShapeProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.Demo/Shapes/DemoShapeProvider.cs @@ -1,16 +1,19 @@ -using Microsoft.AspNetCore.Html; using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Html; namespace OrchardCore.DisplayManagement.Descriptors { public class DemoShapeProvider : IShapeTableProvider, IShapeAttributeProvider { - public void Discover(ShapeTableBuilder builder) + public Task DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("Foo") .OnDisplaying(displaying => displaying.ChildContent = new HtmlString("

Hi

") ); + + return Task.CompletedTask; } [Shape] @@ -25,4 +28,4 @@ public IHtmlContent Baz(string text, int count) return new HtmlString(sb.ToString()); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Facebook/Widgets/Services/LiquidShapes.cs b/src/OrchardCore.Modules/OrchardCore.Facebook/Widgets/Services/LiquidShapes.cs index c5fd35f07d3..385a27e2b19 100644 --- a/src/OrchardCore.Modules/OrchardCore.Facebook/Widgets/Services/LiquidShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Facebook/Widgets/Services/LiquidShapes.cs @@ -29,10 +29,11 @@ private static async Task BuildViewModelAsync(ShapeDisplayContext shapeDisplayCo model.ContentItem = part.ContentItem; } - public void Discover(ShapeTableBuilder builder) + public Task DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("FacebookPluginPart").OnProcessing(BuildViewModelAsync); builder.Describe("FacebookPluginPart_Summary").OnProcessing(BuildViewModelAsync); + return Task.CompletedTask; } } } diff --git a/src/OrchardCore.Modules/OrchardCore.Html/Media/MediaShapes.cs b/src/OrchardCore.Modules/OrchardCore.Html/Media/MediaShapes.cs index 71fdaa97ae2..13382303810 100644 --- a/src/OrchardCore.Modules/OrchardCore.Html/Media/MediaShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Html/Media/MediaShapes.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using OrchardCore.DisplayManagement; using OrchardCore.DisplayManagement.Descriptors; @@ -5,7 +6,7 @@ namespace OrchardCore.Html.Media { public class MediaShapes : IShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public Task DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("HtmlBodyPart_Edit") .OnDisplaying(displaying => @@ -17,6 +18,8 @@ public void Discover(ShapeTableBuilder builder) editor.Metadata.Wrappers.Add("Media_Wrapper__HtmlBodyPart"); } }); + + return Task.CompletedTask; } } } diff --git a/src/OrchardCore.Modules/OrchardCore.Liquid/Services/LiquidShapes.cs b/src/OrchardCore.Modules/OrchardCore.Liquid/Services/LiquidShapes.cs index 99517afa3cf..629d89909b3 100644 --- a/src/OrchardCore.Modules/OrchardCore.Liquid/Services/LiquidShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Liquid/Services/LiquidShapes.cs @@ -34,10 +34,11 @@ private static async Task BuildViewModelAsync(ShapeDisplayContext shapeDisplayCo model.ContentItem = liquidPart.ContentItem; } - public void Discover(ShapeTableBuilder builder) + public Task DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("LiquidPart").OnProcessing(BuildViewModelAsync); builder.Describe("LiquidPart_Summary").OnProcessing(BuildViewModelAsync); + return Task.CompletedTask; } } } diff --git a/src/OrchardCore.Modules/OrchardCore.Markdown/Media/MediaShapes.cs b/src/OrchardCore.Modules/OrchardCore.Markdown/Media/MediaShapes.cs index bc7b1f11767..baa58ab5cca 100644 --- a/src/OrchardCore.Modules/OrchardCore.Markdown/Media/MediaShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Markdown/Media/MediaShapes.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using OrchardCore.DisplayManagement; using OrchardCore.DisplayManagement.Descriptors; @@ -5,7 +6,7 @@ namespace OrchardCore.Markdown.Media { public class MediaShapes : IShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public Task DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("MarkdownBodyPart_Edit") .OnDisplaying(displaying => @@ -28,6 +29,8 @@ public void Discover(ShapeTableBuilder builder) editor.Metadata.Wrappers.Add("Media_Wrapper__MarkdownBodyPart"); } }); + + return Task.CompletedTask; } } } diff --git a/src/OrchardCore.Modules/OrchardCore.Menu/MenuShapes.cs b/src/OrchardCore.Modules/OrchardCore.Menu/MenuShapes.cs index 6e477664cf8..72db3074f98 100644 --- a/src/OrchardCore.Modules/OrchardCore.Menu/MenuShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Menu/MenuShapes.cs @@ -1,5 +1,6 @@ using System; using System.Text; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using OrchardCore.ContentManagement; using OrchardCore.DisplayManagement; @@ -10,7 +11,7 @@ namespace OrchardCore.Menu { public class MenuShapes : IShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public Task DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("Menu") .OnProcessing(async context => @@ -60,7 +61,7 @@ public void Discover(ShapeTableBuilder builder) return; } - string differentiator = FormatName((string) menu.MenuName); + string differentiator = FormatName((string)menu.MenuName); if (!String.IsNullOrEmpty(differentiator)) { @@ -173,6 +174,8 @@ public void Discover(ShapeTableBuilder builder) menuItem.Metadata.Alternates.Add("MenuItemLink__" + differentiator + "__" + encodedContentType + "__level__" + level); } }); + + return Task.CompletedTask; } /// diff --git a/src/OrchardCore.Modules/OrchardCore.Navigation/NavigationShapes.cs b/src/OrchardCore.Modules/OrchardCore.Navigation/NavigationShapes.cs index 547de3aab6f..b755801c5d9 100644 --- a/src/OrchardCore.Modules/OrchardCore.Navigation/NavigationShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Navigation/NavigationShapes.cs @@ -4,12 +4,13 @@ using OrchardCore.DisplayManagement; using OrchardCore.DisplayManagement.Descriptors; using OrchardCore.Mvc.Utilities; +using System.Threading.Tasks; namespace OrchardCore.Navigation { public class NavigationShapes : IShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public Task DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("Navigation") .OnDisplaying(displaying => @@ -94,6 +95,8 @@ public void Discover(ShapeTableBuilder builder) menuItem.Metadata.Alternates.Add("NavigationItemLink__" + EncodeAlternateElement(menuName)); menuItem.Metadata.Alternates.Add("NavigationItemLink__" + EncodeAlternateElement(menuName) + "__level__" + level); }); + + return Task.CompletedTask; } /// diff --git a/src/OrchardCore.Modules/OrchardCore.Navigation/PagerShapes.cs b/src/OrchardCore.Modules/OrchardCore.Navigation/PagerShapes.cs index 5cfbbc61131..0fddd08b532 100644 --- a/src/OrchardCore.Modules/OrchardCore.Navigation/PagerShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Navigation/PagerShapes.cs @@ -9,8 +9,8 @@ using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Routing; using Microsoft.AspNetCore.Routing; -using Microsoft.Extensions.Localization; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Localization; using OrchardCore.DisplayManagement; using OrchardCore.DisplayManagement.Descriptors; using OrchardCore.DisplayManagement.Implementation; @@ -27,18 +27,18 @@ public PagerShapesTableProvider(IStringLocalizer localizer) public IStringLocalizer T { get; set; } - public void Discover(ShapeTableBuilder builder) + public Task DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("Pager") - .OnCreated(created => - { - dynamic pager = created.Shape; - - // Intializes the common properties of a Pager shape - // such that views can safely add values to them. - pager.ItemClasses = new List(); - pager.ItemAttributes = new Dictionary(); - }) + .OnCreated(created => + { + dynamic pager = created.Shape; + + // Intializes the common properties of a Pager shape + // such that views can safely add values to them. + pager.ItemClasses = new List(); + pager.ItemAttributes = new Dictionary(); + }) .OnDisplaying(displaying => { var pager = displaying.Shape; @@ -49,19 +49,19 @@ public void Discover(ShapeTableBuilder builder) } }); - builder.Describe("PagerSlim") - .OnCreated(created => - { + builder.Describe("PagerSlim") + .OnCreated(created => + { dynamic pager = created.Shape; - // Intializes the common properties of a Pager shape - // such that views can safely add values to them. - pager.ItemClasses = new List(); - pager.ItemAttributes = new Dictionary(); - }); + // Intializes the common properties of a Pager shape + // such that views can safely add values to them. + pager.ItemClasses = new List(); + pager.ItemAttributes = new Dictionary(); + }); - builder.Describe("Pager_Gap") + builder.Describe("Pager_Gap") .OnDisplaying(displaying => { var pager = displaying.Shape.Pager; @@ -137,6 +137,8 @@ public void Discover(ShapeTableBuilder builder) displaying.Shape.Metadata.Alternates.Add("Pager_Links__" + EncodeAlternateElement(pagerId)); } }); + + return Task.CompletedTask; } private string EncodeAlternateElement(string alternateElement) @@ -158,7 +160,7 @@ public PagerShapes(IStringLocalizer localizer) [Shape] public async Task Pager_Links(Shape Shape, dynamic DisplayAsync, dynamic New, IHtmlHelper Html, - DisplayContext DisplayContext, + DisplayContext DisplayContext, int Page, int PageSize, double TotalItemCount, @@ -239,7 +241,7 @@ bool ShowNext routeData[rd.Key] = rd.Value; } } - } + } int firstPage = Math.Max(1, Page - (numberOfPagesToShow / 2)); int lastPage = Math.Min(totalPageCount, Page + (int)(numberOfPagesToShow / 2)); @@ -282,7 +284,8 @@ bool ShowNext routeData[pageKey] = currentPage; Shape.Add(await New.Pager_CurrentPage(Value: p, RouteValues: new RouteValueDictionary(routeData), Pager: Shape)); } - else { + else + { if (p == 1) routeData.Remove(pageKey); else @@ -321,7 +324,7 @@ public Task Pager(Shape Shape, dynamic DisplayAsync) public async Task PagerSlim(dynamic Shape, dynamic DisplayAsync, dynamic New, IHtmlHelper Html, object PreviousText, object NextText, - string PreviousClass, + string PreviousClass, string NextClass) { Shape.Classes.Add("pager"); @@ -410,7 +413,7 @@ public IHtmlContent ActionLink(UrlHelper Url, Shape Shape, object Value, bool Di if (Disabled) { TagBuilder parentLiTag = (TagBuilder)((dynamic)Shape).Tag; - parentLiTag.AddCssClass("disabled"); + parentLiTag.AddCssClass("disabled"); } var RouteValues = (object)((dynamic)Shape).RouteValues; diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/DefaultShapeTableManager.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/DefaultShapeTableManager.cs index dc6a4987cd1..6d9114d8eae 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/DefaultShapeTableManager.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/DefaultShapeTableManager.cs @@ -65,13 +65,15 @@ public async Task GetShapeTableAsync(string themeId) foreach (var bindingStrategy in _bindingStrategies) { - IFeatureInfo strategyFeature = _typeFeatureProvider.GetFeatureForDependency(bindingStrategy.GetType()); + var strategyFeature = _typeFeatureProvider.GetFeatureForDependency(bindingStrategy.GetType()); if (!(bindingStrategy is IShapeTableHarvester) && excludedFeatures.Contains(strategyFeature.Id)) + { continue; + } var builder = new ShapeTableBuilder(strategyFeature, excludedFeatures); - bindingStrategy.Discover(builder); + await bindingStrategy.DiscoverAsync(builder); var builtAlterations = builder.BuildAlterations(); BuildDescriptors(bindingStrategy, builtAlterations); diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/Interfaces.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/Interfaces.cs index 6e5e58655a4..335c94d1040 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/Interfaces.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/Interfaces.cs @@ -10,7 +10,7 @@ public interface IShapeTableManager public interface IShapeTableProvider { - void Discover(ShapeTableBuilder builder); + Task DiscoverAsync(ShapeTableBuilder builder); } public interface IShapeTableHarvester : IShapeTableProvider @@ -34,4 +34,4 @@ public static IServiceCollection AddShapeAttributes(this IServiceCollection s return services; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeAttributeStrategy/ShapeAttributeBindingStrategy.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeAttributeStrategy/ShapeAttributeBindingStrategy.cs index 46585e5bb4e..71ef15611db 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeAttributeStrategy/ShapeAttributeBindingStrategy.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeAttributeStrategy/ShapeAttributeBindingStrategy.cs @@ -43,7 +43,7 @@ public ShapeAttributeBindingStrategy( _shapeProviders = shapeProviders; } - public void Discover(ShapeTableBuilder builder) + public Task DiscoverAsync(ShapeTableBuilder builder) { var shapeAttributeOccurrences = new List(); @@ -75,6 +75,8 @@ public void Discover(ShapeTableBuilder builder) occurrence.MethodInfo.DeclaringType.FullName + "::" + occurrence.MethodInfo.Name, descriptor => CreateDelegate(occurrence, descriptor)); } + + return Task.CompletedTask; } [DebuggerStepThrough] @@ -82,12 +84,12 @@ private Func> CreateDelegate( ShapeAttributeOccurrence attributeOccurrence, ShapeDescriptor descriptor) { - return context => - { - var serviceInstance = context.ServiceProvider.GetService(attributeOccurrence.ServiceType); - // oversimplification for the sake of evolving - return PerformInvokeAsync(context, attributeOccurrence.MethodInfo, serviceInstance); - }; + return context => + { + var serviceInstance = context.ServiceProvider.GetService(attributeOccurrence.ServiceType); + // oversimplification for the sake of evolving + return PerformInvokeAsync(context, attributeOccurrence.MethodInfo, serviceInstance); + }; } private static Task PerformInvokeAsync(DisplayContext displayContext, MethodInfo methodInfo, object serviceInstance) @@ -231,4 +233,4 @@ private static IHtmlHelper MakeHtmlHelper(ViewContext viewContext, ViewDataDicti return newHelper; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs index efa0f89ffe7..095486fb2b6 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs @@ -2,8 +2,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OrchardCore.DisplayManagement.Shapes; @@ -20,24 +20,21 @@ public class ShapePlacementParsingStrategy : IShapeTableHarvester { private readonly IHostingEnvironment _hostingEnviroment; private readonly IShellFeaturesManager _shellFeaturesManager; - private readonly ILogger _logger; private readonly IEnumerable _placementParseMatchProviders; public ShapePlacementParsingStrategy( IHostingEnvironment hostingEnviroment, IShellFeaturesManager shellFeaturesManager, - ILogger logger, IEnumerable placementParseMatchProviders) { - _logger = logger; _hostingEnviroment = hostingEnviroment; _shellFeaturesManager = shellFeaturesManager; _placementParseMatchProviders = placementParseMatchProviders; } - public void Discover(ShapeTableBuilder builder) + public async Task DiscoverAsync(ShapeTableBuilder builder) { - var enabledFeatures = _shellFeaturesManager.GetEnabledFeaturesAsync().GetAwaiter().GetResult() + var enabledFeatures = (await _shellFeaturesManager.GetEnabledFeaturesAsync()) .Where(Feature => !builder.ExcludedFeatureIds.Contains(Feature.Id)); foreach (var featureDescriptor in enabledFeatures) @@ -81,7 +78,7 @@ private void ProcessPlacementFile(ShapeTableBuilder builder, IFeatureInfo featur var matches = filter.Filters.ToList(); Func predicate = ctx => CheckFilter(ctx, filter); - + if (matches.Any()) { predicate = matches.Aggregate(predicate, BuildPredicate); @@ -146,4 +143,4 @@ public static Func BuildPredicate(Func _harvesters; private readonly IEnumerable _shapeTemplateViewEngines; private readonly IShapeTemplateFileProviderAccessor _fileProviderAccessor; @@ -27,7 +27,6 @@ public class ShapeTemplateBindingStrategy : IShapeTableHarvester new Dictionary(StringComparer.OrdinalIgnoreCase); public ShapeTemplateBindingStrategy( - ShellSettings shellSettings, IEnumerable harvesters, IShellFeaturesManager shellFeaturesManager, IEnumerable shapeTemplateViewEngines, @@ -35,7 +34,6 @@ public ShapeTemplateBindingStrategy( IShapeTemplateFileProviderAccessor fileProviderAccessor, ILogger logger) { - _shellName = shellSettings.Name; _harvesters = harvesters; _shellFeaturesManager = shellFeaturesManager; _shapeTemplateViewEngines = shapeTemplateViewEngines; @@ -51,7 +49,7 @@ private static IEnumerable Once(IEnumerable featur return featureDescriptors.Select(x => x.Extension).Where(ed => once.TryAdd(ed.Id, null)).ToList(); } - public void Discover(ShapeTableBuilder builder) + public async Task DiscoverAsync(ShapeTableBuilder builder) { if (_logger.IsEnabled(LogLevel.Information)) { @@ -62,7 +60,7 @@ public void Discover(ShapeTableBuilder builder) .Select(harvester => new { harvester, subPaths = harvester.SubPaths() }) .ToList(); - var enabledFeatures = _shellFeaturesManager.GetEnabledFeaturesAsync().GetAwaiter().GetResult() + var enabledFeatures = (await _shellFeaturesManager.GetEnabledFeaturesAsync()) .Where(Feature => !builder.ExcludedFeatureIds.Contains(Feature.Id)).ToList(); var activeExtensions = Once(enabledFeatures); @@ -91,7 +89,7 @@ public void Discover(ShapeTableBuilder builder) var pathContexts = harvesterInfos.SelectMany(harvesterInfo => harvesterInfo.subPaths.Select(subPath => { var filePaths = _fileProviderAccessor.FileProvider.GetViewFilePaths( - PathExtensions.Combine(extensionDescriptor.SubPath, subPath), + PathExtensions.Combine(extensionDescriptor.SubPath, subPath), _viewEnginesByExtension.Keys.ToArray(), inViewsFolder: true, inDepth: false).ToArray(); @@ -168,4 +166,4 @@ public void Discover(ShapeTableBuilder builder) } } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Layout/LayoutShapes.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Layout/LayoutShapes.cs index 190cd78842b..89c74600c1e 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Layout/LayoutShapes.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Layout/LayoutShapes.cs @@ -5,7 +5,7 @@ namespace OrchardCore.DisplayManagement.Zones { public class LayoutShapes : IShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public Task DiscoverAsync(ShapeTableBuilder builder) { builder .Describe("Layout") @@ -23,6 +23,8 @@ public void Discover(ShapeTableBuilder builder) layout.Content = await created.ShapeFactory.CreateAsync("Zone", new { ZoneName = "Content" }); }); + + return Task.CompletedTask; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Shapes/CoreShapes.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Shapes/CoreShapes.cs index 406b5141266..92b06184d10 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Shapes/CoreShapes.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Shapes/CoreShapes.cs @@ -9,121 +9,123 @@ namespace OrchardCore.DisplayManagement.Shapes { - public class CoreShapes : IShapeAttributeProvider - { - [Shape] - public void PlaceChildContent(dynamic Source, TextWriter Output) - { - throw new NotImplementedException(); - } - - [Shape] - public async Task List( - dynamic DisplayAsync, - IEnumerable Items, - string Tag, - string Id, - IEnumerable Classes, - IDictionary Attributes, - string ItemTag, - IEnumerable ItemClasses, - IDictionary ItemAttributes, - string FirstClass, - string LastClass) - { - - if (Items == null) - { - return HtmlString.Empty; - } - - // prevent multiple enumerations - var items = Items.ToList(); - - // var itemDisplayOutputs = Items.Select(item => Display(item)).Where(output => !string.IsNullOrWhiteSpace(output.ToHtmlString())).ToList(); - var count = items.Count(); - if (count < 1) - { - return HtmlString.Empty; - } - - string listTagName = null; - - if (Tag != "-") - { - listTagName = string.IsNullOrEmpty(Tag) ? "ul" : Tag; - } - - var listTag = String.IsNullOrEmpty(listTagName) ? null : Shape.GetTagBuilder(listTagName, Id, Classes, Attributes); - - string itemTagName = null; - if (ItemTag != "-") - { - itemTagName = string.IsNullOrEmpty(ItemTag) ? "li" : ItemTag; - } - - - var index = 0; - foreach (var item in items) - { - var itemTag = String.IsNullOrEmpty(itemTagName) ? null : Shape.GetTagBuilder(itemTagName, null, ItemClasses, ItemAttributes); - - if (index == 0) - { - itemTag.AddCssClass(FirstClass ?? "first"); - } - - if (index == count - 1) - { - itemTag.AddCssClass(LastClass ?? "last"); - } - - if (item is IShape) - { - item.Tag = itemTag; - } - - // Give the item shape the possibility to alter its container tag - // by rendering them before rendering the containing list. - var itemContent = await DisplayAsync(item); - - itemTag.InnerHtml.AppendHtml(itemContent); - listTag.InnerHtml.AppendHtml(itemTag); - - ++index; - } - - return listTag; - } - - [Shape] - public IHtmlContent Message(dynamic Shape) - { - TagBuilder tagBuilder = OrchardCore.DisplayManagement.Shapes.Shape.GetTagBuilder(Shape, "div"); - string type = Shape.Type.ToString().ToLowerInvariant(); - IHtmlContent message = Shape.Message; - tagBuilder.AddCssClass("message"); - tagBuilder.AddCssClass("message-" + type); - tagBuilder.Attributes["role"] = "alert"; - tagBuilder.InnerHtml.AppendHtml(message); - return tagBuilder; - } - } - - public class CoreShapesTableProvider : IShapeTableProvider - { - public void Discover(ShapeTableBuilder builder) - { - builder.Describe("List") - .OnCreated(created => - { - dynamic list = created.Shape; - - // Intializes the common properties of a List shape - // such that views can safely add values to them. - list.ItemClasses = new List(); - list.ItemAttributes = new Dictionary(); - }); - } - } + public class CoreShapes : IShapeAttributeProvider + { + [Shape] + public void PlaceChildContent(dynamic Source, TextWriter Output) + { + throw new NotImplementedException(); + } + + [Shape] + public async Task List( + dynamic DisplayAsync, + IEnumerable Items, + string Tag, + string Id, + IEnumerable Classes, + IDictionary Attributes, + string ItemTag, + IEnumerable ItemClasses, + IDictionary ItemAttributes, + string FirstClass, + string LastClass) + { + + if (Items == null) + { + return HtmlString.Empty; + } + + // prevent multiple enumerations + var items = Items.ToList(); + + // var itemDisplayOutputs = Items.Select(item => Display(item)).Where(output => !string.IsNullOrWhiteSpace(output.ToHtmlString())).ToList(); + var count = items.Count(); + if (count < 1) + { + return HtmlString.Empty; + } + + string listTagName = null; + + if (Tag != "-") + { + listTagName = string.IsNullOrEmpty(Tag) ? "ul" : Tag; + } + + var listTag = String.IsNullOrEmpty(listTagName) ? null : Shape.GetTagBuilder(listTagName, Id, Classes, Attributes); + + string itemTagName = null; + if (ItemTag != "-") + { + itemTagName = string.IsNullOrEmpty(ItemTag) ? "li" : ItemTag; + } + + + var index = 0; + foreach (var item in items) + { + var itemTag = String.IsNullOrEmpty(itemTagName) ? null : Shape.GetTagBuilder(itemTagName, null, ItemClasses, ItemAttributes); + + if (index == 0) + { + itemTag.AddCssClass(FirstClass ?? "first"); + } + + if (index == count - 1) + { + itemTag.AddCssClass(LastClass ?? "last"); + } + + if (item is IShape) + { + item.Tag = itemTag; + } + + // Give the item shape the possibility to alter its container tag + // by rendering them before rendering the containing list. + var itemContent = await DisplayAsync(item); + + itemTag.InnerHtml.AppendHtml(itemContent); + listTag.InnerHtml.AppendHtml(itemTag); + + ++index; + } + + return listTag; + } + + [Shape] + public IHtmlContent Message(dynamic Shape) + { + TagBuilder tagBuilder = OrchardCore.DisplayManagement.Shapes.Shape.GetTagBuilder(Shape, "div"); + string type = Shape.Type.ToString().ToLowerInvariant(); + IHtmlContent message = Shape.Message; + tagBuilder.AddCssClass("message"); + tagBuilder.AddCssClass("message-" + type); + tagBuilder.Attributes["role"] = "alert"; + tagBuilder.InnerHtml.AppendHtml(message); + return tagBuilder; + } + } + + public class CoreShapesTableProvider : IShapeTableProvider + { + public Task DiscoverAsync(ShapeTableBuilder builder) + { + builder.Describe("List") + .OnCreated(created => + { + dynamic list = created.Shape; + + // Intializes the common properties of a List shape + // such that views can safely add values to them. + list.ItemClasses = new List(); + list.ItemAttributes = new Dictionary(); + }); + + return Task.CompletedTask; + } + } } diff --git a/test/OrchardCore.Tests/DisplayManagement/Decriptors/DefaultShapeTableManagerTests.cs b/test/OrchardCore.Tests/DisplayManagement/Decriptors/DefaultShapeTableManagerTests.cs index 47f97dbf588..60619672164 100644 --- a/test/OrchardCore.Tests/DisplayManagement/Decriptors/DefaultShapeTableManagerTests.cs +++ b/test/OrchardCore.Tests/DisplayManagement/Decriptors/DefaultShapeTableManagerTests.cs @@ -301,7 +301,7 @@ public class TestShapeProvider : IShapeTableProvider public Action Discover = x => { }; - void IShapeTableProvider.Discover(ShapeTableBuilder builder) + Task IShapeTableProvider.DiscoverAsync(ShapeTableBuilder builder) { foreach (var pair in FeatureShapes) { @@ -312,6 +312,8 @@ void IShapeTableProvider.Discover(ShapeTableBuilder builder) } Discover(builder); + + return Task.CompletedTask; } } From bd30207c01aac02cb18f3f2afa9605b2d5b8aefb Mon Sep 17 00:00:00 2001 From: jtkech Date: Fri, 19 Jul 2019 07:08:40 +0200 Subject: [PATCH 16/38] More async calls --- .../Controllers/FeedController.cs | 10 ++++- .../OrchardCore.Lists/Feeds/ListFeedQuery.cs | 6 +-- .../Services/TemplatesShapeBindingResolver.cs | 26 +++++------ .../IShapeBindingResolver.cs | 5 ++- .../Implementation/DefaultHtmlDisplay.cs | 43 ++++++++++--------- .../IFeedQuery.cs | 2 +- .../IFeedQueryProvider.cs | 7 +-- .../NavigationManager.cs | 8 ++-- 8 files changed, 60 insertions(+), 47 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Feeds/Controllers/FeedController.cs b/src/OrchardCore.Modules/OrchardCore.Feeds/Controllers/FeedController.cs index a1855021c80..6ee19e7f460 100644 --- a/src/OrchardCore.Modules/OrchardCore.Feeds/Controllers/FeedController.cs +++ b/src/OrchardCore.Modules/OrchardCore.Feeds/Controllers/FeedController.cs @@ -49,8 +49,14 @@ public async Task Index(string format) context.Builder = bestFormatterMatch.FeedBuilder; - var bestQueryMatch = _feedQueryProviders - .Select(provider => provider.Match(context)) + var queryMatches = new List(); + + foreach (var provider in _feedQueryProviders) + { + queryMatches.Add(await provider.MatchAsync(context)); + } + + var bestQueryMatch = queryMatches .Where(match => match != null && match.FeedQuery != null) .OrderByDescending(match => match.Priority) .FirstOrDefault(); diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/Feeds/ListFeedQuery.cs b/src/OrchardCore.Modules/OrchardCore.Lists/Feeds/ListFeedQuery.cs index 7fe21ffa3b5..96749723928 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/Feeds/ListFeedQuery.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/Feeds/ListFeedQuery.cs @@ -28,11 +28,11 @@ public ListFeedQuery(IContentManager contentManager, ISession session) _session = session; } - public FeedQueryMatch Match(FeedContext context) + public async Task MatchAsync(FeedContext context) { var model = new ListFeedQueryViewModel(); - if (!context.Updater.TryUpdateModelAsync(model).GetAwaiter().GetResult() || model.ContentItemId == null) + if (!await context.Updater.TryUpdateModelAsync(model) || model.ContentItemId == null) { return null; } @@ -110,4 +110,4 @@ public async Task ExecuteAsync(FeedContext context) } } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Templates/Services/TemplatesShapeBindingResolver.cs b/src/OrchardCore.Modules/OrchardCore.Templates/Services/TemplatesShapeBindingResolver.cs index aadbd210ecf..a8fa4f3f151 100644 --- a/src/OrchardCore.Modules/OrchardCore.Templates/Services/TemplatesShapeBindingResolver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Templates/Services/TemplatesShapeBindingResolver.cs @@ -1,4 +1,5 @@ using System.Text.Encodings.Web; +using System.Threading.Tasks; using Fluid; using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Http; @@ -13,7 +14,8 @@ namespace OrchardCore.Templates.Services { public class TemplatesShapeBindingResolver : IShapeBindingResolver { - private readonly TemplatesDocument _templatesDocument; + private TemplatesDocument _templatesDocument; + private readonly TemplatesManager _templatesManager; private readonly ILiquidTemplateManager _liquidTemplateManager; private readonly PreviewTemplatesProvider _previewTemplatesProvider; private readonly IHttpContextAccessor _httpContextAccessor; @@ -24,18 +26,17 @@ public TemplatesShapeBindingResolver( PreviewTemplatesProvider previewTemplatesProvider, IHttpContextAccessor httpContextAccessor) { - _templatesDocument = templatesManager.GetTemplatesDocumentAsync().GetAwaiter().GetResult(); + _templatesManager = templatesManager; _liquidTemplateManager = liquidTemplateManager; _previewTemplatesProvider = previewTemplatesProvider; _httpContextAccessor = httpContextAccessor; } - public bool TryGetDescriptorBinding(string shapeType, out ShapeBinding shapeBinding) + public async Task GetDescriptorBindingAsync(string shapeType) { if (AdminAttribute.IsApplied(_httpContextAccessor.HttpContext)) { - shapeBinding = null; - return false; + return null; } var localTemplates = _previewTemplatesProvider.GetTemplates(); @@ -44,21 +45,22 @@ public bool TryGetDescriptorBinding(string shapeType, out ShapeBinding shapeBind { if (localTemplates.Templates.TryGetValue(shapeType, out var localTemplate)) { - shapeBinding = BuildShapeBinding(shapeType, localTemplate); - return true; + return BuildShapeBinding(shapeType, localTemplate); } } - if (_templatesDocument.Templates.TryGetValue(shapeType, out var template)) + if (_templatesDocument == null) { - shapeBinding = BuildShapeBinding(shapeType, template); + _templatesDocument = await _templatesManager.GetTemplatesDocumentAsync(); + } - return true; + if (_templatesDocument.Templates.TryGetValue(shapeType, out var template)) + { + return BuildShapeBinding(shapeType, template); } else { - shapeBinding = null; - return false; + return null; } } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/IShapeBindingResolver.cs b/src/OrchardCore/OrchardCore.DisplayManagement/IShapeBindingResolver.cs index 85b48d0bd73..c9bd1db1f8b 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/IShapeBindingResolver.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/IShapeBindingResolver.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using OrchardCore.DisplayManagement.Descriptors; namespace OrchardCore.DisplayManagement @@ -9,6 +10,6 @@ namespace OrchardCore.DisplayManagement /// public interface IShapeBindingResolver { - bool TryGetDescriptorBinding(string shapeType, out ShapeBinding shapeBinding); + Task GetDescriptorBindingAsync(string shapeType); } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs index 5862c63625c..3b65972a53f 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs @@ -49,7 +49,7 @@ public async Task ExecuteAsync(DisplayContext context) } var shapeMetadata = shape.Metadata; - + // can't really cope with a shape that has no type information if (shapeMetadata == null || string.IsNullOrEmpty(shapeMetadata.Type)) { @@ -79,8 +79,8 @@ public async Task ExecuteAsync(DisplayContext context) // Find base shape association using only the fundamental shape type. // Alternates that may already be registered do not affect the "displaying" event calls. - ShapeBinding shapeBinding; - if (TryGetDescriptorBinding(shapeMetadata.Type, Enumerable.Empty(), shapeTable, out shapeBinding)) + var shapeBinding = await GetDescriptorBindingAsync(shapeMetadata.Type, Enumerable.Empty(), shapeTable); ; + if (shapeBinding != null) { await shapeBinding.ShapeDescriptor.DisplayingAsync.InvokeAsync(action => action(displayContext), _logger); @@ -110,8 +110,8 @@ public async Task ExecuteAsync(DisplayContext context) } // now find the actual binding to render, taking alternates into account - ShapeBinding actualBinding; - if (TryGetDescriptorBinding(shapeMetadata.Type, shapeMetadata.Alternates, shapeTable, out actualBinding)) + var actualBinding = await GetDescriptorBindingAsync(shapeMetadata.Type, shapeMetadata.Alternates, shapeTable); + if (actualBinding != null) { // invoking ShapeMetadata processing events, this includes the Drivers results await shapeMetadata.ProcessingAsync.InvokeAsync(processing => processing(displayContext.Shape), _logger); @@ -129,8 +129,8 @@ public async Task ExecuteAsync(DisplayContext context) { foreach (var frameType in shape.Metadata.Wrappers) { - ShapeBinding frameBinding; - if (TryGetDescriptorBinding(frameType, Enumerable.Empty(), shapeTable, out frameBinding)) + var frameBinding = await GetDescriptorBindingAsync(frameType, Enumerable.Empty(), shapeTable); + if (frameBinding != null) { shape.Metadata.ChildContent = await ProcessAsync(frameBinding, shape, localContext); } @@ -176,7 +176,7 @@ await shapeBinding.ShapeDescriptor.DisplayedAsync.InvokeAsync(async action => return shape.Metadata.ChildContent; } - private bool TryGetDescriptorBinding(string shapeType, IEnumerable shapeAlternates, ShapeTable shapeTable, out ShapeBinding shapeBinding) + private async Task GetDescriptorBindingAsync(string shapeType, IEnumerable shapeAlternates, ShapeTable shapeTable) { // shape alternates are optional, fully qualified binding names // the earliest added alternates have the lowest priority @@ -186,15 +186,17 @@ private bool TryGetDescriptorBinding(string shapeType, IEnumerable shape { foreach (var shapeBindingResolver in _shapeBindingResolvers) { - if (shapeBindingResolver.TryGetDescriptorBinding(shapeAlternate, out shapeBinding)) + var binding = await shapeBindingResolver.GetDescriptorBindingAsync(shapeAlternate); + + if (binding != null) { - return true; + return binding; } } - if (shapeTable.Bindings.TryGetValue(shapeAlternate, out shapeBinding)) + if (shapeTable.Bindings.TryGetValue(shapeAlternate, out var shapeBinding)) { - return true; + return shapeBinding; } } @@ -202,26 +204,27 @@ private bool TryGetDescriptorBinding(string shapeType, IEnumerable shape // the shapetype name can break itself into shorter fallbacks at double-underscore marks // so the shapetype itself may contain a longer alternate forms that falls back to a shorter one var shapeTypeScan = shapeType; - for (;;) + for (; ; ) { foreach (var shapeBindingResolver in _shapeBindingResolvers) { - if (shapeBindingResolver.TryGetDescriptorBinding(shapeTypeScan, out shapeBinding)) + var binding = await shapeBindingResolver.GetDescriptorBindingAsync(shapeTypeScan); + + if (binding != null) { - return true; + return binding; } } - if (shapeTable.Bindings.TryGetValue(shapeTypeScan, out shapeBinding)) + if (shapeTable.Bindings.TryGetValue(shapeTypeScan, out var shapeBinding)) { - return true; + return shapeBinding; } var delimiterIndex = shapeTypeScan.LastIndexOf("__"); if (delimiterIndex < 0) { - shapeBinding = null; - return false; + return null; } shapeTypeScan = shapeTypeScan.Substring(0, delimiterIndex); @@ -265,4 +268,4 @@ static async Task ProcessAsync(ShapeBinding shapeBinding, IShape s return CoerceHtmlString(await shapeBinding.BindingAsync(context)); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.Feeds.Abstractions/IFeedQuery.cs b/src/OrchardCore/OrchardCore.Feeds.Abstractions/IFeedQuery.cs index 09006aab258..d6493bc6ecf 100644 --- a/src/OrchardCore/OrchardCore.Feeds.Abstractions/IFeedQuery.cs +++ b/src/OrchardCore/OrchardCore.Feeds.Abstractions/IFeedQuery.cs @@ -7,4 +7,4 @@ public interface IFeedQuery { Task ExecuteAsync(FeedContext context); } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.Feeds.Abstractions/IFeedQueryProvider.cs b/src/OrchardCore/OrchardCore.Feeds.Abstractions/IFeedQueryProvider.cs index dc338e313c9..180114247e8 100644 --- a/src/OrchardCore/OrchardCore.Feeds.Abstractions/IFeedQueryProvider.cs +++ b/src/OrchardCore/OrchardCore.Feeds.Abstractions/IFeedQueryProvider.cs @@ -1,10 +1,11 @@ -using OrchardCore.Feeds.Models; +using System.Threading.Tasks; +using OrchardCore.Feeds.Models; namespace OrchardCore.Feeds { public interface IFeedQueryProvider { - FeedQueryMatch Match(FeedContext context); + Task MatchAsync(FeedContext context); } public class FeedQueryMatch @@ -12,4 +13,4 @@ public class FeedQueryMatch public int Priority { get; set; } public IFeedQuery FeedQuery { get; set; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.Navigation.Core/NavigationManager.cs b/src/OrchardCore/OrchardCore.Navigation.Core/NavigationManager.cs index 13f96addcbe..30ebc9bf637 100644 --- a/src/OrchardCore/OrchardCore.Navigation.Core/NavigationManager.cs +++ b/src/OrchardCore/OrchardCore.Navigation.Core/NavigationManager.cs @@ -63,7 +63,7 @@ public async Task> BuildMenuAsync(string name, ActionConte Merge(menuItems); // Remove unauthorized menu items - menuItems = Authorize(menuItems, actionContext.HttpContext.User); + menuItems = await AuthorizeAsync(menuItems, actionContext.HttpContext.User); // Compute Url and RouteValues properties to Href menuItems = ComputeHref(menuItems, actionContext); @@ -234,7 +234,7 @@ private string GetUrl(string menuItemUrl, RouteValueDictionary routeValueDiction /// /// Updates the items by checking for permissions /// - private List Authorize(IEnumerable items, ClaimsPrincipal user) + private async Task> AuthorizeAsync(IEnumerable items, ClaimsPrincipal user) { var filtered = new List(); @@ -253,7 +253,7 @@ private List Authorize(IEnumerable items, ClaimsPrincipal us { foreach (var permission in item.Permissions) { - if (_authorizationService.AuthorizeAsync(user, permission, item.Resource).GetAwaiter().GetResult()) + if (await _authorizationService.AuthorizeAsync(user, permission, item.Resource)) { filtered.Add(item); } @@ -263,7 +263,7 @@ private List Authorize(IEnumerable items, ClaimsPrincipal us // Process child items var oldItems = item.Items; - item.Items = Authorize(item.Items, user).ToList(); + item.Items = (await AuthorizeAsync(item.Items, user)).ToList(); } return filtered; From 9e713e56b6a8e844e115c3e22f929c6dd6731278 Mon Sep 17 00:00:00 2001 From: jtkech Date: Sat, 20 Jul 2019 07:30:26 +0200 Subject: [PATCH 17/38] wip on more asunc calls --- .../Drivers/AliasPartDisplayDriver.cs | 24 +-- .../Handlers/AliasPartHandler.cs | 8 +- .../OrchardCore.Alias/Migrations.cs | 11 +- .../Drivers/AutoroutePartDisplay.cs | 8 +- .../Handlers/AutoroutePartHandler.cs | 6 +- .../OrchardCore.Autoroute/Migrations.cs | 11 +- .../Controllers/ContentPickerController.cs | 4 +- ...ntentLocalizationPartHandlerCoordinator.cs | 4 +- .../Records/Migrations.cs | 5 +- .../Controllers/AdminController.cs | 96 ++++++------ .../DefaultContentDefinitionDisplayManager.cs | 8 +- .../RecipeSteps/ContentDefinitionStep.cs | 24 ++- .../Services/ContentDefinitionService.cs | 142 +++++++++--------- .../Services/DefaultStereotypesProvider.cs | 13 +- .../Services/IContentDefinitionService.cs | 45 +++--- .../Services/IStereotypesProvider.cs | 5 +- .../Services/StereotypeService.cs | 15 +- .../SelectContentTypesViewComponent.cs | 9 +- .../ViewModels/SelectContentTypesViewModel.cs | 11 +- .../Views/Admin/Edit.cshtml | 16 +- ...efinitionDeploymentStep.Fields.Edit.cshtml | 5 +- ...nitionDeploymentStep.Fields.Summary.cshtml | 8 +- .../OrchardCore.Contents/AdminMenu.cs | 4 +- .../AdminNodes/ContentTypesAdminNodeDriver.cs | 18 +-- .../ContentTypesAdminNodeNavigationBuilder.cs | 15 +- .../Controllers/AdminController.cs | 30 ++-- .../Drivers/ContentsDriver.cs | 9 +- .../Drivers/DateEditorDriver.cs | 20 +-- .../Drivers/OwnerEditorDriver.cs | 12 +- .../Indexing/ContentItemIndexCoordinator.cs | 4 +- .../OrchardCore.Contents/Migrations.cs | 9 +- .../Security/ContentTypePermissions.cs | 20 ++- .../TagHelpers/ContentLinkTagHelper.cs | 2 +- .../Views/Admin/Create.cshtml | 2 +- .../Views/Admin/Edit.cshtml | 2 +- .../ContentDeploymentStep.Fields.Edit.cshtml | 2 +- ...ontentDeploymentStep.Fields.Summary.cshtml | 2 +- ...ntTypesAdminNode.Fields.TreeSummary.cshtml | 2 +- .../Drivers/ContentEventDisplayDriver.cs | 12 +- .../Drivers/CreateContentTaskDisplay.cs | 6 +- .../OrchardCore.CustomSettings/AdminMenu.cs | 8 +- .../CustomSettingsDeploymentSource.cs | 6 +- .../CustomSettingsDeploymentStepDriver.cs | 6 +- .../Drivers/CustomSettingsDisplayDriver.cs | 6 +- .../OrchardCore.CustomSettings/Permissions.cs | 13 +- .../Recipes/CustomSettingsStep.cs | 4 +- .../Services/CustomSettingsService.cs | 60 +++++--- .../FacebookPluginPartDisplayDriver.cs | 30 ++-- .../Widgets/Migrations.cs | 9 +- .../Drivers/BagPartDisplay.cs | 18 ++- .../Drivers/FlowPartDisplay.cs | 2 +- .../OrchardCore.Flows/Migrations.cs | 13 +- .../Settings/BagPartSettingsDisplayDriver.cs | 8 +- .../Views/FlowPart.Edit.cshtml | 2 +- .../Views/Widget-Bag.Edit.cshtml | 2 +- .../Views/Widget-Flow.Edit.cshtml | 4 +- .../OrchardCore.Forms/Migrations.cs | 41 ++--- .../Drivers/HtmlBodyPartDisplay.cs | 2 +- .../Handlers/HtmlBodyPartHandler.cs | 5 +- .../OrchardCore.Html/Migrations.cs | 14 +- .../Views/Admin/Index.cshtml | 2 +- .../OrchardCore.Liquid/Migrations.cs | 9 +- .../AdminNodes/ListsAdminNodeDriver.cs | 10 +- .../ListsAdminNodeNavigationBuilder.cs | 2 +- .../Drivers/ListPartDisplayDriver.cs | 26 ++-- .../OrchardCore.Lists/Migrations.cs | 9 +- .../RemotePublishing/MetaWeblogHandler.cs | 24 +-- .../Services/ListPartContentAdminFilter.cs | 10 +- .../Settings/ListPartSettingsDisplayDriver.cs | 8 +- .../ListsAdminNode.Fields.TreeSummary.cshtml | 2 +- .../Drivers/MarkdownBodyPartDisplay.cs | 8 +- .../Handlers/MarkdownBodyPartHandler.cs | 5 +- .../OrchardCore.Markdown/Migrations.cs | 9 +- .../Controllers/AdminController.cs | 8 +- .../Views/Admin/Create.cshtml | 2 +- .../OrchardCore.Menu/Views/Admin/Edit.cshtml | 2 +- .../Views/MenuPart.Edit.cshtml | 2 +- .../OrchardCore.ReCaptcha/Forms/Migrations.cs | 13 +- .../Controllers/AdminController.cs | 8 +- .../Indexing/TaxonomyIndex.cs | 6 +- .../OrchardCore.Taxonomies/Migrations.cs | 5 +- .../Views/Admin/Create.cshtml | 2 +- .../Views/Admin/Edit.cshtml | 2 +- .../Views/TaxonomyPart.Edit.cshtml | 4 +- .../OrchardCore.Title/Migrations.cs | 28 ++-- .../Drivers/WidgetsListPartDisplay.cs | 8 +- .../OrchardCore.Widgets/Migrations.cs | 9 +- .../Views/Widget-List.Edit.cshtml | 4 +- .../Views/WidgetsListPart.Edit.cshtml | 2 +- .../IContentDefinitionManager.cs | 34 ++--- .../ContentItemDisplayCoordinator.cs | 6 +- .../ContentPartDisplayDriverTPart.cs | 2 +- .../ContentDisplayManager.cs | 6 +- .../Queries/ContentTypeQuery.cs | 7 +- .../ContentDefinitionManager.cs | 142 ++++++++++-------- .../DefaultContentManager.cs | 4 +- .../Handlers/ContentPartHandlerCoordinator.cs | 44 +++--- .../IDataMigration.cs | 2 +- .../Migration/AutomaticDataMigrations.cs | 2 +- .../IMediaFactorySelector.cs | 7 +- .../IMediaService.cs | 2 +- .../ImageFactory.cs | 6 +- .../MediaService.cs | 18 ++- 103 files changed, 749 insertions(+), 664 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Alias/Drivers/AliasPartDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.Alias/Drivers/AliasPartDisplayDriver.cs index bf3d6d413de..d39f3421aa5 100644 --- a/src/OrchardCore.Modules/OrchardCore.Alias/Drivers/AliasPartDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Alias/Drivers/AliasPartDisplayDriver.cs @@ -1,16 +1,16 @@ using System.Linq; using System.Threading.Tasks; +using Microsoft.Extensions.Localization; +using OrchardCore.Alias.Indexes; +using OrchardCore.Alias.Models; +using OrchardCore.Alias.Settings; +using OrchardCore.Alias.ViewModels; using OrchardCore.ContentManagement.Display.ContentDisplay; using OrchardCore.ContentManagement.Metadata; using OrchardCore.DisplayManagement.ModelBinding; using OrchardCore.DisplayManagement.Views; -using OrchardCore.Alias.Models; -using OrchardCore.Alias.Settings; -using OrchardCore.Alias.ViewModels; -using YesSql; -using OrchardCore.Alias.Indexes; -using Microsoft.Extensions.Localization; using OrchardCore.Mvc.ModelBinding; +using YesSql; namespace OrchardCore.Alias.Drivers { @@ -32,12 +32,12 @@ public AliasPartDisplayDriver( public override IDisplayResult Edit(AliasPart aliasPart) { - return Initialize("AliasPart_Edit", m => BuildViewModel(m, aliasPart)); + return Initialize("AliasPart_Edit", m => BuildViewModelAsync(m, aliasPart)); } public override async Task UpdateAsync(AliasPart model, IUpdateModel updater) { - var settings = GetAliasPartSettings(model); + var settings = await GetAliasPartSettingsAsync(model); await updater.TryUpdateModelAsync(model, Prefix, t => t.Alias); @@ -46,18 +46,18 @@ public override async Task UpdateAsync(AliasPart model, IUpdateM return Edit(model); } - public AliasPartSettings GetAliasPartSettings(AliasPart part) + public async Task GetAliasPartSettingsAsync(AliasPart part) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(p => p.PartDefinition.Name == nameof(AliasPart)); var settings = contentTypePartDefinition.GetSettings(); return settings; } - private void BuildViewModel(AliasPartViewModel model, AliasPart part) + private async Task BuildViewModelAsync(AliasPartViewModel model, AliasPart part) { - var settings = GetAliasPartSettings(part); + var settings = await GetAliasPartSettingsAsync(part); model.Alias = part.Alias; model.AliasPart = part; diff --git a/src/OrchardCore.Modules/OrchardCore.Alias/Handlers/AliasPartHandler.cs b/src/OrchardCore.Modules/OrchardCore.Alias/Handlers/AliasPartHandler.cs index e3b6d1afd6a..30424109f8b 100644 --- a/src/OrchardCore.Modules/OrchardCore.Alias/Handlers/AliasPartHandler.cs +++ b/src/OrchardCore.Modules/OrchardCore.Alias/Handlers/AliasPartHandler.cs @@ -45,7 +45,7 @@ public async override Task UpdatedAsync(UpdateContentContext context, AliasPart return; } - var pattern = GetPattern(part); + var pattern = await GetPatternAsync(part); if (!String.IsNullOrEmpty(pattern)) { @@ -60,9 +60,9 @@ public async override Task UpdatedAsync(UpdateContentContext context, AliasPart /// /// Get the pattern from the AutoroutePartSettings property for its type /// - private string GetPattern(AliasPart part) + private async Task GetPatternAsync(AliasPart part) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => String.Equals(x.PartDefinition.Name, "AliasPart", StringComparison.Ordinal)); var pattern = contentTypePartDefinition.GetSettings().Pattern; @@ -92,7 +92,7 @@ public override async Task CloningAsync(CloneContentContext context, AliasPart p clonedPart.Apply(); } - + private async Task GenerateUniqueAliasAsync(string alias, AliasPart context) { var version = 1; diff --git a/src/OrchardCore.Modules/OrchardCore.Alias/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Alias/Migrations.cs index 57d7988e4b6..bf86bef48d3 100644 --- a/src/OrchardCore.Modules/OrchardCore.Alias/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Alias/Migrations.cs @@ -1,8 +1,9 @@ -using OrchardCore.ContentManagement.Metadata.Settings; -using OrchardCore.ContentManagement.Metadata; -using OrchardCore.Data.Migration; +using System.Threading.Tasks; using OrchardCore.Alias.Indexes; using OrchardCore.Alias.Models; +using OrchardCore.ContentManagement.Metadata; +using OrchardCore.ContentManagement.Metadata.Settings; +using OrchardCore.Data.Migration; namespace OrchardCore.Alias { @@ -15,9 +16,9 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public int Create() + public async Task CreateAsync() { - _contentDefinitionManager.AlterPartDefinition(nameof(AliasPart), builder => builder + await _contentDefinitionManager.AlterPartDefinitionAsync(nameof(AliasPart), builder => builder .Attachable() .WithDescription("Provides a way to define custom aliases for content items.")); diff --git a/src/OrchardCore.Modules/OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs b/src/OrchardCore.Modules/OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs index 5b27096e147..f456b78c8e7 100644 --- a/src/OrchardCore.Modules/OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs +++ b/src/OrchardCore.Modules/OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs @@ -68,13 +68,13 @@ public override IDisplayResult Edit(AutoroutePart autoroutePart) model.IsHomepage = true; } - model.Settings = GetSettings(autoroutePart); + model.Settings = await GetSettingsAsync(autoroutePart); }); } - private AutoroutePartSettings GetSettings(AutoroutePart autoroutePart) + private async Task GetSettingsAsync(AutoroutePart autoroutePart) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(autoroutePart.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(autoroutePart.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => String.Equals(x.PartDefinition.Name, nameof(AutoroutePart), StringComparison.Ordinal)); return contentTypePartDefinition.Settings.ToObject(); } @@ -85,7 +85,7 @@ public override async Task UpdateAsync(AutoroutePart model, IUpd await updater.TryUpdateModelAsync(viewModel, Prefix, t => t.Path, t => t.UpdatePath); - var settings = GetSettings(model); + var settings = await GetSettingsAsync(model); if (settings.AllowCustomPath) { diff --git a/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs b/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs index f70009bacf9..2e927ec6ce9 100644 --- a/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs +++ b/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs @@ -114,7 +114,7 @@ public override async Task UpdatedAsync(UpdateContentContext context, AutorouteP return; } - var pattern = GetPattern(part); + var pattern = await GetPatternAsync(part); if (!String.IsNullOrEmpty(pattern)) { @@ -149,9 +149,9 @@ private Task RemoveTagAsync(AutoroutePart part) /// /// Get the pattern from the AutoroutePartSettings property for its type /// - private string GetPattern(AutoroutePart part) + private async Task GetPatternAsync(AutoroutePart part) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => String.Equals(x.PartDefinition.Name, "AutoroutePart", StringComparison.Ordinal)); var pattern = contentTypePartDefinition.Settings.ToObject().Pattern; diff --git a/src/OrchardCore.Modules/OrchardCore.Autoroute/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Autoroute/Migrations.cs index f1d618ca5ba..6e0821e8e8a 100644 --- a/src/OrchardCore.Modules/OrchardCore.Autoroute/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Autoroute/Migrations.cs @@ -1,6 +1,7 @@ -using OrchardCore.Autoroute.Drivers; -using OrchardCore.ContentManagement.Metadata.Settings; +using System.Threading.Tasks; +using OrchardCore.Autoroute.Drivers; using OrchardCore.ContentManagement.Metadata; +using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.ContentManagement.Records; using OrchardCore.Data.Migration; @@ -15,9 +16,9 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public int Create() + public async Task CreateAsync() { - _contentDefinitionManager.AlterPartDefinition("AutoroutePart", builder => builder + await _contentDefinitionManager.AlterPartDefinitionAsync("AutoroutePart", builder => builder .Attachable() .WithDescription("Provides a custom url for your content item.")); @@ -34,4 +35,4 @@ public int Create() return 1; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.ContentFields/Controllers/ContentPickerController.cs b/src/OrchardCore.Modules/OrchardCore.ContentFields/Controllers/ContentPickerController.cs index 8b4d89dfad3..fcfed974f61 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentFields/Controllers/ContentPickerController.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentFields/Controllers/ContentPickerController.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; using System.Linq; -using OrchardCore.Admin; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using OrchardCore.Admin; using OrchardCore.ContentFields.Settings; using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Metadata; @@ -32,7 +32,7 @@ public async Task List(string part, string field, string query) return BadRequest("Part and field are required parameters"); } - var partFieldDefinition = _contentDefinitionManager.GetPartDefinition(part)?.Fields + var partFieldDefinition = (await _contentDefinitionManager.GetPartDefinitionAsync(part))?.Fields .FirstOrDefault(f => f.Name == field); var fieldSettings = partFieldDefinition?.Settings.ToObject(); diff --git a/src/OrchardCore.Modules/OrchardCore.ContentLocalization/Handlers/ContentLocalizationPartHandlerCoordinator.cs b/src/OrchardCore.Modules/OrchardCore.ContentLocalization/Handlers/ContentLocalizationPartHandlerCoordinator.cs index 0a2cdf0808e..a66933d52c5 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentLocalization/Handlers/ContentLocalizationPartHandlerCoordinator.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentLocalization/Handlers/ContentLocalizationPartHandlerCoordinator.cs @@ -33,7 +33,7 @@ ILogger logger public override async Task LocalizingAsync(LocalizationContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -52,7 +52,7 @@ public override async Task LocalizingAsync(LocalizationContentContext context) public override async Task LocalizedAsync(LocalizationContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; diff --git a/src/OrchardCore.Modules/OrchardCore.ContentLocalization/Records/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.ContentLocalization/Records/Migrations.cs index acfb3c771e5..4d2ea46db5d 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentLocalization/Records/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentLocalization/Records/Migrations.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using OrchardCore.ContentLocalization.Models; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Settings; @@ -14,9 +15,9 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public int Create() + public async Task CreateAsync() { - _contentDefinitionManager.AlterPartDefinition(nameof(LocalizationPart), builder => builder + await _contentDefinitionManager.AlterPartDefinitionAsync(nameof(LocalizationPart), builder => builder .Attachable() .WithDescription("Provides a way to create localized version of content.")); diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Controllers/AdminController.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Controllers/AdminController.cs index f58f9724e44..b2ec348d476 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Controllers/AdminController.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Controllers/AdminController.cs @@ -72,7 +72,7 @@ public async Task List() return View("List", new ListContentTypesViewModel { - Types = _contentDefinitionService.GetTypes() + Types = await _contentDefinitionService.GetTypesAsync() }); } @@ -103,7 +103,7 @@ public async Task CreatePOST(CreateTypeViewModel viewModel) ModelState.AddModelError("Name", S["The Content Type Id can't be empty."]); } - if (_contentDefinitionService.GetTypes().Any(t => String.Equals(t.Name.Trim(), viewModel.Name.Trim(), StringComparison.OrdinalIgnoreCase))) + if ((await _contentDefinitionService.GetTypesAsync()).Any(t => String.Equals(t.Name.Trim(), viewModel.Name.Trim(), StringComparison.OrdinalIgnoreCase))) { ModelState.AddModelError("Name", S["A type with the same Id already exists."]); } @@ -113,7 +113,7 @@ public async Task CreatePOST(CreateTypeViewModel viewModel) ModelState.AddModelError("Name", S["The technical name must start with a letter."]); } - if (_contentDefinitionService.GetTypes().Any(t => String.Equals(t.DisplayName.Trim(), viewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase))) + if ((await _contentDefinitionService.GetTypesAsync()).Any(t => String.Equals(t.DisplayName.Trim(), viewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase))) { ModelState.AddModelError("DisplayName", S["A type with the same Display Name already exists."]); } @@ -124,7 +124,7 @@ public async Task CreatePOST(CreateTypeViewModel viewModel) return View(viewModel); } - var contentTypeDefinition = _contentDefinitionService.AddType(viewModel.Name, viewModel.DisplayName); + var contentTypeDefinition = await _contentDefinitionService.AddTypeAsync(viewModel.Name, viewModel.DisplayName); var typeViewModel = new EditTypeViewModel(contentTypeDefinition); @@ -139,7 +139,7 @@ public async Task Edit(string id) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var typeViewModel = _contentDefinitionService.GetType(id); + var typeViewModel = await _contentDefinitionService.GetTypeAsync(id); if (typeViewModel == null) { @@ -158,7 +158,7 @@ public async Task EditPOST(string id, EditTypeViewModel viewModel) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(id); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(id); if (contentTypeDefinition == null) { @@ -178,12 +178,12 @@ public async Task EditPOST(string id, EditTypeViewModel viewModel) } else { - var ownedPartDefinition = _contentDefinitionManager.GetPartDefinition(contentTypeDefinition.Name); + var ownedPartDefinition = await _contentDefinitionManager.GetPartDefinitionAsync(contentTypeDefinition.Name); if (ownedPartDefinition != null && viewModel.OrderedFieldNames != null) { - _contentDefinitionService.AlterPartFieldsOrder(ownedPartDefinition, viewModel.OrderedFieldNames); + await _contentDefinitionService.AlterPartFieldsOrderAsync(ownedPartDefinition, viewModel.OrderedFieldNames); } - _contentDefinitionService.AlterTypePartsOrder(contentTypeDefinition, viewModel.OrderedPartNames); + await _contentDefinitionService.AlterTypePartsOrderAsync(contentTypeDefinition, viewModel.OrderedPartNames); _notifier.Success(T["\"{0}\" settings have been saved.", contentTypeDefinition.Name]); } @@ -197,12 +197,12 @@ public async Task Delete(string id) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var typeViewModel = _contentDefinitionService.GetType(id); + var typeViewModel = await _contentDefinitionService.GetTypeAsync(id); if (typeViewModel == null) return NotFound(); - _contentDefinitionService.RemoveType(id, true); + await _contentDefinitionService.RemoveTypeAsync(id, true); _notifier.Success(T["\"{0}\" has been removed.", typeViewModel.DisplayName]); @@ -216,7 +216,7 @@ public async Task AddPartsTo(string id) return Unauthorized(); } - var typeViewModel = _contentDefinitionService.GetType(id); + var typeViewModel = await _contentDefinitionService.GetTypeAsync(id); if (typeViewModel == null) return NotFound(); @@ -226,7 +226,7 @@ public async Task AddPartsTo(string id) var viewModel = new AddPartsViewModel { Type = typeViewModel, - PartSelections = _contentDefinitionService.GetParts(metadataPartsOnly: false) + PartSelections = (await _contentDefinitionService.GetPartsAsync(metadataPartsOnly: false)) .Where(cpd => !typePartNames.Contains(cpd.Name) && cpd.Settings.ToObject().Attachable) .Select(cpd => new PartSelectionViewModel { PartName = cpd.Name, PartDisplayName = cpd.DisplayName, PartDescription = cpd.Description }) .ToList() @@ -242,12 +242,12 @@ public async Task AddReusablePartTo(string id) return Unauthorized(); } - var typeViewModel = _contentDefinitionService.GetType(id); + var typeViewModel = await _contentDefinitionService.GetTypeAsync(id); if (typeViewModel == null) return NotFound(); - var reusableParts = _contentDefinitionService.GetParts(metadataPartsOnly: false) + var reusableParts = (await _contentDefinitionService.GetPartsAsync(metadataPartsOnly: false)) .Where(cpd => cpd.Settings.ToObject().Attachable && cpd.Settings.ToObject().Reusable); @@ -270,7 +270,7 @@ public async Task AddPartsToPOST(string id) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var typeViewModel = _contentDefinitionService.GetType(id); + var typeViewModel = await _contentDefinitionService.GetTypeAsync(id); if (typeViewModel == null) return NotFound(); @@ -284,7 +284,7 @@ public async Task AddPartsToPOST(string id) var partsToAdd = viewModel.PartSelections.Where(ps => ps.IsSelected).Select(ps => ps.PartName); foreach (var partToAdd in partsToAdd) { - _contentDefinitionService.AddPartToType(partToAdd, typeViewModel.Name); + await _contentDefinitionService.AddPartToTypeAsync(partToAdd, typeViewModel.Name); _notifier.Success(T["The \"{0}\" part has been added.", partToAdd]); } @@ -303,7 +303,7 @@ public async Task AddReusablePartToPOST(string id) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var typeViewModel = _contentDefinitionService.GetType(id); + var typeViewModel = await _contentDefinitionService.GetTypeAsync(id); if (typeViewModel == null) return NotFound(); @@ -326,7 +326,7 @@ public async Task AddReusablePartToPOST(string id) var partToAdd = viewModel.SelectedPartName; - _contentDefinitionService.AddReusablePartToType(viewModel.Name, viewModel.DisplayName, viewModel.Description, partToAdd, typeViewModel.Name); + await _contentDefinitionService.AddReusablePartToTypeAsync(viewModel.Name, viewModel.DisplayName, viewModel.Description, partToAdd, typeViewModel.Name); if (!ModelState.IsValid) { @@ -347,13 +347,13 @@ public async Task RemovePartPOST(string id, string name) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var typeViewModel = _contentDefinitionService.GetType(id); + var typeViewModel = await _contentDefinitionService.GetTypeAsync(id); if (typeViewModel == null || !typeViewModel.TypeDefinition.Parts.Any(p => p.Name == name)) return NotFound(); - _contentDefinitionService.RemovePartFromType(name, id); + await _contentDefinitionService.RemovePartFromTypeAsync(name, id); _notifier.Success(T["The \"{0}\" part has been removed.", name]); @@ -372,7 +372,7 @@ public async Task ListParts() return View(new ListContentPartsViewModel { // only user-defined parts (not code as they are not configurable) - Parts = _contentDefinitionService.GetParts(true/*metadataPartsOnly*/) + Parts = await _contentDefinitionService.GetPartsAsync(true/*metadataPartsOnly*/) }); } @@ -394,7 +394,7 @@ public async Task CreatePartPOST(CreatePartViewModel viewModel) { ModelState.AddModelError("Name", S["Name is Required."]); } - else if (_contentDefinitionManager.GetPartDefinition(viewModel.Name) != null) + else if (await _contentDefinitionManager.GetPartDefinitionAsync(viewModel.Name) != null) { ModelState.AddModelError("Name", S["Cannot add part named '{0}'. It already exists.", viewModel.Name]); } @@ -402,7 +402,7 @@ public async Task CreatePartPOST(CreatePartViewModel viewModel) if (!ModelState.IsValid) return View(viewModel); - var partViewModel = _contentDefinitionService.AddPart(viewModel); + var partViewModel = await _contentDefinitionService.AddPartAsync(viewModel); if (partViewModel == null) { @@ -420,7 +420,7 @@ public async Task EditPart(string id) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var contentPartDefinition = _contentDefinitionManager.GetPartDefinition(id); + var contentPartDefinition = await _contentDefinitionManager.GetPartDefinitionAsync(id); if (contentPartDefinition == null) { @@ -440,7 +440,7 @@ public async Task EditPartPOST(string id, string[] orderedFieldNam if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var contentPartDefinition = _contentDefinitionManager.GetPartDefinition(id); + var contentPartDefinition = await _contentDefinitionManager.GetPartDefinitionAsync(id); if (contentPartDefinition == null) { @@ -457,7 +457,7 @@ public async Task EditPartPOST(string id, string[] orderedFieldNam } else { - _contentDefinitionService.AlterPartFieldsOrder(contentPartDefinition, orderedFieldNames); + await _contentDefinitionService.AlterPartFieldsOrderAsync(contentPartDefinition, orderedFieldNames); _notifier.Success(T["The settings of \"{0}\" have been saved.", contentPartDefinition.Name]); } @@ -471,12 +471,12 @@ public async Task DeletePart(string id) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var partViewModel = _contentDefinitionService.GetPart(id); + var partViewModel = await _contentDefinitionService.GetPartAsync(id); if (partViewModel == null) return NotFound(); - _contentDefinitionService.RemovePart(id); + await _contentDefinitionService.RemovePartAsync(id); _notifier.Information(T["\"{0}\" has been removed.", partViewModel.DisplayName]); @@ -488,7 +488,7 @@ public async Task AddFieldTo(string id, string returnUrl = null) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var partViewModel = _contentDefinitionService.GetPart(id); + var partViewModel = await _contentDefinitionService.GetPartAsync(id); if (partViewModel == null) { @@ -498,7 +498,7 @@ public async Task AddFieldTo(string id, string returnUrl = null) var viewModel = new AddFieldViewModel { Part = partViewModel.PartDefinition, - Fields = _contentDefinitionService.GetFields().Select(x => x.Name).OrderBy(x => x).ToList() + Fields = (await _contentDefinitionService.GetFieldsAsync()).Select(x => x.Name).OrderBy(x => x).ToList() }; ViewData["ReturnUrl"] = returnUrl; @@ -511,7 +511,7 @@ public async Task AddFieldToPOST(AddFieldViewModel viewModel, stri if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var partViewModel = _contentDefinitionService.GetPart(id); + var partViewModel = await _contentDefinitionService.GetPartAsync(id); if (partViewModel == null) { @@ -557,7 +557,7 @@ public async Task AddFieldToPOST(AddFieldViewModel viewModel, stri if (!ModelState.IsValid) { viewModel.Part = partDefinition; - viewModel.Fields = _contentDefinitionService.GetFields().Select(x => x.Name).OrderBy(x => x).ToList(); + viewModel.Fields = (await _contentDefinitionService.GetFieldsAsync()).Select(x => x.Name).OrderBy(x => x).ToList(); _session.Cancel(); @@ -565,7 +565,7 @@ public async Task AddFieldToPOST(AddFieldViewModel viewModel, stri return View(viewModel); } - _contentDefinitionService.AddFieldToPart(viewModel.Name, viewModel.DisplayName, viewModel.FieldTypeName, partDefinition.Name); + await _contentDefinitionService.AddFieldToPartAsync(viewModel.Name, viewModel.DisplayName, viewModel.FieldTypeName, partDefinition.Name); _notifier.Success(T["The field \"{0}\" has been added.", viewModel.DisplayName]); @@ -576,7 +576,7 @@ public async Task AddFieldToPOST(AddFieldViewModel viewModel, stri else { return RedirectToAction("EditField", new { id, viewModel.Name }); - } + } } public async Task EditField(string id, string name, string returnUrl = null) @@ -584,7 +584,7 @@ public async Task EditField(string id, string name, string returnU if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var partViewModel = _contentDefinitionService.GetPart(id); + var partViewModel = await _contentDefinitionService.GetPartAsync(id); if (partViewModel == null) { @@ -626,14 +626,14 @@ public async Task EditFieldPOST(string id, EditFieldViewModel view return NotFound(); } - var partViewModel = _contentDefinitionService.GetPart(id); + var partViewModel = await _contentDefinitionService.GetPartAsync(id); if (partViewModel == null) { return NotFound(); } - var field = _contentDefinitionManager.GetPartDefinition(id).Fields.FirstOrDefault(x => x.Name == viewModel.Name); + var field = (await _contentDefinitionManager.GetPartDefinitionAsync(id)).Fields.FirstOrDefault(x => x.Name == viewModel.Name); if (field == null) { @@ -652,7 +652,7 @@ public async Task EditFieldPOST(string id, EditFieldViewModel view ModelState.AddModelError("DisplayName", S["The Display Name name can't be empty."]); } - if (_contentDefinitionService.GetPart(partViewModel.Name).PartDefinition.Fields.Any(t => t.Name != viewModel.Name && String.Equals(t.DisplayName().Trim(), viewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase))) + if ((await _contentDefinitionService.GetPartAsync(partViewModel.Name)).PartDefinition.Fields.Any(t => t.Name != viewModel.Name && String.Equals(t.DisplayName().Trim(), viewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase))) { ModelState.AddModelError("DisplayName", S["A field with the same Display Name already exists."]); } @@ -668,10 +668,10 @@ public async Task EditFieldPOST(string id, EditFieldViewModel view _notifier.Information(T["Display name changed to {0}.", viewModel.DisplayName]); } - _contentDefinitionService.AlterField(partViewModel, viewModel); + await _contentDefinitionService.AlterFieldAsync(partViewModel, viewModel); // Refresh the local field variable in case it has been altered - field = _contentDefinitionManager.GetPartDefinition(id).Fields.FirstOrDefault(x => x.Name == viewModel.Name); + field = (await _contentDefinitionManager.GetPartDefinitionAsync(id)).Fields.FirstOrDefault(x => x.Name == viewModel.Name); viewModel.Shape = await _contentDefinitionDisplayManager.UpdatePartFieldEditorAsync(field, this); @@ -695,7 +695,7 @@ public async Task EditFieldPOST(string id, EditFieldViewModel view else { // Redirect to the type editor if a type exists with this name - var typeViewModel = _contentDefinitionService.GetType(id); + var typeViewModel = await _contentDefinitionService.GetTypeAsync(id); if (typeViewModel != null) { return RedirectToAction("Edit", new { id }); @@ -711,7 +711,7 @@ public async Task RemoveFieldFromPOST(string id, string name) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var partViewModel = _contentDefinitionService.GetPart(id); + var partViewModel = await _contentDefinitionService.GetPartAsync(id); if (partViewModel == null) { @@ -725,11 +725,11 @@ public async Task RemoveFieldFromPOST(string id, string name) return NotFound(); } - _contentDefinitionService.RemoveFieldFromPart(name, partViewModel.Name); + await _contentDefinitionService.RemoveFieldFromPartAsync(name, partViewModel.Name); _notifier.Success(T["The \"{0}\" field has been removed.", field.DisplayName()]); - if (_contentDefinitionService.GetType(id) != null) + if (await _contentDefinitionService.GetTypeAsync(id) != null) { return RedirectToAction("Edit", new { id }); } @@ -745,7 +745,7 @@ public async Task EditTypePart(string id, string name) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var typeDefinition = _contentDefinitionManager.GetTypeDefinition(id); + var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(id); if (typeDefinition == null) { @@ -784,7 +784,7 @@ public async Task EditTypePartPOST(string id, EditTypePartViewMode return NotFound(); } - var typeDefinition = _contentDefinitionManager.GetTypeDefinition(id); + var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(id); if (typeDefinition == null) { @@ -826,7 +826,7 @@ public async Task EditTypePartPOST(string id, EditTypePartViewMode } } - _contentDefinitionService.AlterTypePart(viewModel); + await _contentDefinitionService.AlterTypePartAsync(viewModel); viewModel.Shape = await _contentDefinitionDisplayManager.UpdateTypePartEditorAsync(part, this); diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Editors/DefaultContentDefinitionDisplayManager.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Editors/DefaultContentDefinitionDisplayManager.cs index 65132cf7461..626b64629ba 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Editors/DefaultContentDefinitionDisplayManager.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Editors/DefaultContentDefinitionDisplayManager.cs @@ -84,7 +84,7 @@ public async Task UpdateTypeEditorAsync(ContentTypeDefinition contentTy var layout = await _layoutAccessor.GetLayoutAsync(); - _contentDefinitionManager.AlterTypeDefinition(contentTypeDefinition.Name, typeBuilder => + await _contentDefinitionManager.AlterTypeDefinitionAsync(contentTypeDefinition.Name, typeBuilder => { var typeContext = new UpdateTypeEditorContext( typeBuilder, @@ -143,7 +143,7 @@ public async Task UpdatePartEditorAsync(ContentPartDefinition contentPa UpdatePartEditorContext partContext = null; var layout = await _layoutAccessor.GetLayoutAsync(); - _contentDefinitionManager.AlterPartDefinition(contentPartDefinition.Name, partBuilder => + await _contentDefinitionManager.AlterPartDefinitionAsync(contentPartDefinition.Name, partBuilder => { partContext = new UpdatePartEditorContext( partBuilder, @@ -201,7 +201,7 @@ public async Task UpdateTypePartEditorAsync(ContentTypePartDefinition c dynamic typePartDefinitionShape = await CreateContentShapeAsync("ContentTypePartDefinition_Edit"); var layout = await _layoutAccessor.GetLayoutAsync(); - _contentDefinitionManager.AlterTypeDefinition(contentTypePartDefinition.ContentTypeDefinition.Name, typeBuilder => + await _contentDefinitionManager.AlterTypeDefinitionAsync(contentTypePartDefinition.ContentTypeDefinition.Name, typeBuilder => { typeBuilder.WithPart(contentTypePartDefinition.Name, async typePartBuilder => @@ -267,7 +267,7 @@ public async Task UpdatePartFieldEditorAsync(ContentPartFieldDefinition var layout = await _layoutAccessor.GetLayoutAsync(); - _contentDefinitionManager.AlterPartDefinition(contentPartDefinition.Name, partBuilder => + await _contentDefinitionManager.AlterPartDefinitionAsync(contentPartDefinition.Name, partBuilder => { partBuilder.WithField(contentPartFieldDefinition.Name, async partFieldBuilder => { diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/RecipeSteps/ContentDefinitionStep.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/RecipeSteps/ContentDefinitionStep.cs index b321c56ec3b..07260e31a03 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/RecipeSteps/ContentDefinitionStep.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/RecipeSteps/ContentDefinitionStep.cs @@ -1,8 +1,8 @@ using System; using System.Threading.Tasks; +using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentManagement.Metadata.Records; -using OrchardCore.ContentManagement.Metadata; using OrchardCore.Recipes.Models; using OrchardCore.Recipes.Services; @@ -20,37 +20,35 @@ public ContentDefinitionStep(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public Task ExecuteAsync(RecipeExecutionContext context) + public async Task ExecuteAsync(RecipeExecutionContext context) { if (!String.Equals(context.Name, "ContentDefinition", StringComparison.OrdinalIgnoreCase)) { - return Task.CompletedTask; + return; } var step = context.Step.ToObject(); foreach (var contentType in step.ContentTypes) { - var newType = _contentDefinitionManager.GetTypeDefinition(contentType.Name) + var newType = await _contentDefinitionManager.GetTypeDefinitionAsync(contentType.Name) ?? new ContentTypeDefinition(contentType.Name, contentType.DisplayName); - UpdateContentType(newType, contentType); + await UpdateContentTypeAsync(newType, contentType); } foreach (var contentPart in step.ContentParts) { - var newPart = _contentDefinitionManager.GetPartDefinition(contentPart.Name) + var newPart = await _contentDefinitionManager.GetPartDefinitionAsync(contentPart.Name) ?? new ContentPartDefinition(contentPart.Name); - UpdateContentPart(newPart, contentPart); + await UpdateContentPartAsync(newPart, contentPart); } - - return Task.CompletedTask; } - private void UpdateContentType(ContentTypeDefinition type, ContentTypeDefinitionRecord record) + private async Task UpdateContentTypeAsync(ContentTypeDefinition type, ContentTypeDefinitionRecord record) { - _contentDefinitionManager.AlterTypeDefinition(type.Name, builder => + await _contentDefinitionManager.AlterTypeDefinitionAsync(type.Name, builder => { if (!String.IsNullOrEmpty(record.DisplayName)) { @@ -65,9 +63,9 @@ private void UpdateContentType(ContentTypeDefinition type, ContentTypeDefinition }); } - private void UpdateContentPart(ContentPartDefinition part, ContentPartDefinitionRecord record) + private async Task UpdateContentPartAsync(ContentPartDefinition part, ContentPartDefinitionRecord record) { - _contentDefinitionManager.AlterPartDefinition(part.Name, builder => + await _contentDefinitionManager.AlterPartDefinitionAsync(part.Name, builder => { builder.MergeSettings(record.Settings); diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/ContentDefinitionService.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/ContentDefinitionService.cs index 69cd0a485a4..a28b7a31747 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/ContentDefinitionService.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/ContentDefinitionService.cs @@ -1,13 +1,13 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentManagement.Metadata.Settings; -using OrchardCore.ContentManagement.Records; using OrchardCore.ContentTypes.Events; using OrchardCore.ContentTypes.ViewModels; using OrchardCore.Modules; @@ -49,17 +49,17 @@ public ContentDefinitionService( public ILogger Logger { get; } public IStringLocalizer T { get; set; } - public IEnumerable GetTypes() + public async Task> GetTypesAsync() { - return _contentDefinitionManager - .ListTypeDefinitions() + return (await _contentDefinitionManager + .ListTypeDefinitionsAsync()) .Select(ctd => new EditTypeViewModel(ctd)) .OrderBy(m => m.DisplayName); } - public EditTypeViewModel GetType(string name) + public async Task GetTypeAsync(string name) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(name); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(name); if (contentTypeDefinition == null) { @@ -69,7 +69,7 @@ public EditTypeViewModel GetType(string name) return new EditTypeViewModel(contentTypeDefinition); } - public ContentTypeDefinition AddType(string name, string displayName) + public async Task AddTypeAsync(string name, string displayName) { if (String.IsNullOrWhiteSpace(displayName)) { @@ -78,62 +78,65 @@ public ContentTypeDefinition AddType(string name, string displayName) if (String.IsNullOrWhiteSpace(name)) { - name = GenerateContentTypeNameFromDisplayName(displayName); + name = await GenerateContentTypeNameFromDisplayNameAsync(displayName); } - else { + else + { if (!name[0].IsLetter()) { throw new ArgumentException("Content type name must start with a letter", "name"); } } - while (_contentDefinitionManager.GetTypeDefinition(name) != null) + while (await _contentDefinitionManager.GetTypeDefinitionAsync(name) != null) + { name = VersionName(name); + } var contentTypeDefinition = new ContentTypeDefinition(name, displayName); - _contentDefinitionManager.StoreTypeDefinition(contentTypeDefinition); + await _contentDefinitionManager.StoreTypeDefinitionAsync(contentTypeDefinition); // Ensure it has its own part - _contentDefinitionManager.AlterTypeDefinition(name, builder => builder.WithPart(name)); - _contentDefinitionManager.AlterTypeDefinition(name, cfg => cfg.Creatable().Draftable().Versionable().Listable().Securable()); + await _contentDefinitionManager.AlterTypeDefinitionAsync(name, builder => builder.WithPart(name)); + await _contentDefinitionManager.AlterTypeDefinitionAsync(name, cfg => cfg.Creatable().Draftable().Versionable().Listable().Securable()); _contentDefinitionEventHandlers.Invoke(x => x.ContentTypeCreated(new ContentTypeCreatedContext { ContentTypeDefinition = contentTypeDefinition }), Logger); return contentTypeDefinition; } - public void RemoveType(string name, bool deleteContent) + public async Task RemoveTypeAsync(string name, bool deleteContent) { // first remove all attached parts - var typeDefinition = _contentDefinitionManager.GetTypeDefinition(name); + var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(name); var partDefinitions = typeDefinition.Parts.ToArray(); foreach (var partDefinition in partDefinitions) { - RemovePartFromType(partDefinition.PartDefinition.Name, name); + await RemovePartFromTypeAsync(partDefinition.PartDefinition.Name, name); // delete the part if it's its own part if (partDefinition.PartDefinition.Name == name) { - RemovePart(name); + await RemovePartAsync(name); } } - _contentDefinitionManager.DeleteTypeDefinition(name); + await _contentDefinitionManager.DeleteTypeDefinitionAsync(name); _contentDefinitionEventHandlers.Invoke(x => x.ContentTypeRemoved(new ContentTypeRemovedContext { ContentTypeDefinition = typeDefinition }), Logger); } - public void AddPartToType(string partName, string typeName) + public async Task AddPartToTypeAsync(string partName, string typeName) { - _contentDefinitionManager.AlterTypeDefinition(typeName, typeBuilder => typeBuilder.WithPart(partName)); + await _contentDefinitionManager.AlterTypeDefinitionAsync(typeName, typeBuilder => typeBuilder.WithPart(partName)); _contentDefinitionEventHandlers.Invoke(x => x.ContentPartAttached(new ContentPartAttachedContext { ContentTypeName = typeName, ContentPartName = partName }), Logger); } - public void AddReusablePartToType(string name, string displayName, string description, string partName, string typeName) + public async Task AddReusablePartToTypeAsync(string name, string displayName, string description, string partName, string typeName) { - _contentDefinitionManager.AlterTypeDefinition(typeName, typeBuilder => typeBuilder.WithPart(name, partName, cfg => + await _contentDefinitionManager.AlterTypeDefinitionAsync(typeName, typeBuilder => typeBuilder.WithPart(name, partName, cfg => { cfg.WithDisplayName(displayName); cfg.WithDescription(description); @@ -142,19 +145,19 @@ public void AddReusablePartToType(string name, string displayName, string descri _contentDefinitionEventHandlers.Invoke(x => x.ContentPartAttached(new ContentPartAttachedContext { ContentTypeName = typeName, ContentPartName = partName }), Logger); } - public void RemovePartFromType(string partName, string typeName) + public async Task RemovePartFromTypeAsync(string partName, string typeName) { - _contentDefinitionManager.AlterTypeDefinition(typeName, typeBuilder => typeBuilder.RemovePart(partName)); + await _contentDefinitionManager.AlterTypeDefinitionAsync(typeName, typeBuilder => typeBuilder.RemovePart(partName)); _contentDefinitionEventHandlers.Invoke(x => x.ContentPartDetached(new ContentPartDetachedContext { ContentTypeName = typeName, ContentPartName = partName }), Logger); } - public IEnumerable GetParts(bool metadataPartsOnly) + public async Task> GetPartsAsync(bool metadataPartsOnly) { - var typeNames = new HashSet(GetTypes().Select(ctd => ctd.Name)); + var typeNames = new HashSet((await GetTypesAsync()).Select(ctd => ctd.Name)); // user-defined parts // except for those parts with the same name as a type (implicit type's part or a mistake) - var userContentParts = _contentDefinitionManager.ListPartDefinitions() + var userContentParts = (await _contentDefinitionManager.ListPartDefinitionsAsync()) .Where(cpd => !typeNames.Contains(cpd.Name)) .Select(cpd => new EditPartViewModel(cpd)) .ToDictionary( @@ -175,15 +178,15 @@ public IEnumerable GetParts(bool metadataPartsOnly) .OrderBy(m => m.DisplayName); } - public EditPartViewModel GetPart(string name) + public async Task GetPartAsync(string name) { - var contentPartDefinition = _contentDefinitionManager.GetPartDefinition(name); + var contentPartDefinition = await _contentDefinitionManager.GetPartDefinitionAsync(name); if (contentPartDefinition == null) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(name); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(name); - if(contentTypeDefinition == null) + if (contentTypeDefinition == null) { return null; } @@ -196,17 +199,17 @@ public EditPartViewModel GetPart(string name) return viewModel; } - public EditPartViewModel AddPart(CreatePartViewModel partViewModel) + public async Task AddPartAsync(CreatePartViewModel partViewModel) { var name = partViewModel.Name; - if (_contentDefinitionManager.GetPartDefinition(name) != null) + if (await _contentDefinitionManager.GetPartDefinitionAsync(name) != null) throw new Exception(T["Cannot add part named '{0}'. It already exists.", name]); if (!string.IsNullOrEmpty(name)) { - _contentDefinitionManager.AlterPartDefinition(name, builder => builder.Attachable()); - var partDefinition = _contentDefinitionManager.GetPartDefinition(name); + await _contentDefinitionManager.AlterPartDefinitionAsync(name, builder => builder.Attachable()); + var partDefinition = await _contentDefinitionManager.GetPartDefinitionAsync(name); _contentDefinitionEventHandlers.Invoke(x => x.ContentPartCreated(new ContentPartCreatedContext { ContentPartDefinition = partDefinition }), Logger); return new EditPartViewModel(partDefinition); } @@ -214,9 +217,9 @@ public EditPartViewModel AddPart(CreatePartViewModel partViewModel) return null; } - public void RemovePart(string name) + public async Task RemovePartAsync(string name) { - var partDefinition = _contentDefinitionManager.GetPartDefinition(name); + var partDefinition = await _contentDefinitionManager.GetPartDefinitionAsync(name); if (partDefinition == null) { @@ -227,42 +230,42 @@ public void RemovePart(string name) var fieldDefinitions = partDefinition.Fields.ToArray(); foreach (var fieldDefinition in fieldDefinitions) { - RemoveFieldFromPart(fieldDefinition.Name, name); + await RemoveFieldFromPartAsync(fieldDefinition.Name, name); } - _contentDefinitionManager.DeletePartDefinition(name); + await _contentDefinitionManager.DeletePartDefinitionAsync(name); _contentDefinitionEventHandlers.Invoke(x => x.ContentPartRemoved(new ContentPartRemovedContext { ContentPartDefinition = partDefinition }), Logger); } - public IEnumerable GetFields() + public Task> GetFieldsAsync() { - return _contentFields.Select(x => x.GetType()).ToList(); + return Task.FromResult((IEnumerable)_contentFields.Select(x => x.GetType()).ToArray()); } - public void AddFieldToPart(string fieldName, string fieldTypeName, string partName) + public Task AddFieldToPartAsync(string fieldName, string fieldTypeName, string partName) { - AddFieldToPart(fieldName, fieldName, fieldTypeName, partName); + return AddFieldToPartAsync(fieldName, fieldName, fieldTypeName, partName); } - public void AddFieldToPart(string fieldName, string displayName, string fieldTypeName, string partName) + public async Task AddFieldToPartAsync(string fieldName, string displayName, string fieldTypeName, string partName) { if (String.IsNullOrEmpty(fieldName)) { throw new ArgumentException(nameof(fieldName)); } - var partDefinition = _contentDefinitionManager.GetPartDefinition(partName); - var typeDefinition = _contentDefinitionManager.GetTypeDefinition(partName); + var partDefinition = await _contentDefinitionManager.GetPartDefinitionAsync(partName); + var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(partName); // If the type exists ensure it has its own part if (typeDefinition != null) { - _contentDefinitionManager.AlterTypeDefinition(partName, builder => builder.WithPart(partName)); + await _contentDefinitionManager.AlterTypeDefinitionAsync(partName, builder => builder.WithPart(partName)); } fieldName = fieldName.ToSafeName(); - _contentDefinitionManager.AlterPartDefinition(partName, + await _contentDefinitionManager.AlterPartDefinitionAsync(partName, partBuilder => partBuilder.WithField(fieldName, fieldBuilder => fieldBuilder.OfType(fieldTypeName).WithDisplayName(displayName))); _contentDefinitionEventHandlers.Invoke(x => x.ContentFieldAttached(new ContentFieldAttachedContext @@ -274,9 +277,9 @@ public void AddFieldToPart(string fieldName, string displayName, string fieldTyp }), Logger); } - public void RemoveFieldFromPart(string fieldName, string partName) + public async Task RemoveFieldFromPartAsync(string fieldName, string partName) { - _contentDefinitionManager.AlterPartDefinition(partName, typeBuilder => typeBuilder.RemoveField(fieldName)); + await _contentDefinitionManager.AlterPartDefinitionAsync(partName, typeBuilder => typeBuilder.RemoveField(fieldName)); _contentDefinitionEventHandlers.Invoke(x => x.ContentFieldDetached(new ContentFieldDetachedContext { ContentPartName = partName, @@ -284,9 +287,9 @@ public void RemoveFieldFromPart(string fieldName, string partName) }), Logger); } - public void AlterField(EditPartViewModel partViewModel, EditFieldViewModel fieldViewModel) + public Task AlterFieldAsync(EditPartViewModel partViewModel, EditFieldViewModel fieldViewModel) { - _contentDefinitionManager.AlterPartDefinition(partViewModel.Name, partBuilder => + return _contentDefinitionManager.AlterPartDefinitionAsync(partViewModel.Name, partBuilder => { partBuilder.WithField(fieldViewModel.Name, fieldBuilder => { @@ -297,11 +300,11 @@ public void AlterField(EditPartViewModel partViewModel, EditFieldViewModel field }); } - public void AlterTypePart(EditTypePartViewModel typePartViewModel) + public Task AlterTypePartAsync(EditTypePartViewModel typePartViewModel) { var typeDefinition = typePartViewModel.TypePartDefinition.ContentTypeDefinition; - _contentDefinitionManager.AlterTypeDefinition(typeDefinition.Name, type => + return _contentDefinitionManager.AlterTypeDefinitionAsync(typeDefinition.Name, type => { type.WithPart(typePartViewModel.Name, typePartViewModel.TypePartDefinition.PartDefinition, part => { @@ -312,9 +315,9 @@ public void AlterTypePart(EditTypePartViewModel typePartViewModel) }); } - public void AlterTypePartsOrder(ContentTypeDefinition typeDefinition, string[] partNames) + public Task AlterTypePartsOrderAsync(ContentTypeDefinition typeDefinition, string[] partNames) { - _contentDefinitionManager.AlterTypeDefinition(typeDefinition.Name, type => + return _contentDefinitionManager.AlterTypeDefinitionAsync(typeDefinition.Name, type => { for (var i = 0; i < partNames.Length; i++) { @@ -327,9 +330,9 @@ public void AlterTypePartsOrder(ContentTypeDefinition typeDefinition, string[] p }); } - public void AlterPartFieldsOrder(ContentPartDefinition partDefinition, string[] fieldNames) + public Task AlterPartFieldsOrderAsync(ContentPartDefinition partDefinition, string[] fieldNames) { - _contentDefinitionManager.AlterPartDefinition(partDefinition.Name, type => + return _contentDefinitionManager.AlterPartDefinitionAsync(partDefinition.Name, type => { for (var i = 0; i < fieldNames.Length; i++) { @@ -342,26 +345,28 @@ public void AlterPartFieldsOrder(ContentPartDefinition partDefinition, string[] }); } - public string GenerateContentTypeNameFromDisplayName(string displayName) + public async Task GenerateContentTypeNameFromDisplayNameAsync(string displayName) { displayName = displayName.ToSafeName(); - while (_contentDefinitionManager.GetTypeDefinition(displayName) != null) + while (await _contentDefinitionManager.GetTypeDefinitionAsync(displayName) != null) + { displayName = VersionName(displayName); + } return displayName; } - public string GenerateFieldNameFromDisplayName(string partName, string displayName) + public async Task GenerateFieldNameFromDisplayNameAsync(string partName, string displayName) { IEnumerable fieldDefinitions; - var part = _contentDefinitionManager.GetPartDefinition(partName); + var part = await _contentDefinitionManager.GetPartDefinitionAsync(partName); displayName = displayName.ToSafeName(); if (part == null) { - var type = _contentDefinitionManager.GetTypeDefinition(partName); + var type = await _contentDefinitionManager.GetTypeDefinitionAsync(partName); if (type == null) { @@ -375,12 +380,14 @@ public string GenerateFieldNameFromDisplayName(string partName, string displayNa { return displayName; } - else { + else + { fieldDefinitions = typePart.PartDefinition.Fields.ToArray(); } } - else { + else + { fieldDefinitions = part.Fields.ToArray(); } @@ -401,11 +408,12 @@ private static string VersionName(string name) //this could unintentionally chomp something that looks like a version name = string.Join("-", nameParts.Take(nameParts.Length - 1)); } - else { + else + { version = 2; } return string.Format("{0}-{1}", name, version); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/DefaultStereotypesProvider.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/DefaultStereotypesProvider.cs index 9d39db601bb..a6a28c7584a 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/DefaultStereotypesProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/DefaultStereotypesProvider.cs @@ -1,22 +1,23 @@ -using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace OrchardCore.ContentTypes.Services { public class DefaultStereotypesProvider : IStereotypesProvider { - private readonly Lazy _contentDefinitionService; - public DefaultStereotypesProvider(Lazy contentDefinitionService) + private readonly IContentDefinitionService _contentDefinitionService; + public DefaultStereotypesProvider(IContentDefinitionService contentDefinitionService) { _contentDefinitionService = contentDefinitionService; } - public IEnumerable GetStereotypes() + public async Task> GetStereotypesAsync() { + // Harvest all available stereotypes by finding out about the stereotype of all content types - var stereotypes = _contentDefinitionService.Value.GetTypes().Where(x => x.Settings["Stereotype"] != null).Select(x => x.Settings["Stereotype"].ToString()).Distinct(); + var stereotypes = (await _contentDefinitionService.GetTypesAsync()).Where(x => x.Settings["Stereotype"] != null).Select(x => x.Settings["Stereotype"].ToString()).Distinct(); return stereotypes.Select(x => new StereotypeDescription { DisplayName = x, Stereotype = x }); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/IContentDefinitionService.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/IContentDefinitionService.cs index 36d7f659120..485087f136c 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/IContentDefinitionService.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/IContentDefinitionService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentTypes.ViewModels; @@ -7,30 +8,30 @@ namespace OrchardCore.ContentTypes.Services { public interface IContentDefinitionService { - IEnumerable GetTypes(); - EditTypeViewModel GetType(string name); - ContentTypeDefinition AddType(string name, string displayName); - void RemoveType(string name, bool deleteContent); - void AddPartToType(string partName, string typeName); - void AddReusablePartToType(string name, string displayName, string description, string partName, string typeName); - void RemovePartFromType(string partName, string typeName); - string GenerateContentTypeNameFromDisplayName(string displayName); - string GenerateFieldNameFromDisplayName(string partName, string displayName); + Task> GetTypesAsync(); + Task GetTypeAsync(string name); + Task AddTypeAsync(string name, string displayName); + Task RemoveTypeAsync(string name, bool deleteContent); + Task AddPartToTypeAsync(string partName, string typeName); + Task AddReusablePartToTypeAsync(string name, string displayName, string description, string partName, string typeName); + Task RemovePartFromTypeAsync(string partName, string typeName); + Task GenerateContentTypeNameFromDisplayNameAsync(string displayName); + Task GenerateFieldNameFromDisplayNameAsync(string partName, string displayName); - IEnumerable GetParts(bool metadataPartsOnly); - EditPartViewModel GetPart(string name); - EditPartViewModel AddPart(CreatePartViewModel partViewModel); - void RemovePart(string name); + Task> GetPartsAsync(bool metadataPartsOnly); + Task GetPartAsync(string name); + Task AddPartAsync(CreatePartViewModel partViewModel); + Task RemovePartAsync(string name); - IEnumerable GetFields(); - void AddFieldToPart(string fieldName, string fieldTypeName, string partName); - void AddFieldToPart(string fieldName, string displayName, string fieldTypeName, string partName); - void RemoveFieldFromPart(string fieldName, string partName); - void AlterField(EditPartViewModel partViewModel, EditFieldViewModel fieldViewModel); + Task> GetFieldsAsync(); + Task AddFieldToPartAsync(string fieldName, string fieldTypeName, string partName); + Task AddFieldToPartAsync(string fieldName, string displayName, string fieldTypeName, string partName); + Task RemoveFieldFromPartAsync(string fieldName, string partName); + Task AlterFieldAsync(EditPartViewModel partViewModel, EditFieldViewModel fieldViewModel); - void AlterTypePart(EditTypePartViewModel partViewModel); + Task AlterTypePartAsync(EditTypePartViewModel partViewModel); - void AlterTypePartsOrder(ContentTypeDefinition typeDefinition, string[] partNames); - void AlterPartFieldsOrder(ContentPartDefinition partDefinition, string[] fieldNames); + Task AlterTypePartsOrderAsync(ContentTypeDefinition typeDefinition, string[] partNames); + Task AlterPartFieldsOrderAsync(ContentPartDefinition partDefinition, string[] fieldNames); } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/IStereotypesProvider.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/IStereotypesProvider.cs index b9689c57f79..c4d4e007582 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/IStereotypesProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/IStereotypesProvider.cs @@ -1,10 +1,11 @@ using System.Collections.Generic; +using System.Threading.Tasks; namespace OrchardCore.ContentTypes.Services { public interface IStereotypesProvider { - IEnumerable GetStereotypes(); + Task> GetStereotypesAsync(); } public class StereotypeDescription @@ -12,4 +13,4 @@ public class StereotypeDescription public string Stereotype { get; set; } public string DisplayName { get; set; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/StereotypeService.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/StereotypeService.cs index 17358cfc601..c8a43dcab0b 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/StereotypeService.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/StereotypeService.cs @@ -1,11 +1,11 @@ using System.Collections.Generic; -using System.Linq; +using System.Threading.Tasks; namespace OrchardCore.ContentTypes.Services { public interface IStereotypeService { - IEnumerable GetStereotypes(); + Task> GetStereotypesAsync(); } public class StereotypeService : IStereotypeService @@ -17,9 +17,14 @@ public StereotypeService(IEnumerable providers) _providers = providers; } - public IEnumerable GetStereotypes() + public async Task> GetStereotypesAsync() { - return _providers.SelectMany(x => x.GetStereotypes()); + var stereotypes = new List(); + foreach (var provider in _providers) + { + stereotypes.AddRange(await provider.GetStereotypesAsync()); + } + return stereotypes; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewComponents/SelectContentTypesViewComponent.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewComponents/SelectContentTypesViewComponent.cs index 4f848206a05..6b11f169c9b 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewComponents/SelectContentTypesViewComponent.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewComponents/SelectContentTypesViewComponent.cs @@ -1,10 +1,11 @@ using System; +using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; -using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.ContentManagement.Metadata; +using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.ContentTypes.ViewModels; -using System.Collections.Generic; namespace OrchardCore.ContentTypes.ViewComponents { @@ -17,14 +18,14 @@ public SelectContentTypesViewComponent(IContentDefinitionManager contentDefiniti _contentDefinitionManager = contentDefinitionManager; } - public IViewComponentResult Invoke(IEnumerable selectedContentTypes, string htmlName, string stereotype) + public async Task InvokeAsync(IEnumerable selectedContentTypes, string htmlName, string stereotype) { if (selectedContentTypes == null) { selectedContentTypes = new string[0]; } - var contentTypes = ContentTypeSelection.Build(_contentDefinitionManager, selectedContentTypes); + var contentTypes = await ContentTypeSelection.BuildAsync(_contentDefinitionManager, selectedContentTypes); if (!String.IsNullOrEmpty(stereotype)) { diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewModels/SelectContentTypesViewModel.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewModels/SelectContentTypesViewModel.cs index f915272a636..cd46c31bb91 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewModels/SelectContentTypesViewModel.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewModels/SelectContentTypesViewModel.cs @@ -1,7 +1,8 @@ +using System.Collections.Generic; using System.Linq; -using OrchardCore.ContentManagement.Metadata.Models; +using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata; -using System.Collections.Generic; +using OrchardCore.ContentManagement.Metadata.Models; namespace OrchardCore.ContentTypes.ViewModels { @@ -16,10 +17,10 @@ public class ContentTypeSelection public bool IsSelected { get; set; } public ContentTypeDefinition ContentTypeDefinition { get; set; } - public static ContentTypeSelection[] Build(IContentDefinitionManager contentDefinitionManager, IEnumerable selectedContentTypes) + public static async Task BuildAsync(IContentDefinitionManager contentDefinitionManager, IEnumerable selectedContentTypes) { - var contentTypes = contentDefinitionManager - .ListTypeDefinitions() + var contentTypes = (await contentDefinitionManager + .ListTypeDefinitionsAsync()) .Select(x => new ContentTypeSelection { diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/Edit.cshtml index bc0cd1a3c42..045424364d7 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/Edit.cshtml @@ -7,14 +7,16 @@ @{ var typePart = Model.TypeDefinition.Parts.FirstOrDefault(x => String.Equals(x.Name, Model.TypeDefinition.Name, StringComparison.OrdinalIgnoreCase)); - var orderedParts = Model.TypeDefinition.Parts - .Select(part => - { - var defaultPosition = ContentDefinitionManager.GetPartDefinition(part.PartDefinition.Name)?.DefaultPosition() ?? "5"; - return new { Part = part, Order = int.Parse(part.Settings["Position"]?.ToString() ?? defaultPosition) }; - }) + var dynamicParts = new List(); + foreach (var part in Model.TypeDefinition.Parts) + { + var defaultPosition = (await ContentDefinitionManager.GetPartDefinitionAsync(part.PartDefinition.Name))?.DefaultPosition() ?? "5"; + dynamicParts.Add(new { Part = part, Order = int.Parse(part.Settings["Position"]?.ToString() ?? defaultPosition) }); + } + + var orderedParts = dynamicParts .OrderBy(x => x.Order) - .Select(x => x.Part); + .Select(x => (ContentTypePartDefinition)x.Part); var orderedFields = typePart == null ? Enumerable.Empty() : typePart.PartDefinition.Fields .Select(field => new { Field = field, Order = int.Parse(field.Settings["Position"]?.ToString() ?? "0") }) diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Items/ContentDefinitionDeploymentStep.Fields.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Items/ContentDefinitionDeploymentStep.Fields.Edit.cshtml index a5cbf62533f..e627827f5f4 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Items/ContentDefinitionDeploymentStep.Fields.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Items/ContentDefinitionDeploymentStep.Fields.Edit.cshtml @@ -5,8 +5,8 @@ var contentTypes = (string[])Model.ContentTypes; var contentParts = (string[])Model.ContentParts; - var allTypes = ContentDefinitionManager.ListTypeDefinitions(); - var allParts = ContentDefinitionManager.ListPartDefinitions(); + var allTypes = await ContentDefinitionManager.ListTypeDefinitionsAsync(); + var allParts = await ContentDefinitionManager.ListPartDefinitionsAsync(); var avaParts = allParts.Where(x => !allTypes.Any(y => y.Name == x.Name)); } @@ -147,4 +147,3 @@ }); }); - diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Items/ContentDefinitionDeploymentStep.Fields.Summary.cshtml b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Items/ContentDefinitionDeploymentStep.Fields.Summary.cshtml index af6a7b4dec9..40eb16ef40d 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Items/ContentDefinitionDeploymentStep.Fields.Summary.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Items/ContentDefinitionDeploymentStep.Fields.Summary.cshtml @@ -15,14 +15,14 @@ else var contentTypes = Model.Value.ContentTypes; var contentParts = Model.Value.ContentParts; - var allTypes = ContentDefinitionManager.ListTypeDefinitions(); - var allParts = ContentDefinitionManager.ListPartDefinitions(); + var allTypes = await ContentDefinitionManager.ListTypeDefinitionsAsync(); + var allParts = await ContentDefinitionManager.ListPartDefinitionsAsync(); var avaParts = allParts.Where(x => !allTypes.Any(y => y.Name == x.Name)); if (contentTypes?.Length > 0) { - foreach (var def in ContentDefinitionManager.ListTypeDefinitions()) + foreach (var def in await ContentDefinitionManager.ListTypeDefinitionsAsync()) { if (contentTypes.Contains(def.Name)) { @@ -41,4 +41,4 @@ else } } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/AdminMenu.cs b/src/OrchardCore.Modules/OrchardCore.Contents/AdminMenu.cs index a44c0d7d166..216a6888b3f 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/AdminMenu.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/AdminMenu.cs @@ -34,7 +34,7 @@ public async Task BuildNavigationAsync(string name, NavigationBuilder builder) return; } - var contentTypeDefinitions = _contentDefinitionManager.ListTypeDefinitions().OrderBy(d => d.Name); + var contentTypeDefinitions = (await _contentDefinitionManager.ListTypeDefinitionsAsync()).OrderBy(d => d.Name); builder.Add(T["Content"], "1.4", content => content .AddClass("content").Id("content") @@ -65,4 +65,4 @@ await builder.AddAsync(T["New"], "-1", async newMenu => } } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/AdminNodes/ContentTypesAdminNodeDriver.cs b/src/OrchardCore.Modules/OrchardCore.Contents/AdminNodes/ContentTypesAdminNodeDriver.cs index 2c2c868fc62..1b09ad060e7 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/AdminNodes/ContentTypesAdminNodeDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/AdminNodes/ContentTypesAdminNodeDriver.cs @@ -1,11 +1,9 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.DisplayManagement.Handlers; -using OrchardCore.DisplayManagement.ModelBinding; using OrchardCore.DisplayManagement.Views; using OrchardCore.Navigation; @@ -27,13 +25,12 @@ public override IDisplayResult Display(ContentTypesAdminNode treeNode) ); } - public override IDisplayResult Edit(ContentTypesAdminNode treeNode) + public override async Task EditAsync(ContentTypesAdminNode treeNode, BuildEditorContext context) { - var listable = _contentDefinitionManager.ListTypeDefinitions() + var listable = (await _contentDefinitionManager.ListTypeDefinitionsAsync()) .Where(ctd => ctd.Settings.ToObject().Listable) .OrderBy(ctd => ctd.DisplayName).ToList(); - var entries = listable.Select(x => new ContentTypeEntryViewModel { ContentTypeId = x.Name, @@ -50,24 +47,25 @@ public override IDisplayResult Edit(ContentTypesAdminNode treeNode) }).Location("Content"); } - public override async Task UpdateAsync(ContentTypesAdminNode treeNode, IUpdateModel updater) + public override async Task UpdateAsync(ContentTypesAdminNode treeNode, UpdateEditorContext context) { // Initializes the value to empty otherwise the model is not updated if no type is selected. treeNode.ContentTypes = Array.Empty(); var model = new ContentTypesAdminNodeViewModel(); - if (await updater.TryUpdateModelAsync(model, Prefix, x => x.ShowAll, x => x.IconClass, x => x.ContentTypes)) { + if (await context.Updater.TryUpdateModelAsync(model, Prefix, x => x.ShowAll, x => x.IconClass, x => x.ContentTypes)) + { treeNode.ShowAll = model.ShowAll; treeNode.IconClass = model.IconClass; treeNode.ContentTypes = model.ContentTypes - .Where( x => x.IsChecked == true) - .Select(x => new ContentTypeEntry { ContentTypeId = x.ContentTypeId, IconClass = x.IconClass }) + .Where(x => x.IsChecked == true) + .Select(x => new ContentTypeEntry { ContentTypeId = x.ContentTypeId, IconClass = x.IconClass }) .ToArray(); }; - return Edit(treeNode); + return await EditAsync(treeNode, context); } } } diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/AdminNodes/ContentTypesAdminNodeNavigationBuilder.cs b/src/OrchardCore.Modules/OrchardCore.Contents/AdminNodes/ContentTypesAdminNodeNavigationBuilder.cs index 3785d64d7a1..0ca88c4ba26 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/AdminNodes/ContentTypesAdminNodeNavigationBuilder.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/AdminNodes/ContentTypesAdminNodeNavigationBuilder.cs @@ -35,7 +35,6 @@ public ContentTypesAdminNodeNavigationBuilder( public string Name => typeof(ContentTypesAdminNode).Name; - public async Task BuildNavigationAsync(MenuItem menuItem, NavigationBuilder builder, IEnumerable treeNodeBuilders) { var node = menuItem as ContentTypesAdminNode; @@ -46,7 +45,7 @@ public async Task BuildNavigationAsync(MenuItem menuItem, NavigationBuilder buil } // Add ContentTypes specific children - var typesToShow = GetContentTypesToShow(node); + var typesToShow = await GetContentTypesToShowAsync(node); foreach (var ctd in typesToShow) { builder.Add(new LocalizedString(ctd.DisplayName, ctd.DisplayName), cTypeMenu => @@ -61,7 +60,6 @@ public async Task BuildNavigationAsync(MenuItem menuItem, NavigationBuilder buil }); } - // Add external children foreach (var childNode in node.Items) { @@ -75,16 +73,13 @@ public async Task BuildNavigationAsync(MenuItem menuItem, NavigationBuilder buil _logger.LogError(e, "An exception occurred while building the '{MenuItem}' child Menu Item.", childNode.GetType().Name); } } - } - private IEnumerable GetContentTypesToShow(ContentTypesAdminNode node) + private async Task> GetContentTypesToShowAsync(ContentTypesAdminNode node) { - - var typesToShow = _contentDefinitionManager.ListTypeDefinitions() + var typesToShow = (await _contentDefinitionManager.ListTypeDefinitionsAsync()) .Where(ctd => ctd.Settings.ToObject().Listable); - if (!node.ShowAll) { node.ContentTypes = node.ContentTypes ?? (new ContentTypeEntry[] { }); @@ -92,7 +87,6 @@ private IEnumerable GetContentTypesToShow(ContentTypesAdm typesToShow = typesToShow .Where(ctd => node.ContentTypes.ToList() .Any(s => String.Equals(ctd.Name, s.ContentTypeId, StringComparison.OrdinalIgnoreCase))); - } return typesToShow.OrderBy(t => t.DisplayName); @@ -111,7 +105,6 @@ private List GetIconClasses(ContentTypeDefinition contentType, ContentTy .FirstOrDefault(); return AddPrefixToClasses(typeEntry.IconClass); - } } @@ -123,7 +116,5 @@ private List AddPrefixToClasses(string unprefixed) .ToList() ?? new List(); } - } - } diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Controllers/AdminController.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Controllers/AdminController.cs index 666db85c0e7..a89f434d149 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Controllers/AdminController.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Controllers/AdminController.cs @@ -108,7 +108,7 @@ public async Task List(ListContentsViewModel model, PagerParamete if (!string.IsNullOrEmpty(model.Options.SelectedContentType)) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(model.Options.SelectedContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(model.Options.SelectedContentType); if (contentTypeDefinition == null) return NotFound(); @@ -321,15 +321,13 @@ public async Task Create(string id) public Task CreatePOST(string id, [Bind(Prefix = "submit.Save")] string submitSave, string returnUrl) { var stayOnSamePage = submitSave == "submit.SaveAndContinue"; - return CreatePOST(id, returnUrl, stayOnSamePage, contentItem => + return CreatePOST(id, returnUrl, stayOnSamePage, async contentItem => { - var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); _notifier.Success(string.IsNullOrWhiteSpace(typeDefinition.DisplayName) ? T["Your content draft has been saved."] : T["Your {0} draft has been saved.", typeDefinition.DisplayName]); - - return Task.CompletedTask; }); } @@ -351,7 +349,7 @@ public async Task CreateAndPublishPOST(string id, [Bind(Prefix = { await _contentManager.PublishAsync(contentItem); - var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); _notifier.Success(string.IsNullOrWhiteSpace(typeDefinition.DisplayName) ? T["Your content has been published."] @@ -439,15 +437,13 @@ public async Task Edit(string contentItemId) public Task EditPOST(string contentItemId, [Bind(Prefix = "submit.Save")] string submitSave, string returnUrl) { var stayOnSamePage = submitSave == "submit.SaveAndContinue"; - return EditPOST(contentItemId, returnUrl, stayOnSamePage, contentItem => + return EditPOST(contentItemId, returnUrl, stayOnSamePage, async contentItem => { - var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); _notifier.Success(string.IsNullOrWhiteSpace(typeDefinition.DisplayName) ? T["Your content draft has been saved."] : T["Your {0} draft has been saved.", typeDefinition.DisplayName]); - - return Task.CompletedTask; }); } @@ -472,7 +468,7 @@ public async Task EditAndPublishPOST(string contentItemId, [Bind( { await _contentManager.PublishAsync(contentItem); - var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); _notifier.Success(string.IsNullOrWhiteSpace(typeDefinition.DisplayName) ? T["Your content has been published."] @@ -577,7 +573,7 @@ public async Task DiscardDraft(string contentItemId, string retur if (contentItem != null) { - var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); await _contentManager.DiscardDraftAsync(contentItem); @@ -601,7 +597,7 @@ public async Task Remove(string contentItemId, string returnUrl) if (contentItem != null) { - var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); await _contentManager.RemoveAsync(contentItem); @@ -629,7 +625,7 @@ public async Task Publish(string contentItemId, string returnUrl) await _contentManager.PublishAsync(contentItem); - var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); if (string.IsNullOrEmpty(typeDefinition.DisplayName)) { @@ -659,7 +655,7 @@ public async Task Unpublish(string contentItemId, string returnUr await _contentManager.UnpublishAsync(contentItem); - var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); if (string.IsNullOrEmpty(typeDefinition.DisplayName)) { @@ -676,7 +672,7 @@ public async Task Unpublish(string contentItemId, string returnUr private async Task> GetCreatableTypesAsync() { var creatable = new List(); - foreach (var ctd in _contentDefinitionManager.ListTypeDefinitions()) + foreach (var ctd in await _contentDefinitionManager.ListTypeDefinitionsAsync()) { if (ctd.Settings.ToObject().Creatable) { @@ -693,7 +689,7 @@ private async Task> GetCreatableTypesAsync() private async Task> GetListableTypesAsync() { var listable = new List(); - foreach (var ctd in _contentDefinitionManager.ListTypeDefinitions()) + foreach (var ctd in await _contentDefinitionManager.ListTypeDefinitionsAsync()) { if (ctd.Settings.ToObject().Listable) { diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/ContentsDriver.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/ContentsDriver.cs index e1892658bc7..58ce7d94a65 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/ContentsDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/ContentsDriver.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Display.ContentDisplay; using OrchardCore.ContentManagement.Display.ViewModels; @@ -19,14 +20,14 @@ public ContentsDriver(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public override IDisplayResult Display(ContentItem model, IUpdateModel updater) + public override async Task DisplayAsync(ContentItem model, IUpdateModel updater) { // We add custom alternates. This could be done generically to all shapes coming from ContentDisplayDriver but right now it's // only necessary on this shape. Otherwise c.f. ContentPartDisplayDriver var contentsMetadataShape = Shape("ContentsMetadata", new ContentItemViewModel(model)).Location("Detail", "Content:before"); - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(model.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(model.ContentType); if (contentTypeDefinition != null) { @@ -55,9 +56,9 @@ public override IDisplayResult Display(ContentItem model, IUpdateModel updater) ); } - public override IDisplayResult Edit(ContentItem contentItem, IUpdateModel updater) + public override async Task EditAsync(ContentItem contentItem, IUpdateModel updater) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); if (contentTypeDefinition == null) { diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/DateEditorDriver.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/DateEditorDriver.cs index 586b62c4614..66c99020e5a 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/DateEditorDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/DateEditorDriver.cs @@ -2,10 +2,10 @@ using System.Linq; using System.Threading.Tasks; using OrchardCore.ContentManagement.Display.ContentDisplay; +using OrchardCore.ContentManagement.Display.Models; using OrchardCore.ContentManagement.Metadata; using OrchardCore.Contents.Models; using OrchardCore.Contents.ViewModels; -using OrchardCore.DisplayManagement.ModelBinding; using OrchardCore.DisplayManagement.Views; using OrchardCore.Modules; @@ -22,9 +22,9 @@ public DateEditorDriver(IContentDefinitionManager contentDefinitionManager, ILoc _localClock = localClock; } - public override IDisplayResult Edit(CommonPart part) + public override async Task EditAsync(CommonPart part, BuildPartEditorContext context) { - var settings = GetSettings(part); + var settings = await GetSettingsAsync(part); if (settings.DisplayDateEditor) { @@ -37,14 +37,14 @@ public override IDisplayResult Edit(CommonPart part) return null; } - public override async Task UpdateAsync(CommonPart part, IUpdateModel updater) + public override async Task UpdateAsync(CommonPart part, UpdatePartEditorContext context) { - var settings = GetSettings(part); + var settings = await GetSettingsAsync(part); if (settings.DisplayDateEditor) { var model = new DateEditorViewModel(); - await updater.TryUpdateModelAsync(model, Prefix); + await context.Updater.TryUpdateModelAsync(model, Prefix); if (model.LocalDateTime == null) { @@ -56,14 +56,14 @@ public override async Task UpdateAsync(CommonPart part, IUpdateM } } - return Edit(part); + return await EditAsync(part, context); } - public CommonPartSettings GetSettings(CommonPart part) + public async Task GetSettingsAsync(CommonPart part) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => String.Equals(x.PartDefinition.Name, "CommonPart", StringComparison.Ordinal)); return contentTypePartDefinition.GetSettings(); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/OwnerEditorDriver.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/OwnerEditorDriver.cs index eeacede4419..25bed35731b 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/OwnerEditorDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/OwnerEditorDriver.cs @@ -46,7 +46,7 @@ public override async Task EditAsync(CommonPart part, BuildPartE return null; } - var settings = GetSettings(part); + var settings = await GetSettingsAsync(part); if (settings.DisplayOwnerEditor) { @@ -59,7 +59,7 @@ public override async Task EditAsync(CommonPart part, BuildPartE return null; } - public override async Task UpdateAsync(CommonPart part, BuildPartEditorContext context) + public override async Task UpdateAsync(CommonPart part, UpdatePartEditorContext context) { var currentUser = _httpContextAccessor.HttpContext?.User; @@ -68,7 +68,7 @@ public override async Task UpdateAsync(CommonPart part, BuildPar return null; } - var settings = GetSettings(part); + var settings = await GetSettingsAsync(part); if (!settings.DisplayOwnerEditor) { @@ -107,11 +107,11 @@ public override async Task UpdateAsync(CommonPart part, BuildPar return await EditAsync(part, context); } - public CommonPartSettings GetSettings(CommonPart part) + public async Task GetSettingsAsync(CommonPart part) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => String.Equals(x.PartDefinition.Name, "CommonPart", StringComparison.Ordinal)); return contentTypePartDefinition.GetSettings(); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Indexing/ContentItemIndexCoordinator.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Indexing/ContentItemIndexCoordinator.cs index a64d3747ad4..06ebc133539 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Indexing/ContentItemIndexCoordinator.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Indexing/ContentItemIndexCoordinator.cs @@ -1,10 +1,10 @@ using System.Collections.Generic; using System.Threading.Tasks; -using OrchardCore.Modules; using Microsoft.Extensions.Logging; using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Metadata; using OrchardCore.Indexing; +using OrchardCore.Modules; namespace OrchardCore.Contents.Indexing { @@ -36,7 +36,7 @@ public ContentItemIndexCoordinator( public async Task BuildIndexAsync(BuildIndexContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) { diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Migrations.cs index 088b168c338..c667dcb700e 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Migrations.cs @@ -1,5 +1,6 @@ -using OrchardCore.ContentManagement.Metadata.Settings; +using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata; +using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.Data.Migration; namespace OrchardCore.Contents @@ -13,13 +14,13 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public int Create() + public async Task CreateAsync() { - _contentDefinitionManager.AlterPartDefinition("CommonPart", builder => builder + await _contentDefinitionManager.AlterPartDefinitionAsync("CommonPart", builder => builder .Attachable() .WithDescription("Provides an editor for the common properties of a content item.")); return 1; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Security/ContentTypePermissions.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Security/ContentTypePermissions.cs index 8198693bb79..c702340b5ed 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Security/ContentTypePermissions.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Security/ContentTypePermissions.cs @@ -1,14 +1,15 @@ using System; -using System.Linq; using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Models; -using OrchardCore.Security.Permissions; using OrchardCore.ContentManagement.Metadata.Settings; +using OrchardCore.Security.Permissions; namespace OrchardCore.Contents.Security { - public class ContentTypePermissions : IPermissionProvider + public class ContentTypePermissions : IAsyncPermissionProvider { private static readonly Permission PublishContent = new Permission("Publish_{0}", "Publish or unpublish {0} for others", new[] { Permissions.PublishContent }); private static readonly Permission PublishOwnContent = new Permission("PublishOwn_{0}", "Publish or unpublish {0}", new[] { PublishContent, Permissions.PublishOwnContent }); @@ -41,19 +42,28 @@ public ContentTypePermissions(IContentDefinitionManager contentDefinitionManager _contentDefinitionManager = contentDefinitionManager; } + // Sync version for backward compatibility. public IEnumerable GetPermissions() + { + return GetPermissionsAsync().GetAwaiter().GetResult(); + } + + public async Task> GetPermissionsAsync() { // manage rights only for Securable types - var securableTypes = _contentDefinitionManager.ListTypeDefinitions() + var securableTypes = (await _contentDefinitionManager.ListTypeDefinitionsAsync()) .Where(ctd => ctd.Settings.ToObject().Securable); + var permissions = new List(); foreach (var typeDefinition in securableTypes) { foreach (var permissionTemplate in PermissionTemplates.Values) { - yield return CreateDynamicPermission(permissionTemplate, typeDefinition); + permissions.Add(CreateDynamicPermission(permissionTemplate, typeDefinition)); } } + + return permissions; } public IEnumerable GetDefaultStereotypes() diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/TagHelpers/ContentLinkTagHelper.cs b/src/OrchardCore.Modules/OrchardCore.Contents/TagHelpers/ContentLinkTagHelper.cs index b26953a3369..b09634b49b7 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/TagHelpers/ContentLinkTagHelper.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/TagHelpers/ContentLinkTagHelper.cs @@ -160,7 +160,7 @@ public override async Task ProcessAsync(TagHelperContext tagHelperContext, TagHe } else { - var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); output.Content.Append(typeDefinition.ToString()); } } diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Admin/Create.cshtml b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Admin/Create.cshtml index 8f2ba0ae5c0..9c8ef6e8534 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Admin/Create.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Admin/Create.cshtml @@ -6,7 +6,7 @@ @{ ContentItem contentItem = Model.ContentItem; - var contentTypeDefinition = ContentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var contentTypeDefinition = await ContentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); var typeDisplayName = contentTypeDefinition?.DisplayName ?? contentItem.ContentType.CamelFriendly(); } diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Admin/Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Admin/Edit.cshtml index 6c86fbfb59a..605c3a0a33b 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Admin/Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Admin/Edit.cshtml @@ -6,7 +6,7 @@ @{ ContentItem contentItem = Model.ContentItem; - var contentTypeDefinition = ContentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var contentTypeDefinition = await ContentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); var typeDisplayName = contentTypeDefinition?.DisplayName ?? contentItem.ContentType.CamelFriendly(); } diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/ContentDeploymentStep.Fields.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/ContentDeploymentStep.Fields.Edit.cshtml index df8589f49a1..e786f479eff 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/ContentDeploymentStep.Fields.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/ContentDeploymentStep.Fields.Edit.cshtml @@ -10,7 +10,7 @@
    - @foreach (var contentTypeDefinition in ContentDefinitionManager.ListTypeDefinitions().OrderBy(i => i.Name)) + @foreach (var contentTypeDefinition in (await ContentDefinitionManager.ListTypeDefinitionsAsync()).OrderBy(i => i.Name)) { var name = contentTypeDefinition.Name; var checkd = contentTypes?.Contains(name); diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/ContentDeploymentStep.Fields.Summary.cshtml b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/ContentDeploymentStep.Fields.Summary.cshtml index dca63f34729..d0204b45521 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/ContentDeploymentStep.Fields.Summary.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/ContentDeploymentStep.Fields.Summary.cshtml @@ -8,7 +8,7 @@
    @T["Content"]
    @if (contentTypes != null && contentTypes.Length > 0) { - @foreach (var contentTypeDefinition in ContentDefinitionManager.ListTypeDefinitions()) + @foreach (var contentTypeDefinition in await ContentDefinitionManager.ListTypeDefinitionsAsync()) { if (contentTypes.Contains(contentTypeDefinition.Name)) { diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/ContentTypesAdminNode.Fields.TreeSummary.cshtml b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/ContentTypesAdminNode.Fields.TreeSummary.cshtml index 5748ff45d05..f3969718af1 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/ContentTypesAdminNode.Fields.TreeSummary.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/ContentTypesAdminNode.Fields.TreeSummary.cshtml @@ -4,7 +4,7 @@ @inject OrchardCore.ContentManagement.Metadata.IContentDefinitionManager ContentDefinitionManager @{ - var allContentTypes = ContentDefinitionManager.ListTypeDefinitions(); + var allContentTypes = await ContentDefinitionManager.ListTypeDefinitionsAsync(); var selectedContentTypes = Model.Value.ContentTypes ?? new ContentTypeEntry[] { } ; diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Workflows/Drivers/ContentEventDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Workflows/Drivers/ContentEventDisplayDriver.cs index 036d2c432c8..3a177ac624a 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Workflows/Drivers/ContentEventDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Workflows/Drivers/ContentEventDisplayDriver.cs @@ -29,7 +29,7 @@ public async override Task UpdateAsync(TActivity model, IUpdateM var viewModel = new TViewModel(); if (await updater.TryUpdateModelAsync(viewModel, Prefix, x => x.SelectedContentTypeNames)) { - model.ContentTypeFilter = FilterContentTypesQuery(viewModel.SelectedContentTypeNames).ToList(); + model.ContentTypeFilter = (await FilterContentTypesQueryAsync(viewModel.SelectedContentTypeNames)).ToList(); } return Edit(model); } @@ -38,9 +38,9 @@ public override IDisplayResult Display(TActivity activity) { return Combine( Shape($"{typeof(TActivity).Name}_Fields_Thumbnail", new ContentEventViewModel(activity)).Location("Thumbnail", "Content"), - Factory($"{typeof(TActivity).Name}_Fields_Design", ctx => + Factory($"{typeof(TActivity).Name}_Fields_Design", async ctx => { - var contentTypeDefinitions = ContentDefinitionManager.ListTypeDefinitions().ToDictionary(x => x.Name); + var contentTypeDefinitions = (await ContentDefinitionManager.ListTypeDefinitionsAsync()).ToDictionary(x => x.Name); var selectedContentTypeDefinitions = activity.ContentTypeFilter.Select(x => contentTypeDefinitions[x]).ToList(); var shape = new ContentEventViewModel(); @@ -48,7 +48,7 @@ public override IDisplayResult Display(TActivity activity) shape.Activity = activity; return shape; - + }).Location("Design", "Content") ); } @@ -56,9 +56,9 @@ public override IDisplayResult Display(TActivity activity) /// /// Filters out any content type that doesn't exist. /// - protected IEnumerable FilterContentTypesQuery(IEnumerable contentTypeNames) + protected async Task> FilterContentTypesQueryAsync(IEnumerable contentTypeNames) { - var contentTypeDefinitions = ContentDefinitionManager.ListTypeDefinitions().ToDictionary(x => x.Name); + var contentTypeDefinitions = (await ContentDefinitionManager.ListTypeDefinitionsAsync()).ToDictionary(x => x.Name); return contentTypeNames.Where(x => !string.IsNullOrWhiteSpace(x) && contentTypeDefinitions.ContainsKey(x)); } } diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Workflows/Drivers/CreateContentTaskDisplay.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Workflows/Drivers/CreateContentTaskDisplay.cs index f4c24f89554..0b8ea6f6b94 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Workflows/Drivers/CreateContentTaskDisplay.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Workflows/Drivers/CreateContentTaskDisplay.cs @@ -1,7 +1,7 @@ using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Rendering; using OrchardCore.ContentManagement.Metadata; -using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.Contents.Workflows.Activities; using OrchardCore.Contents.Workflows.ViewModels; using OrchardCore.Workflows.Models; @@ -17,9 +17,9 @@ public CreateContentTaskDisplay(IContentDefinitionManager contentDefinitionManag _contentDefinitionManager = contentDefinitionManager; } - protected override void EditActivity(CreateContentTask activity, CreateContentTaskViewModel model) + protected override async Task EditActivityAsync(CreateContentTask activity, CreateContentTaskViewModel model) { - model.AvailableContentTypes = _contentDefinitionManager.ListTypeDefinitions() + model.AvailableContentTypes = (await _contentDefinitionManager.ListTypeDefinitionsAsync()) .Select(x => new SelectListItem { Text = x.DisplayName, Value = x.Name }) .ToList(); diff --git a/src/OrchardCore.Modules/OrchardCore.CustomSettings/AdminMenu.cs b/src/OrchardCore.Modules/OrchardCore.CustomSettings/AdminMenu.cs index 1e385f808ff..aeafde0fb7c 100644 --- a/src/OrchardCore.Modules/OrchardCore.CustomSettings/AdminMenu.cs +++ b/src/OrchardCore.Modules/OrchardCore.CustomSettings/AdminMenu.cs @@ -20,14 +20,14 @@ public AdminMenu( public IStringLocalizer T { get; set; } - public Task BuildNavigationAsync(string name, NavigationBuilder builder) + public async Task BuildNavigationAsync(string name, NavigationBuilder builder) { if (!String.Equals(name, "admin", StringComparison.OrdinalIgnoreCase)) { - return Task.CompletedTask; + return; } - foreach (var type in _customSettingsService.GetAllSettingsTypes()) + foreach (var type in await _customSettingsService.GetAllSettingsTypesAsync()) { builder .Add(T["Configuration"], configuration => configuration @@ -39,8 +39,6 @@ public Task BuildNavigationAsync(string name, NavigationBuilder builder) .LocalNav() ))); } - - return Task.CompletedTask; } } } diff --git a/src/OrchardCore.Modules/OrchardCore.CustomSettings/Deployment/CustomSettingsDeploymentSource.cs b/src/OrchardCore.Modules/OrchardCore.CustomSettings/Deployment/CustomSettingsDeploymentSource.cs index 21f2c219a6f..86f506b5efb 100644 --- a/src/OrchardCore.Modules/OrchardCore.CustomSettings/Deployment/CustomSettingsDeploymentSource.cs +++ b/src/OrchardCore.Modules/OrchardCore.CustomSettings/Deployment/CustomSettingsDeploymentSource.cs @@ -27,8 +27,8 @@ public async Task ProcessDeploymentStepAsync(DeploymentStep step, DeploymentPlan var settingsList = new List { new JProperty("name", "custom-settings") }; var settingsTypes = customSettingsStep.IncludeAll - ? _customSettingsService.GetAllSettingsTypes().ToArray() - : _customSettingsService.GetSettingsTypes(customSettingsStep.SettingsTypeNames).ToArray(); + ? (await _customSettingsService.GetAllSettingsTypesAsync()).ToArray() + : (await _customSettingsService.GetSettingsTypesAsync(customSettingsStep.SettingsTypeNames)).ToArray(); foreach (var settingsType in settingsTypes) { @@ -48,4 +48,4 @@ public async Task ProcessDeploymentStepAsync(DeploymentStep step, DeploymentPlan result.Steps.Add(new JObject(settingsList.ToArray())); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.CustomSettings/Deployment/CustomSettingsDeploymentStepDriver.cs b/src/OrchardCore.Modules/OrchardCore.CustomSettings/Deployment/CustomSettingsDeploymentStepDriver.cs index 5de58e327e7..ecfece6f31b 100644 --- a/src/OrchardCore.Modules/OrchardCore.CustomSettings/Deployment/CustomSettingsDeploymentStepDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.CustomSettings/Deployment/CustomSettingsDeploymentStepDriver.cs @@ -30,11 +30,11 @@ public override IDisplayResult Display(CustomSettingsDeploymentStep step) public override IDisplayResult Edit(CustomSettingsDeploymentStep step) { - return Initialize("CustomSettingsDeploymentStep_Fields_Edit", model => + return Initialize("CustomSettingsDeploymentStep_Fields_Edit", async model => { model.IncludeAll = step.IncludeAll; model.SettingsTypeNames = step.SettingsTypeNames; - model.AllSettingsTypeNames = _customSettingsService.GetAllSettingsTypeNames().ToArray(); + model.AllSettingsTypeNames = (await _customSettingsService.GetAllSettingsTypeNamesAsync()).ToArray(); }).Location("Content"); } @@ -56,4 +56,4 @@ await updater.TryUpdateModelAsync(step, return Edit(step); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.CustomSettings/Drivers/CustomSettingsDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.CustomSettings/Drivers/CustomSettingsDisplayDriver.cs index 98f316db7df..8866e5c86b6 100644 --- a/src/OrchardCore.Modules/OrchardCore.CustomSettings/Drivers/CustomSettingsDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.CustomSettings/Drivers/CustomSettingsDisplayDriver.cs @@ -28,7 +28,7 @@ public CustomSettingsDisplayDriver( public override async Task EditAsync(ISite site, BuildEditorContext context) { - var contentTypeDefinition = _customSettingsService.GetSettingsType(context.GroupId); + var contentTypeDefinition = await _customSettingsService.GetSettingsTypeAsync(context.GroupId); if (contentTypeDefinition == null) { return null; @@ -52,7 +52,7 @@ public override async Task EditAsync(ISite site, BuildEditorCont public override async Task UpdateAsync(ISite site, UpdateEditorContext context) { - var contentTypeDefinition = _customSettingsService.GetSettingsType(context.GroupId); + var contentTypeDefinition = await _customSettingsService.GetSettingsTypeAsync(context.GroupId); if (contentTypeDefinition == null) { return null; @@ -73,4 +73,4 @@ public override async Task UpdateAsync(ISite site, UpdateEditorC return await EditAsync(site, context); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.CustomSettings/Permissions.cs b/src/OrchardCore.Modules/OrchardCore.CustomSettings/Permissions.cs index a7ee786402b..3c97ca5b2ae 100644 --- a/src/OrchardCore.Modules/OrchardCore.CustomSettings/Permissions.cs +++ b/src/OrchardCore.Modules/OrchardCore.CustomSettings/Permissions.cs @@ -1,13 +1,14 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.CustomSettings.Services; using OrchardCore.Security.Permissions; namespace OrchardCore.CustomSettings { - public class Permissions : IPermissionProvider + public class Permissions : IAsyncPermissionProvider { private static readonly Permission ManageCustomSettings = new Permission("ManageCustomSettings_{0}", "Manage Custom Settings - {0}", new[] { new Permission("ManageResourceSettings") }); @@ -18,18 +19,24 @@ public Permissions(CustomSettingsService customSettingsService) _customSettingsService = customSettingsService; } + // Sync version for backward compatibility. public IEnumerable GetPermissions() + { + return GetPermissionsAsync().GetAwaiter().GetResult(); + } + + public async Task> GetPermissionsAsync() { var list = new List(); - foreach(var type in _customSettingsService.GetAllSettingsTypes()) + foreach (var type in await _customSettingsService.GetAllSettingsTypesAsync()) { list.Add(CreatePermissionForType(type)); } return list; } - + public static string CreatePermissionName(string name) { return String.Format(ManageCustomSettings.Name, name); diff --git a/src/OrchardCore.Modules/OrchardCore.CustomSettings/Recipes/CustomSettingsStep.cs b/src/OrchardCore.Modules/OrchardCore.CustomSettings/Recipes/CustomSettingsStep.cs index 6f95a8538b7..2be6e736c07 100644 --- a/src/OrchardCore.Modules/OrchardCore.CustomSettings/Recipes/CustomSettingsStep.cs +++ b/src/OrchardCore.Modules/OrchardCore.CustomSettings/Recipes/CustomSettingsStep.cs @@ -40,7 +40,7 @@ public async Task ExecuteAsync(RecipeExecutionContext context) var customSettingsNames = (from customSettings in customSettingsList select customSettings.Name).ToArray(); - var customSettingsTypes = _customSettingsService.GetSettingsTypes(customSettingsNames).ToArray(); + var customSettingsTypes = (await _customSettingsService.GetSettingsTypesAsync(customSettingsNames)).ToArray(); foreach (var customSettingsType in customSettingsTypes) { @@ -60,4 +60,4 @@ public async Task ExecuteAsync(RecipeExecutionContext context) await _siteService.UpdateSiteSettingsAsync(siteSettings); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.CustomSettings/Services/CustomSettingsService.cs b/src/OrchardCore.Modules/OrchardCore.CustomSettings/Services/CustomSettingsService.cs index c1a0ede3a21..7b1d2cf2151 100644 --- a/src/OrchardCore.Modules/OrchardCore.CustomSettings/Services/CustomSettingsService.cs +++ b/src/OrchardCore.Modules/OrchardCore.CustomSettings/Services/CustomSettingsService.cs @@ -4,12 +4,12 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; +using Newtonsoft.Json.Linq; +using OrchardCore.ContentManagement; +using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentManagement.Metadata.Settings; -using OrchardCore.ContentManagement.Metadata; using OrchardCore.Settings; -using Newtonsoft.Json.Linq; -using OrchardCore.ContentManagement; namespace OrchardCore.CustomSettings.Services { @@ -20,7 +20,7 @@ public class CustomSettingsService private readonly IHttpContextAccessor _httpContextAccessor; private readonly IAuthorizationService _authorizationService; private readonly IContentDefinitionManager _contentDefinitionManager; - private readonly Lazy> _settingsTypes; + private IDictionary _settingsTypes; public CustomSettingsService( ISiteService siteService, @@ -34,44 +34,56 @@ public CustomSettingsService( _httpContextAccessor = httpContextAccessor; _authorizationService = authorizationService; _contentDefinitionManager = contentDefinitionManager; - _settingsTypes = new Lazy>( - () => _contentDefinitionManager - .ListTypeDefinitions() - .Where(x => x.Settings.ToObject().Stereotype == "CustomSettings") - .ToDictionary(x => x.Name)); } - public IEnumerable GetAllSettingsTypeNames() + public async Task> GetAllSettingsTypeNamesAsync() { - return _settingsTypes.Value.Keys; + await EnsureSettingsTypesAsync(); + return _settingsTypes.Keys; } - public IEnumerable GetAllSettingsTypes() + public async Task> GetAllSettingsTypesAsync() { - return _settingsTypes.Value.Values; + await EnsureSettingsTypesAsync(); + return _settingsTypes.Values; } - public IEnumerable GetSettingsTypes(params string[] settingsTypeNames) + public async Task> GetSettingsTypesAsync(params string[] settingsTypeNames) { + await EnsureSettingsTypesAsync(); + + var settingsTypes = new List(); foreach (var settingsTypeName in settingsTypeNames) { ContentTypeDefinition settingsType; - if (_settingsTypes.Value.TryGetValue(settingsTypeName, out settingsType)) + if (_settingsTypes.TryGetValue(settingsTypeName, out settingsType)) { - yield return settingsType; + settingsTypes.Add(settingsType); } } + + return settingsTypes; } - public ContentTypeDefinition GetSettingsType(string settingsTypeName) + public async Task GetSettingsTypeAsync(string settingsTypeName) { - ContentTypeDefinition settingsType; + await EnsureSettingsTypesAsync(); - _settingsTypes.Value.TryGetValue(settingsTypeName, out settingsType); + _settingsTypes.TryGetValue(settingsTypeName, out var settingsType); return settingsType; } + private async Task EnsureSettingsTypesAsync() + { + if (_settingsTypes == null) + { + _settingsTypes = (await _contentDefinitionManager.ListTypeDefinitionsAsync()) + .Where(x => x.Settings.ToObject().Stereotype == "CustomSettings") + .ToDictionary(x => x.Name); + } + } + public async Task CanUserCreateSettingsAsync(ContentTypeDefinition settingsType) { var user = _httpContextAccessor.HttpContext?.User; @@ -79,15 +91,15 @@ public async Task CanUserCreateSettingsAsync(ContentTypeDefinition setting return await _authorizationService.AuthorizeAsync(user, Permissions.CreatePermissionForType(settingsType)); } - public Task GetSettingsAsync(string settingsTypeName, Action isNew = null) + public async Task GetSettingsAsync(string settingsTypeName, Action isNew = null) { - var settingsType = GetSettingsType(settingsTypeName); + var settingsType = await GetSettingsTypeAsync(settingsTypeName); if (settingsType == null) { - return Task.FromResult(null); + return null; } - return GetSettingsAsync(settingsType, isNew); + return await GetSettingsAsync(settingsType, isNew); } public async Task GetSettingsAsync(ContentTypeDefinition settingsType, Action isNew = null) @@ -116,4 +128,4 @@ public async Task GetSettingsAsync(ISite site, ContentTypeDefinitio return contentItem; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Facebook/Widgets/Drivers/FacebookPluginPartDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.Facebook/Widgets/Drivers/FacebookPluginPartDisplayDriver.cs index 0258e9363a9..4f7a63a792a 100644 --- a/src/OrchardCore.Modules/OrchardCore.Facebook/Widgets/Drivers/FacebookPluginPartDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Facebook/Widgets/Drivers/FacebookPluginPartDisplayDriver.cs @@ -1,5 +1,6 @@ -using OrchardCore.Facebook.Widgets.Models; -using OrchardCore.Facebook.Widgets.ViewModels; +using System; +using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Localization; @@ -7,13 +8,10 @@ using OrchardCore.ContentManagement.Metadata; using OrchardCore.DisplayManagement.ModelBinding; using OrchardCore.DisplayManagement.Views; -using OrchardCore.Settings; -using OrchardCore.Mvc.ModelBinding; -using System; -using System.Linq; -using System.Threading.Tasks; -using OrchardCore.ContentManagement.Display.Models; +using OrchardCore.Facebook.Widgets.Models; using OrchardCore.Facebook.Widgets.Settings; +using OrchardCore.Facebook.Widgets.ViewModels; +using OrchardCore.Settings; namespace OrchardCore.Facebook.Widgets.Drivers { @@ -43,14 +41,14 @@ IStringLocalizer localizer public override IDisplayResult Display(FacebookPluginPart part) { return Combine( - Initialize("FacebookPluginPart", m => BuildViewModel(m, part)) + Initialize("FacebookPluginPart", m => BuildViewModelAsync(m, part)) .Location("Detail", "Content:10"), - Initialize("FacebookPluginPart_Summary", m => BuildViewModel(m, part)) + Initialize("FacebookPluginPart_Summary", m => BuildViewModelAsync(m, part)) .Location("Summary", "Content:10") ); } - private void BuildViewModel(FacebookPluginPartViewModel model, FacebookPluginPart part) + private async Task BuildViewModelAsync(FacebookPluginPartViewModel model, FacebookPluginPart part) { if (model == null) { @@ -58,29 +56,29 @@ private void BuildViewModel(FacebookPluginPartViewModel model, FacebookPluginPar } model.FacebookPluginPart = part ?? throw new ArgumentNullException(nameof(part)); - model.Settings = GetFacebookPluginPartSettings(part); + model.Settings = await GetFacebookPluginPartSettingsAsync(part); model.Liquid = part.Liquid; model.ContentItem = part.ContentItem; } public override IDisplayResult Edit(FacebookPluginPart part) { - return Initialize("FacebookPluginPart_Edit", model => + return Initialize("FacebookPluginPart_Edit", async model => { - model.Settings = GetFacebookPluginPartSettings(part); + model.Settings = await GetFacebookPluginPartSettingsAsync(part); model.FacebookPluginPart = part; model.Liquid = string.IsNullOrWhiteSpace(part.Liquid) ? model.Settings.Liquid : part.Liquid; }); } - private FacebookPluginPartSettings GetFacebookPluginPartSettings(FacebookPluginPart part) + private async Task GetFacebookPluginPartSettingsAsync(FacebookPluginPart part) { if (part == null) { throw new ArgumentNullException(nameof(part)); } - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => String.Equals(x.PartDefinition.Name, nameof(FacebookPluginPart), StringComparison.Ordinal)); return contentTypePartDefinition.GetSettings(); } diff --git a/src/OrchardCore.Modules/OrchardCore.Facebook/Widgets/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Facebook/Widgets/Migrations.cs index 507fe56c889..42503068025 100644 --- a/src/OrchardCore.Modules/OrchardCore.Facebook/Widgets/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Facebook/Widgets/Migrations.cs @@ -1,10 +1,9 @@ -using OrchardCore.Facebook.Widgets.Models; +using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.Data.Migration; +using OrchardCore.Facebook.Widgets.Models; using OrchardCore.Recipes.Services; -using System.Threading.Tasks; -using OrchardCore.Facebook.Widgets.Settings; namespace OrchardCore.Facebook.Widgets { @@ -21,7 +20,7 @@ public WidgetMigrations(IRecipeMigrator recipeMigrator, IContentDefinitionManage public async Task CreateAsync() { - _contentDefinitionManager.AlterPartDefinition(nameof(FacebookPluginPart), builder => builder + await _contentDefinitionManager.AlterPartDefinitionAsync(nameof(FacebookPluginPart), builder => builder .Attachable() .WithDescription("Provides a facebook plugin part to create facebook social plugin widgets.")); @@ -29,4 +28,4 @@ public async Task CreateAsync() return await Task.FromResult(1); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Flows/Drivers/BagPartDisplay.cs b/src/OrchardCore.Modules/OrchardCore.Flows/Drivers/BagPartDisplay.cs index dd604458c0a..43654e1c029 100644 --- a/src/OrchardCore.Modules/OrchardCore.Flows/Drivers/BagPartDisplay.cs +++ b/src/OrchardCore.Modules/OrchardCore.Flows/Drivers/BagPartDisplay.cs @@ -47,15 +47,15 @@ public override IDisplayResult Display(BagPart bagPart, BuildPartDisplayContext public override IDisplayResult Edit(BagPart bagPart, BuildPartEditorContext context) { - return Initialize("BagPart_Edit", m => + return Initialize("BagPart_Edit", async m => { m.BagPart = bagPart; m.Updater = context.Updater; - m.ContainedContentTypeDefinitions = GetContainedContentTypes(context.TypePartDefinition); + m.ContainedContentTypeDefinitions = await GetContainedContentTypesAsync(context.TypePartDefinition); }); } - public override async Task UpdateAsync(BagPart part, BuildPartEditorContext context) + public override async Task UpdateAsync(BagPart part, UpdatePartEditorContext context) { var contentItemDisplayManager = _serviceProvider.GetRequiredService(); var model = new BagPartEditViewModel { BagPart = part }; @@ -75,10 +75,18 @@ public override async Task UpdateAsync(BagPart part, BuildPartEd return Edit(part, context); } - private IEnumerable GetContainedContentTypes(ContentTypePartDefinition typePartDefinition) + private async Task> GetContainedContentTypesAsync(ContentTypePartDefinition typePartDefinition) { var settings = typePartDefinition.Settings.ToObject(); - return settings.ContainedContentTypes.Select(contentType => _contentDefinitionManager.GetTypeDefinition(contentType)); + + var typeDefinitions = new List(); + + foreach (var contentType in settings.ContainedContentTypes) + { + typeDefinitions.Add(await _contentDefinitionManager.GetTypeDefinitionAsync(contentType)); + } + + return typeDefinitions; } } } diff --git a/src/OrchardCore.Modules/OrchardCore.Flows/Drivers/FlowPartDisplay.cs b/src/OrchardCore.Modules/OrchardCore.Flows/Drivers/FlowPartDisplay.cs index 3c69413f107..2df0b4a1bc9 100644 --- a/src/OrchardCore.Modules/OrchardCore.Flows/Drivers/FlowPartDisplay.cs +++ b/src/OrchardCore.Modules/OrchardCore.Flows/Drivers/FlowPartDisplay.cs @@ -47,7 +47,7 @@ public override IDisplayResult Edit(FlowPart flowPart, BuildPartEditorContext co }); } - public override async Task UpdateAsync(FlowPart part, BuildPartEditorContext context) + public override async Task UpdateAsync(FlowPart part, UpdatePartEditorContext context) { var contentItemDisplayManager = _serviceProvider.GetRequiredService(); diff --git a/src/OrchardCore.Modules/OrchardCore.Flows/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Flows/Migrations.cs index 671d1f8b8f3..d19fd5411c7 100644 --- a/src/OrchardCore.Modules/OrchardCore.Flows/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Flows/Migrations.cs @@ -1,5 +1,6 @@ -using OrchardCore.ContentManagement.Metadata.Settings; +using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata; +using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.Data.Migration; namespace OrchardCore.Flows @@ -13,18 +14,18 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public int Create() + public async Task CreateAsync() { - _contentDefinitionManager.AlterPartDefinition("FlowPart", builder => builder + await _contentDefinitionManager.AlterPartDefinitionAsync("FlowPart", builder => builder .Attachable() .WithDescription("Provides a customizable body for your content item.")); return 1; } - public int UpdateFrom1() + public async Task UpdateFrom1() { - _contentDefinitionManager.AlterPartDefinition("BagPart", builder => builder + await _contentDefinitionManager.AlterPartDefinitionAsync("BagPart", builder => builder .Attachable() .Reusable() .WithDescription("Provides a collection behavior for your content item.")); @@ -32,4 +33,4 @@ public int UpdateFrom1() return 2; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Flows/Settings/BagPartSettingsDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.Flows/Settings/BagPartSettingsDisplayDriver.cs index b7f334c34a1..99355b68e10 100644 --- a/src/OrchardCore.Modules/OrchardCore.Flows/Settings/BagPartSettingsDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Flows/Settings/BagPartSettingsDisplayDriver.cs @@ -2,8 +2,8 @@ using System.Collections.Specialized; using System.Threading.Tasks; using Microsoft.Extensions.Localization; -using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentManagement.Metadata; +using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentTypes.Editors; using OrchardCore.DisplayManagement.ModelBinding; using OrchardCore.DisplayManagement.Views; @@ -33,14 +33,14 @@ public override IDisplayResult Edit(ContentTypePartDefinition contentTypePartDef return null; } - return Initialize("BagPartSettings_Edit", model => + return Initialize("BagPartSettings_Edit", async model => { model.BagPartSettings = contentTypePartDefinition.Settings.ToObject(); model.ContainedContentTypes = model.BagPartSettings.ContainedContentTypes; model.DisplayType = model.BagPartSettings.DisplayType; model.ContentTypes = new NameValueCollection(); - foreach (var contentTypeDefinition in _contentDefinitionManager.ListTypeDefinitions()) + foreach (var contentTypeDefinition in await _contentDefinitionManager.ListTypeDefinitionsAsync()) { model.ContentTypes.Add(contentTypeDefinition.Name, contentTypeDefinition.DisplayName); } @@ -71,4 +71,4 @@ public override async Task UpdateAsync(ContentTypePartDefinition return Edit(contentTypePartDefinition, context.Updater); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Flows/Views/FlowPart.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.Flows/Views/FlowPart.Edit.cshtml index ebb9baba697..b74b3289ae7 100644 --- a/src/OrchardCore.Modules/OrchardCore.Flows/Views/FlowPart.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Flows/Views/FlowPart.Edit.cshtml @@ -8,7 +8,7 @@ @inject OrchardCore.ContentManagement.Display.IContentItemDisplayManager ContentItemDisplayManager @{ - var widgetContentTypes = ContentDefinitionManager.ListTypeDefinitions().Where(t => t.Settings.ToObject().Stereotype == "Widget"); + var widgetContentTypes = (await ContentDefinitionManager.ListTypeDefinitionsAsync()).Where(t => t.Settings.ToObject().Stereotype == "Widget"); var widgetTemplatePlaceholderId = Html.Id("widgetTemplatePlaceholder"); } diff --git a/src/OrchardCore.Modules/OrchardCore.Flows/Views/Widget-Bag.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.Flows/Views/Widget-Bag.Edit.cshtml index 38d8086db3c..4a33f748be5 100644 --- a/src/OrchardCore.Modules/OrchardCore.Flows/Views/Widget-Bag.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Flows/Views/Widget-Bag.Edit.cshtml @@ -2,7 +2,7 @@ @{ ContentItem contentItem = Model.ContentItem; - var contentType = ContentDefinitionManager.GetTypeDefinition(contentItem.ContentType).DisplayName; + var contentType = (await ContentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType)).DisplayName; }
    diff --git a/src/OrchardCore.Modules/OrchardCore.Flows/Views/Widget-Flow.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.Flows/Views/Widget-Flow.Edit.cshtml index 2f474427566..d19c54f4ecf 100644 --- a/src/OrchardCore.Modules/OrchardCore.Flows/Views/Widget-Flow.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Flows/Views/Widget-Flow.Edit.cshtml @@ -3,9 +3,9 @@ @{ var contentItem = (IContent)Model.ContentItem; - var contentTypeDisplayText = ContentDefinitionManager.GetTypeDefinition((string)Model.ContentItem.ContentType).DisplayName; + var contentTypeDisplayText = (await ContentDefinitionManager.GetTypeDefinitionAsync((string)Model.ContentItem.ContentType)).DisplayName; var contentItemDisplayText = contentItem.ContentItem.DisplayText; - var widgetContentTypes = ContentDefinitionManager.ListTypeDefinitions().Where(t => t.Settings.ToObject().Stereotype == "Widget"); + var widgetContentTypes = (await ContentDefinitionManager.ListTypeDefinitionsAsync()).Where(t => t.Settings.ToObject().Stereotype == "Widget"); }
    diff --git a/src/OrchardCore.Modules/OrchardCore.Forms/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Forms/Migrations.cs index dec542fb046..49c962b6b70 100644 --- a/src/OrchardCore.Modules/OrchardCore.Forms/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Forms/Migrations.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.Data.Migration; @@ -13,94 +14,94 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public int Create() + public async Task CreateAsync() { // Form - _contentDefinitionManager.AlterPartDefinition("FormPart", part => part + await _contentDefinitionManager.AlterPartDefinitionAsync("FormPart", part => part .Attachable() .WithDescription("Turns your content item into a form.")); - _contentDefinitionManager.AlterTypeDefinition("Form", type => type + await _contentDefinitionManager.AlterTypeDefinitionAsync("Form", type => type .WithPart("TitlePart") .WithPart("FormPart") .WithPart("FlowPart") .Stereotype("Widget")); // FormElement - _contentDefinitionManager.AlterPartDefinition("FormElementPart", part => part + await _contentDefinitionManager.AlterPartDefinitionAsync("FormElementPart", part => part .WithDescription("Provides attributes common to all form elements.")); // FormInputElement - _contentDefinitionManager.AlterPartDefinition("FormInputElementPart", part => part + await _contentDefinitionManager.AlterPartDefinitionAsync("FormInputElementPart", part => part .WithDescription("Provides attributes common to all input form elements.")); // Label - _contentDefinitionManager.AlterPartDefinition("LabelPart", part => part + await _contentDefinitionManager.AlterPartDefinitionAsync("LabelPart", part => part .WithDescription("Provides label properties.")); - _contentDefinitionManager.AlterTypeDefinition("Label", type => type + await _contentDefinitionManager.AlterTypeDefinitionAsync("Label", type => type .WithPart("TitlePart") .WithPart("FormElementPart") .WithPart("LabelPart") .Stereotype("Widget")); // Input - _contentDefinitionManager.AlterPartDefinition("InputPart", part => part + await _contentDefinitionManager.AlterPartDefinitionAsync("InputPart", part => part .WithDescription("Provides input field properties.")); - _contentDefinitionManager.AlterTypeDefinition("Input", type => type + await _contentDefinitionManager.AlterTypeDefinitionAsync("Input", type => type .WithPart("FormInputElementPart") .WithPart("FormElementPart") .WithPart("InputPart") .Stereotype("Widget")); // TextArea - _contentDefinitionManager.AlterPartDefinition("TextAreaPart", part => part + await _contentDefinitionManager.AlterPartDefinitionAsync("TextAreaPart", part => part .WithDescription("Provides text area properties.")); - _contentDefinitionManager.AlterTypeDefinition("TextArea", type => type + await _contentDefinitionManager.AlterTypeDefinitionAsync("TextArea", type => type .WithPart("FormInputElementPart") .WithPart("FormElementPart") .WithPart("TextAreaPart") .Stereotype("Widget")); // Select - _contentDefinitionManager.AlterPartDefinition("SelectPart", part => part + await _contentDefinitionManager.AlterPartDefinitionAsync("SelectPart", part => part .WithDescription("Provides select field properties.")); - _contentDefinitionManager.AlterTypeDefinition("Select", type => type + await _contentDefinitionManager.AlterTypeDefinitionAsync("Select", type => type .WithPart("FormInputElementPart") .WithPart("FormElementPart") .WithPart("SelectPart") .Stereotype("Widget")); // Button - _contentDefinitionManager.AlterPartDefinition("ButtonPart", part => part + await _contentDefinitionManager.AlterPartDefinitionAsync("ButtonPart", part => part .WithDescription("Provides button properties.")); - _contentDefinitionManager.AlterTypeDefinition("Button", type => type + await _contentDefinitionManager.AlterTypeDefinitionAsync("Button", type => type .WithPart("FormInputElementPart") .WithPart("FormElementPart") .WithPart("ButtonPart") .Stereotype("Widget")); // Validation Summary - _contentDefinitionManager.AlterPartDefinition("ValidationSummaryPart", part => part + await _contentDefinitionManager.AlterPartDefinitionAsync("ValidationSummaryPart", part => part .WithDescription("Displays a validation summary.")); - _contentDefinitionManager.AlterTypeDefinition("ValidationSummary", type => type + await _contentDefinitionManager.AlterTypeDefinitionAsync("ValidationSummary", type => type .WithPart("ValidationSummaryPart") .Stereotype("Widget")); // Validation - _contentDefinitionManager.AlterPartDefinition("ValidationPart", part => part + await _contentDefinitionManager.AlterPartDefinitionAsync("ValidationPart", part => part .WithDescription("Displays a field validation error.")); - _contentDefinitionManager.AlterTypeDefinition("Validation", type => type + await _contentDefinitionManager.AlterTypeDefinitionAsync("Validation", type => type .WithPart("ValidationPart") .Stereotype("Widget")); return 1; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Html/Drivers/HtmlBodyPartDisplay.cs b/src/OrchardCore.Modules/OrchardCore.Html/Drivers/HtmlBodyPartDisplay.cs index 2ab37f13a39..cb0e472a946 100644 --- a/src/OrchardCore.Modules/OrchardCore.Html/Drivers/HtmlBodyPartDisplay.cs +++ b/src/OrchardCore.Modules/OrchardCore.Html/Drivers/HtmlBodyPartDisplay.cs @@ -54,7 +54,7 @@ public override async Task UpdateAsync(HtmlBodyPart model, IUpda private async Task BuildViewModelAsync(HtmlBodyPartViewModel model, HtmlBodyPart HtmlBodyPart, ContentTypePartDefinition definition) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(HtmlBodyPart.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(HtmlBodyPart.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(p => p.Name == nameof(HtmlBodyPart)); var settings = contentTypePartDefinition.GetSettings(); diff --git a/src/OrchardCore.Modules/OrchardCore.Html/Handlers/HtmlBodyPartHandler.cs b/src/OrchardCore.Modules/OrchardCore.Html/Handlers/HtmlBodyPartHandler.cs index 89d2c13169a..34e5b78a0a9 100644 --- a/src/OrchardCore.Modules/OrchardCore.Html/Handlers/HtmlBodyPartHandler.cs +++ b/src/OrchardCore.Modules/OrchardCore.Html/Handlers/HtmlBodyPartHandler.cs @@ -20,15 +20,14 @@ public HtmlBodyPartHandler(IContentDefinitionManager contentDefinitionManager) public override Task GetContentItemAspectAsync(ContentItemAspectContext context, HtmlBodyPart part) { - return context.ForAsync(bodyAspect => + return context.ForAsync(async bodyAspect => { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(p => p.PartDefinition.Name == nameof(HtmlBodyPart)); var settings = contentTypePartDefinition.GetSettings(); var body = part.Html; bodyAspect.Body = new HtmlString(body); - return Task.CompletedTask; }); } } diff --git a/src/OrchardCore.Modules/OrchardCore.Html/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Html/Migrations.cs index 3094ec66a3a..41c78b33258 100644 --- a/src/OrchardCore.Modules/OrchardCore.Html/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Html/Migrations.cs @@ -29,9 +29,9 @@ public Migrations( } - public int Create() + public async Task CreateAsync() { - _contentDefinitionManager.AlterPartDefinition("HtmlBodyPart", builder => builder + await _contentDefinitionManager.AlterPartDefinitionAsync("HtmlBodyPart", builder => builder .Attachable() .WithDescription("Provides an HTML Body for your content item.")); @@ -48,22 +48,22 @@ public async Task UpdateFrom3() // This code can be removed in RC // Update content type definitions - foreach (var contentType in _contentDefinitionManager.ListTypeDefinitions()) + foreach (var contentType in await _contentDefinitionManager.ListTypeDefinitionsAsync()) { if (contentType.Parts.Any(x => x.PartDefinition.Name == "BodyPart")) { - _contentDefinitionManager.AlterTypeDefinition(contentType.Name, x => x.RemovePart("BodyPart").WithPart("HtmlBodyPart")); + await _contentDefinitionManager.AlterTypeDefinitionAsync(contentType.Name, x => x.RemovePart("BodyPart").WithPart("HtmlBodyPart")); } } - _contentDefinitionManager.DeletePartDefinition("BodyPart"); + await _contentDefinitionManager.DeletePartDefinitionAsync("BodyPart"); // We are patching all content item versions by moving the Title to DisplayText // This step doesn't need to be executed for a brand new site var lastDocumentId = 0; - for (;;) + for (; ; ) { var contentItemVersions = await _session.Query(x => x.DocumentId > lastDocumentId).Take(10).ListAsync(); @@ -114,4 +114,4 @@ bool UpdateBody(JToken content) } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Layers/Views/Admin/Index.cshtml b/src/OrchardCore.Modules/OrchardCore.Layers/Views/Admin/Index.cshtml index 285130bc150..9811f192644 100644 --- a/src/OrchardCore.Modules/OrchardCore.Layers/Views/Admin/Index.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Layers/Views/Admin/Index.cshtml @@ -7,7 +7,7 @@ @inject OrchardCore.ContentManagement.Display.IContentItemDisplayManager ContentItemDisplayManager @{ - var widgetContentTypes = ContentDefinitionManager.ListTypeDefinitions().Where(t => t.Settings.ToObject().Stereotype == "Widget"); + var widgetContentTypes = (await ContentDefinitionManager.ListTypeDefinitionsAsync()).Where(t => t.Settings.ToObject().Stereotype == "Widget"); } diff --git a/src/OrchardCore.Modules/OrchardCore.Liquid/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Liquid/Migrations.cs index 019f4cc6882..585f25a9838 100644 --- a/src/OrchardCore.Modules/OrchardCore.Liquid/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Liquid/Migrations.cs @@ -1,5 +1,6 @@ -using OrchardCore.ContentManagement.Metadata.Settings; +using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata; +using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.Data.Migration; namespace OrchardCore.Liquid @@ -13,13 +14,13 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public int Create() + public async Task CreateAsync() { - _contentDefinitionManager.AlterPartDefinition("LiquidPart", builder => builder + await _contentDefinitionManager.AlterPartDefinitionAsync("LiquidPart", builder => builder .Attachable() .WithDescription("Provides a Liquid formatted body for your content item.")); return 1; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/AdminNodes/ListsAdminNodeDriver.cs b/src/OrchardCore.Modules/OrchardCore.Lists/AdminNodes/ListsAdminNodeDriver.cs index 93faa343cf8..c4cc762601f 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/AdminNodes/ListsAdminNodeDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/AdminNodes/ListsAdminNodeDriver.cs @@ -30,10 +30,10 @@ public override IDisplayResult Display(ListsAdminNode treeNode) public override IDisplayResult Edit(ListsAdminNode treeNode) { - return Initialize("ListsAdminNode_Fields_TreeEdit", model => + return Initialize("ListsAdminNode_Fields_TreeEdit", async model => { model.ContentType = treeNode.ContentType; - model.ContentTypes = GetContenTypesSelectList(); + model.ContentTypes = await GetContenTypesSelectListAsync(); model.IconForContentItems = treeNode.IconForContentItems; model.AddContentTypeAsParent = treeNode.AddContentTypeAsParent; model.IconForParentLink = treeNode.IconForParentLink; @@ -44,7 +44,7 @@ public override async Task UpdateAsync(ListsAdminNode treeNode, { var model = new ListsAdminNodeViewModel(); - if (await updater.TryUpdateModelAsync(model, Prefix, + if (await updater.TryUpdateModelAsync(model, Prefix, x => x.ContentType, x => x.IconForContentItems, x => x.AddContentTypeAsParent, x => x.IconForParentLink)) { @@ -58,9 +58,9 @@ public override async Task UpdateAsync(ListsAdminNode treeNode, } - private List GetContenTypesSelectList() + private async Task> GetContenTypesSelectListAsync() { - return _contentDefinitionManager.ListTypeDefinitions() + return (await _contentDefinitionManager.ListTypeDefinitionsAsync()) .Where(ctd => ctd.Parts.Any(p => p.PartDefinition.Name.Equals(typeof(ListPart).Name, StringComparison.OrdinalIgnoreCase))) .OrderBy(ctd => ctd.DisplayName) .Select(ctd => new SelectListItem { Value = ctd.Name, Text = ctd.DisplayName }) diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/AdminNodes/ListsAdminNodeNavigationBuilder.cs b/src/OrchardCore.Modules/OrchardCore.Lists/AdminNodes/ListsAdminNodeNavigationBuilder.cs index 1a1e1f25348..90432d441f2 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/AdminNodes/ListsAdminNodeNavigationBuilder.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/AdminNodes/ListsAdminNodeNavigationBuilder.cs @@ -49,7 +49,7 @@ public async Task BuildNavigationAsync(MenuItem menuItem, NavigationBuilder buil return; } - _contentType = _contentDefinitionManager.GetTypeDefinition(_node.ContentType); + _contentType = await _contentDefinitionManager.GetTypeDefinitionAsync(_node.ContentType); if (_node.AddContentTypeAsParent) { diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/Drivers/ListPartDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.Lists/Drivers/ListPartDisplayDriver.cs index cc1c6536d26..19728e86592 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/Drivers/ListPartDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/Drivers/ListPartDisplayDriver.cs @@ -42,14 +42,14 @@ IServiceProvider serviceProvider public override IDisplayResult Display(ListPart listPart, BuildPartDisplayContext context) { return - Combine( + Combine( Initialize("ListPart", async model => { var pager = await GetPagerAsync(context.Updater, listPart); model.ListPart = listPart; model.ContentItems = (await QueryListItemsAsync(listPart, pager, true)).ToArray(); - model.ContainedContentTypeDefinitions = GetContainedContentTypes(listPart); + model.ContainedContentTypeDefinitions = await GetContainedContentTypesAsync(listPart); model.Context = context; model.Pager = await context.New.PagerSlim(pager); }) @@ -60,7 +60,7 @@ public override IDisplayResult Display(ListPart listPart, BuildPartDisplayContex model.ListPart = listPart; model.ContentItems = (await QueryListItemsAsync(listPart, pager, false)).ToArray(); - model.ContainedContentTypeDefinitions = GetContainedContentTypes(listPart); + model.ContainedContentTypeDefinitions = await GetContainedContentTypesAsync(listPart); model.Context = context; model.Pager = await context.New.PagerSlim(pager); }) @@ -70,7 +70,7 @@ public override IDisplayResult Display(ListPart listPart, BuildPartDisplayContex private async Task GetPagerAsync(IUpdateModel updater, ListPart part) { - var settings = GetSettings(part); + var settings = await GetSettingsAsync(part); PagerSlimParameters pagerParameters = new PagerSlimParameters(); await updater.TryUpdateModelAsync(pagerParameters); @@ -203,18 +203,24 @@ private static Expression> CreateContentIndexFilter } } - private IEnumerable GetContainedContentTypes(ListPart listPart) + private async Task> GetContainedContentTypesAsync(ListPart listPart) { - var settings = GetSettings(listPart); + var settings = await GetSettingsAsync(listPart); var contentTypes = settings.ContainedContentTypes ?? Enumerable.Empty(); - return contentTypes.Select(contentType => _contentDefinitionManager.GetTypeDefinition(contentType)); + + var typeDefinitions = new List(); + foreach (var contentType in contentTypes) + { + typeDefinitions.Add(await _contentDefinitionManager.GetTypeDefinitionAsync(contentType)); + } + return typeDefinitions; } - private ListPartSettings GetSettings(ListPart listPart) + private async Task GetSettingsAsync(ListPart listPart) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(listPart.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(listPart.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => String.Equals(x.PartDefinition.Name, "ListPart", StringComparison.Ordinal)); return contentTypePartDefinition.Settings.ToObject(); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Lists/Migrations.cs index 8fcd2f79784..dcdc98f28d1 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/Migrations.cs @@ -1,5 +1,6 @@ -using OrchardCore.ContentManagement.Metadata.Settings; +using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata; +using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.Data.Migration; using OrchardCore.Lists.Indexes; @@ -14,9 +15,9 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public int Create() + public async Task CreateAsync() { - _contentDefinitionManager.AlterPartDefinition("ListPart", builder => builder + await _contentDefinitionManager.AlterPartDefinitionAsync("ListPart", builder => builder .Attachable() .WithDescription("Add a list behavior.")); @@ -32,4 +33,4 @@ public int Create() return 1; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/RemotePublishing/MetaWeblogHandler.cs b/src/OrchardCore.Modules/OrchardCore.Lists/RemotePublishing/MetaWeblogHandler.cs index fb083eaca41..8bc6fdd6b26 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/RemotePublishing/MetaWeblogHandler.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/RemotePublishing/MetaWeblogHandler.cs @@ -7,24 +7,24 @@ using System.Threading.Tasks; using System.Xml.Linq; using Microsoft.AspNetCore.Authorization; -using OrchardCore.Modules; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using OrchardCore.ContentManagement; -using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentManagement.Metadata; +using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentManagement.Records; using OrchardCore.Contents; using OrchardCore.FileStorage; -using OrchardCore.XmlRpc; -using OrchardCore.XmlRpc.Models; using OrchardCore.Lists.Indexes; using OrchardCore.Lists.Models; using OrchardCore.Media; using OrchardCore.MetaWeblog; +using OrchardCore.Modules; using OrchardCore.Security.Permissions; using OrchardCore.Users.Services; +using OrchardCore.XmlRpc; +using OrchardCore.XmlRpc.Models; using YesSql; namespace OrchardCore.Lists.RemotePublishing @@ -183,7 +183,7 @@ private async Task MetaWeblogGetUserBlogsAsync(XmlRpcContext context, XRpcArray array = new XRpcArray(); // Look for all types using ListPart - foreach (var type in _contentDefinitionManager.ListTypeDefinitions()) + foreach (var type in await _contentDefinitionManager.ListTypeDefinitionsAsync()) { if (!type.Parts.Any(x => x.Name == nameof(ListPart))) { @@ -273,7 +273,7 @@ private async Task MetaWeblogNewPostAsync( throw new InvalidOperationException("Could not find content item " + contentItemId); } - var postType = GetContainedContentTypes(list).FirstOrDefault(); + var postType = (await GetContainedContentTypesAsync(list)).FirstOrDefault(); var contentItem = await _contentManager.NewAsync(postType.Name); contentItem.Owner = userName; @@ -493,13 +493,19 @@ private async Task CheckAccessAsync(Permission permission, ClaimsPrincipal user, } } - private IEnumerable GetContainedContentTypes(ContentItem contentItem) + private async Task> GetContainedContentTypesAsync(ContentItem contentItem) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => String.Equals(x.PartDefinition.Name, "ListPart", StringComparison.Ordinal)); var settings = contentTypePartDefinition.Settings.ToObject(); var contentTypes = settings.ContainedContentTypes ?? Enumerable.Empty(); - return contentTypes.Select(contentType => _contentDefinitionManager.GetTypeDefinition(contentType)); + + var typeDefinitions = new List(); + foreach (var contentType in contentTypes) + { + typeDefinitions.Add(await _contentDefinitionManager.GetTypeDefinitionAsync(contentType)); + } + return typeDefinitions; } } } diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/Services/ListPartContentAdminFilter.cs b/src/OrchardCore.Modules/OrchardCore.Lists/Services/ListPartContentAdminFilter.cs index f4848f0429d..9272ab466c0 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/Services/ListPartContentAdminFilter.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/Services/ListPartContentAdminFilter.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using System.Threading.Tasks; using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Metadata; @@ -26,13 +26,13 @@ public ListPartContentAdminFilter(IContentDefinitionManager contentDefinitionMan public async Task FilterAsync(IQuery query, ListContentsViewModel model, PagerParameters pagerParameters, IUpdateModel updateModel) { var viewModel = new ListPartContentAdminFilterModel(); - if(await updateModel.TryUpdateModelAsync(viewModel, "")) + if (await updateModel.TryUpdateModelAsync(viewModel, "")) { // Show list content items if (viewModel.ShowListContentTypes) { - var listableTypes = _contentDefinitionManager - .ListTypeDefinitions() + var listableTypes = (await _contentDefinitionManager + .ListTypeDefinitionsAsync()) .Where(x => x.Parts.Any(p => p.PartDefinition.Name == nameof(ListPart))) @@ -42,7 +42,7 @@ public async Task FilterAsync(IQuery query, ListContentsViewModel m } // Show contained elements for the specified list - else if(viewModel.ListContentItemId != null) + else if (viewModel.ListContentItemId != null) { query.With(x => x.ListContentItemId == viewModel.ListContentItemId); } diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/Settings/ListPartSettingsDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.Lists/Settings/ListPartSettingsDisplayDriver.cs index 9ade59e8d0f..35fc74c0312 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/Settings/ListPartSettingsDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/Settings/ListPartSettingsDisplayDriver.cs @@ -2,8 +2,8 @@ using System.Collections.Specialized; using System.Threading.Tasks; using Microsoft.Extensions.Localization; -using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentManagement.Metadata; +using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentTypes.Editors; using OrchardCore.DisplayManagement.ModelBinding; using OrchardCore.DisplayManagement.Views; @@ -33,14 +33,14 @@ public override IDisplayResult Edit(ContentTypePartDefinition contentTypePartDef return null; } - return Initialize("ListPartSettings_Edit", model => + return Initialize("ListPartSettings_Edit", async model => { model.ListPartSettings = contentTypePartDefinition.Settings.ToObject(); model.PageSize = model.ListPartSettings.PageSize; model.ContainedContentTypes = model.ListPartSettings.ContainedContentTypes; model.ContentTypes = new NameValueCollection(); - foreach(var contentTypeDefinition in _contentDefinitionManager.ListTypeDefinitions()) + foreach (var contentTypeDefinition in await _contentDefinitionManager.ListTypeDefinitionsAsync()) { model.ContentTypes.Add(contentTypeDefinition.Name, contentTypeDefinition.DisplayName); } @@ -71,4 +71,4 @@ public override async Task UpdateAsync(ContentTypePartDefinition return Edit(contentTypePartDefinition, context.Updater); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/Views/Items/ListsAdminNode.Fields.TreeSummary.cshtml b/src/OrchardCore.Modules/OrchardCore.Lists/Views/Items/ListsAdminNode.Fields.TreeSummary.cshtml index 6ef8b938d20..732c9205050 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/Views/Items/ListsAdminNode.Fields.TreeSummary.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Lists/Views/Items/ListsAdminNode.Fields.TreeSummary.cshtml @@ -3,7 +3,7 @@ @{ - var displayName = ContentDefinitionManager.GetTypeDefinition(Model.Value.ContentType); + var displayName = await ContentDefinitionManager.GetTypeDefinitionAsync(Model.Value.ContentType); }
    diff --git a/src/OrchardCore.Modules/OrchardCore.Markdown/Drivers/MarkdownBodyPartDisplay.cs b/src/OrchardCore.Modules/OrchardCore.Markdown/Drivers/MarkdownBodyPartDisplay.cs index 71fd513e927..c9e6be5dbfd 100644 --- a/src/OrchardCore.Modules/OrchardCore.Markdown/Drivers/MarkdownBodyPartDisplay.cs +++ b/src/OrchardCore.Modules/OrchardCore.Markdown/Drivers/MarkdownBodyPartDisplay.cs @@ -30,14 +30,14 @@ public MarkdownBodyPartDisplay( public override IDisplayResult Display(MarkdownBodyPart MarkdownBodyPart, BuildPartDisplayContext context) { - return Initialize("MarkdownBodyPart", m => BuildViewModel(m, MarkdownBodyPart, context.TypePartDefinition)) + return Initialize("MarkdownBodyPart", m => BuildViewModelAsync(m, MarkdownBodyPart, context.TypePartDefinition)) .Location("Detail", "Content:10") .Location("Summary", "Content:10"); } public override IDisplayResult Edit(MarkdownBodyPart MarkdownBodyPart, BuildPartEditorContext context) { - return Initialize(GetEditorShapeType(context), m => BuildViewModel(m, MarkdownBodyPart, context.TypePartDefinition)); + return Initialize(GetEditorShapeType(context), m => BuildViewModelAsync(m, MarkdownBodyPart, context.TypePartDefinition)); } public override async Task UpdateAsync(MarkdownBodyPart model, IUpdateModel updater) @@ -51,9 +51,9 @@ public override async Task UpdateAsync(MarkdownBodyPart model, I return Edit(model); } - private async Task BuildViewModel(MarkdownBodyPartViewModel model, MarkdownBodyPart MarkdownBodyPart, ContentTypePartDefinition definition) + private async Task BuildViewModelAsync(MarkdownBodyPartViewModel model, MarkdownBodyPart MarkdownBodyPart, ContentTypePartDefinition definition) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(MarkdownBodyPart.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(MarkdownBodyPart.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(p => p.PartDefinition.Name == nameof(MarkdownBodyPart)); var settings = contentTypePartDefinition.GetSettings(); diff --git a/src/OrchardCore.Modules/OrchardCore.Markdown/Handlers/MarkdownBodyPartHandler.cs b/src/OrchardCore.Modules/OrchardCore.Markdown/Handlers/MarkdownBodyPartHandler.cs index 5a93cbc9c70..4b01cd13f72 100644 --- a/src/OrchardCore.Modules/OrchardCore.Markdown/Handlers/MarkdownBodyPartHandler.cs +++ b/src/OrchardCore.Modules/OrchardCore.Markdown/Handlers/MarkdownBodyPartHandler.cs @@ -20,15 +20,14 @@ public MarkdownBodyPartHandler(IContentDefinitionManager contentDefinitionManage public override Task GetContentItemAspectAsync(ContentItemAspectContext context, MarkdownBodyPart part) { - return context.ForAsync(bodyAspect => + return context.ForAsync(async bodyAspect => { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(p => p.PartDefinition.Name == nameof(MarkdownBodyPart)); var settings = contentTypePartDefinition.GetSettings(); var html = Markdig.Markdown.ToHtml(part.Markdown ?? ""); bodyAspect.Body = new HtmlString(html); - return Task.CompletedTask; }); } } diff --git a/src/OrchardCore.Modules/OrchardCore.Markdown/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Markdown/Migrations.cs index bf188807461..5a54f8bbae9 100644 --- a/src/OrchardCore.Modules/OrchardCore.Markdown/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Markdown/Migrations.cs @@ -1,5 +1,6 @@ -using OrchardCore.ContentManagement.Metadata.Settings; +using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata; +using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.Data.Migration; namespace OrchardCore.Markdown @@ -13,13 +14,13 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public int Create() + public async Task CreateAsync() { - _contentDefinitionManager.AlterPartDefinition("MarkdownBodyPart", builder => builder + await _contentDefinitionManager.AlterPartDefinitionAsync("MarkdownBodyPart", builder => builder .Attachable() .WithDescription("Provides a Markdown formatted body for your content item.")); return 1; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Menu/Controllers/AdminController.cs b/src/OrchardCore.Modules/OrchardCore.Menu/Controllers/AdminController.cs index 77bf46e0b47..b9afe7420f4 100644 --- a/src/OrchardCore.Modules/OrchardCore.Menu/Controllers/AdminController.cs +++ b/src/OrchardCore.Modules/OrchardCore.Menu/Controllers/AdminController.cs @@ -6,8 +6,8 @@ using Newtonsoft.Json.Linq; using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Display; -using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.ContentManagement.Metadata; +using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.DisplayManagement.ModelBinding; using OrchardCore.DisplayManagement.Notify; using OrchardCore.Menu.Models; @@ -77,7 +77,7 @@ public async Task CreatePost(string id, string menuContentItemId, ContentItem menu; - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition("Menu"); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync("Menu"); if (!contentTypeDefinition.Settings.ToObject().Draftable) { @@ -179,7 +179,7 @@ public async Task EditPost(string menuContentItemId, string menuI ContentItem menu; - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition("Menu"); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync("Menu"); if (!contentTypeDefinition.Settings.ToObject().Draftable) { @@ -234,7 +234,7 @@ public async Task Delete(string menuContentItemId, string menuIte ContentItem menu; - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition("Menu"); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync("Menu"); if (!contentTypeDefinition.Settings.ToObject().Draftable) { diff --git a/src/OrchardCore.Modules/OrchardCore.Menu/Views/Admin/Create.cshtml b/src/OrchardCore.Modules/OrchardCore.Menu/Views/Admin/Create.cshtml index c099cfd397c..79abac00ade 100644 --- a/src/OrchardCore.Modules/OrchardCore.Menu/Views/Admin/Create.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Menu/Views/Admin/Create.cshtml @@ -6,7 +6,7 @@ @{ ContentItem contentItem = Model.ContentItem; - var contentTypeDefinition = ContentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var contentTypeDefinition = await ContentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); var typeDisplayName = contentTypeDefinition?.DisplayName ?? contentItem.ContentType.CamelFriendly(); } diff --git a/src/OrchardCore.Modules/OrchardCore.Menu/Views/Admin/Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.Menu/Views/Admin/Edit.cshtml index 719f2f516a2..7ac70cad385 100644 --- a/src/OrchardCore.Modules/OrchardCore.Menu/Views/Admin/Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Menu/Views/Admin/Edit.cshtml @@ -6,7 +6,7 @@ @{ ContentItem contentItem = Model.ContentItem; - var contentTypeDefinition = ContentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var contentTypeDefinition = await ContentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); var typeDisplayName = contentTypeDefinition?.DisplayName ?? contentItem.ContentType.CamelFriendly(); } diff --git a/src/OrchardCore.Modules/OrchardCore.Menu/Views/MenuPart.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.Menu/Views/MenuPart.Edit.cshtml index a671b31d6f5..ea3bf06806b 100644 --- a/src/OrchardCore.Modules/OrchardCore.Menu/Views/MenuPart.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Menu/Views/MenuPart.Edit.cshtml @@ -16,7 +16,7 @@ @{ var updater = ModelUpdaterAccessor.ModelUpdater; - var menuItemContentTypes = ContentDefinitionManager.ListTypeDefinitions().Where(t => t.Settings.ToObject().Stereotype == "MenuItem"); + var menuItemContentTypes = (await ContentDefinitionManager.ListTypeDefinitionsAsync()).Where(t => t.Settings.ToObject().Stereotype == "MenuItem"); var canAddMenuItem = Model.MenuPart.ContentItem.Id != 0; var index = 0; } diff --git a/src/OrchardCore.Modules/OrchardCore.ReCaptcha/Forms/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.ReCaptcha/Forms/Migrations.cs index c8d816dad1d..56736d336a5 100644 --- a/src/OrchardCore.Modules/OrchardCore.ReCaptcha/Forms/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.ReCaptcha/Forms/Migrations.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.Data.Migration; @@ -13,24 +14,24 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public int Create() + public async Task CreateAsync() { // NoCaptcha - //_contentDefinitionManager.AlterPartDefinition("NoCaptchaPart", part => part + //await _contentDefinitionManager.AlterPartDefinitionAsync("NoCaptchaPart", part => part // .WithDescription("Provides captcha properties.")); - //_contentDefinitionManager.AlterTypeDefinition("NoCaptcha", type => type + //await _contentDefinitionManager.AlterTypeDefinitionAsync("NoCaptcha", type => type // .WithPart("NoCaptchaPart") // .Stereotype("Widget")); - _contentDefinitionManager.AlterPartDefinition("ReCaptchaPart", part => part + await _contentDefinitionManager.AlterPartDefinitionAsync("ReCaptchaPart", part => part .WithDescription("Provides captcha properties.")); - _contentDefinitionManager.AlterTypeDefinition("ReCaptcha", type => type + await _contentDefinitionManager.AlterTypeDefinitionAsync("ReCaptcha", type => type .WithPart("ReCaptchaPart") .Stereotype("Widget")); return 1; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Taxonomies/Controllers/AdminController.cs b/src/OrchardCore.Modules/OrchardCore.Taxonomies/Controllers/AdminController.cs index fd9baec5f48..2dc0c89f4a5 100644 --- a/src/OrchardCore.Modules/OrchardCore.Taxonomies/Controllers/AdminController.cs +++ b/src/OrchardCore.Modules/OrchardCore.Taxonomies/Controllers/AdminController.cs @@ -77,7 +77,7 @@ public async Task CreatePost(string id, string taxonomyContentIte ContentItem taxonomy; - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition("Taxonomy"); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync("Taxonomy"); if (!contentTypeDefinition.Settings.ToObject().Draftable) { @@ -116,7 +116,7 @@ public async Task CreatePost(string id, string taxonomyContentIte if (parentTaxonomyItem == null) { return NotFound(); - } + } var taxonomyItems = parentTaxonomyItem?.Terms as JArray; @@ -177,7 +177,7 @@ public async Task EditPost(string taxonomyContentItemId, string t ContentItem taxonomy; - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition("Taxonomy"); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync("Taxonomy"); if (!contentTypeDefinition.Settings.ToObject().Draftable) { @@ -235,7 +235,7 @@ public async Task Delete(string taxonomyContentItemId, string tax ContentItem taxonomy; - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition("Taxonomy"); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync("Taxonomy"); if (!contentTypeDefinition.Settings.ToObject().Draftable) { diff --git a/src/OrchardCore.Modules/OrchardCore.Taxonomies/Indexing/TaxonomyIndex.cs b/src/OrchardCore.Modules/OrchardCore.Taxonomies/Indexing/TaxonomyIndex.cs index c061d7efd4c..fce52d43f87 100644 --- a/src/OrchardCore.Modules/OrchardCore.Taxonomies/Indexing/TaxonomyIndex.cs +++ b/src/OrchardCore.Modules/OrchardCore.Taxonomies/Indexing/TaxonomyIndex.cs @@ -55,13 +55,13 @@ public override void Describe(DescribeContext context) // Search for Taxonomy fields var fieldDefinitions = _contentDefinitionManager - .GetTypeDefinition(contentItem.ContentType) + .GetTypeDefinitionAsync(contentItem.ContentType).GetAwaiter().GetResult() .Parts.SelectMany(x => x.PartDefinition.Fields.Where(f => f.FieldDefinition.Name == nameof(TaxonomyField))) .ToArray(); // This type doesn't have any TaxonomyField, ignore it if (fieldDefinitions.Length == 0) - { + { _ignoredTypes.Add(contentItem.ContentType); return null; } @@ -105,4 +105,4 @@ public override void Describe(DescribeContext context) }); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Taxonomies/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Taxonomies/Migrations.cs index 585ee667c9f..0aa15590c4e 100644 --- a/src/OrchardCore.Modules/OrchardCore.Taxonomies/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Taxonomies/Migrations.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.Data.Migration; @@ -14,9 +15,9 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public int Create() + public async Task CreateAsync() { - _contentDefinitionManager.AlterTypeDefinition("Taxonomy", menu => menu + await _contentDefinitionManager.AlterTypeDefinitionAsync("Taxonomy", menu => menu .Draftable() .Versionable() .Creatable() diff --git a/src/OrchardCore.Modules/OrchardCore.Taxonomies/Views/Admin/Create.cshtml b/src/OrchardCore.Modules/OrchardCore.Taxonomies/Views/Admin/Create.cshtml index 11bf6702f7e..bfbaf3d9fde 100644 --- a/src/OrchardCore.Modules/OrchardCore.Taxonomies/Views/Admin/Create.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Taxonomies/Views/Admin/Create.cshtml @@ -6,7 +6,7 @@ @{ ContentItem contentItem = Model.ContentItem; - var contentTypeDefinition = ContentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var contentTypeDefinition = await ContentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); var typeDisplayName = contentTypeDefinition?.DisplayName ?? contentItem.ContentType.CamelFriendly(); } diff --git a/src/OrchardCore.Modules/OrchardCore.Taxonomies/Views/Admin/Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.Taxonomies/Views/Admin/Edit.cshtml index 23bf31af014..5096106d81b 100644 --- a/src/OrchardCore.Modules/OrchardCore.Taxonomies/Views/Admin/Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Taxonomies/Views/Admin/Edit.cshtml @@ -6,7 +6,7 @@ @{ ContentItem contentItem = Model.ContentItem; - var contentTypeDefinition = ContentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var contentTypeDefinition = await ContentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); var typeDisplayName = contentTypeDefinition?.DisplayName ?? contentItem.ContentType.CamelFriendly(); } diff --git a/src/OrchardCore.Modules/OrchardCore.Taxonomies/Views/TaxonomyPart.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.Taxonomies/Views/TaxonomyPart.Edit.cshtml index 3ddc6088605..0634a4642d4 100644 --- a/src/OrchardCore.Modules/OrchardCore.Taxonomies/Views/TaxonomyPart.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Taxonomies/Views/TaxonomyPart.Edit.cshtml @@ -17,7 +17,7 @@ @{ var updater = ModelUpdaterAccessor.ModelUpdater; var canAddTerm = Model.TaxonomyPart.ContentItem.Id != 0; - var termContentTypes = ContentDefinitionManager.ListTypeDefinitions().Where(t => String.IsNullOrEmpty(t.Settings.ToObject().Stereotype)).OrderBy(x => x.DisplayName); + var termContentTypes = (await ContentDefinitionManager.ListTypeDefinitionsAsync()).Where(t => String.IsNullOrEmpty(t.Settings.ToObject().Stereotype)).OrderBy(x => x.DisplayName); var index = 0; }
    @@ -29,7 +29,7 @@ @if (canAddTerm && Model.TermContentType != null) { - var termContentType = ContentDefinitionManager.GetTypeDefinition(Model.TermContentType); + var termContentType = await ContentDefinitionManager.GetTypeDefinitionAsync(Model.TermContentType); _logger; public Migrations( - IContentDefinitionManager contentDefinitionManager, + IContentDefinitionManager contentDefinitionManager, ISession session, ILogger logger) { @@ -28,9 +28,9 @@ public Migrations( _logger = logger; } - public int Create() + public async Task CreateAsync() { - _contentDefinitionManager.AlterPartDefinition("TitlePart", builder => builder + await _contentDefinitionManager.AlterPartDefinitionAsync("TitlePart", builder => builder .Attachable() .WithDescription("Provides a Title for your content item.") .WithDefaultPosition("0") @@ -38,7 +38,7 @@ public int Create() return 2; } - + public async Task UpdateFrom1() { // This code can be removed in RC @@ -47,17 +47,17 @@ public async Task UpdateFrom1() var lastDocumentId = 0; - for(;;) + for (; ; ) { var contentItemVersions = await _session.Query(x => x.DocumentId > lastDocumentId).Take(10).ListAsync(); - + if (!contentItemVersions.Any()) { // No more content item version to process break; } - foreach(var contentItemVersion in contentItemVersions) + foreach (var contentItemVersion in contentItemVersions) { if (String.IsNullOrEmpty(contentItemVersion.DisplayText) && UpdateTitle(contentItemVersion.Content)) @@ -70,7 +70,7 @@ public async Task UpdateFrom1() } await _session.CommitAsync(); - } + } bool UpdateTitle(JToken content) { @@ -78,8 +78,8 @@ bool UpdateTitle(JToken content) if (content.Type == JTokenType.Object) { - var title = content["TitlePart"] ? ["Title"]?.Value(); - + var title = content["TitlePart"]?["Title"]?.Value(); + if (!String.IsNullOrWhiteSpace(title)) { content["DisplayText"] = title; @@ -98,4 +98,4 @@ bool UpdateTitle(JToken content) return 2; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Widgets/Drivers/WidgetsListPartDisplay.cs b/src/OrchardCore.Modules/OrchardCore.Widgets/Drivers/WidgetsListPartDisplay.cs index 08627e3b3d5..68f4b378854 100644 --- a/src/OrchardCore.Modules/OrchardCore.Widgets/Drivers/WidgetsListPartDisplay.cs +++ b/src/OrchardCore.Modules/OrchardCore.Widgets/Drivers/WidgetsListPartDisplay.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using OrchardCore.Mvc.Utilities; using Microsoft.Extensions.DependencyInjection; using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Display; @@ -10,6 +9,7 @@ using OrchardCore.ContentManagement.Display.Models; using OrchardCore.ContentManagement.Metadata; using OrchardCore.DisplayManagement.Views; +using OrchardCore.Mvc.Utilities; using OrchardCore.Settings; using OrchardCore.Widgets.Models; using OrchardCore.Widgets.Settings; @@ -73,9 +73,9 @@ public override async Task DisplayAsync(WidgetsListPart part, Bu public override IDisplayResult Edit(WidgetsListPart widgetPart, BuildPartEditorContext context) { - return Initialize("WidgetsListPart_Edit", m => + return Initialize("WidgetsListPart_Edit", async m => { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(widgetPart.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(widgetPart.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(p => p.PartDefinition.Name == nameof(WidgetsListPart)); var settings = contentTypePartDefinition.GetSettings(); @@ -86,7 +86,7 @@ public override IDisplayResult Edit(WidgetsListPart widgetPart, BuildPartEditorC }); } - public override async Task UpdateAsync(WidgetsListPart part, BuildPartEditorContext context) + public override async Task UpdateAsync(WidgetsListPart part, UpdatePartEditorContext context) { var contentItemDisplayManager = _serviceProvider.GetRequiredService(); diff --git a/src/OrchardCore.Modules/OrchardCore.Widgets/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Widgets/Migrations.cs index 539b3bcaf50..f929abad00a 100644 --- a/src/OrchardCore.Modules/OrchardCore.Widgets/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Widgets/Migrations.cs @@ -1,5 +1,6 @@ -using OrchardCore.ContentManagement.Metadata.Settings; +using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata; +using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.Data.Migration; namespace OrchardCore.Widgets @@ -13,9 +14,9 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public int Create() + public async Task CreateAsync() { - _contentDefinitionManager.AlterPartDefinition("WidgetsListPart", builder => builder + await _contentDefinitionManager.AlterPartDefinitionAsync("WidgetsListPart", builder => builder .Attachable() .WithDescription("Provides a way to add widgets per content items.") ); @@ -23,4 +24,4 @@ public int Create() return 1; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore.Modules/OrchardCore.Widgets/Views/Widget-List.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.Widgets/Views/Widget-List.Edit.cshtml index f2a95d97254..1ca34913cbd 100644 --- a/src/OrchardCore.Modules/OrchardCore.Widgets/Views/Widget-List.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Widgets/Views/Widget-List.Edit.cshtml @@ -2,8 +2,8 @@ @inject OrchardCore.ContentManagement.Metadata.IContentDefinitionManager ContentDefinitionManager @{ - var contentType = ContentDefinitionManager.GetTypeDefinition((string)Model.ContentItem.ContentType).DisplayName; - var widgetContentTypes = ContentDefinitionManager.ListTypeDefinitions().Where(t => t.Settings.ToObject().Stereotype == "Widget"); + var contentType = (await ContentDefinitionManager.GetTypeDefinitionAsync((string)Model.ContentItem.ContentType)).DisplayName; + var widgetContentTypes = (await ContentDefinitionManager.ListTypeDefinitionsAsync()).Where(t => t.Settings.ToObject().Stereotype == "Widget"); }
    diff --git a/src/OrchardCore.Modules/OrchardCore.Widgets/Views/WidgetsListPart.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.Widgets/Views/WidgetsListPart.Edit.cshtml index ed6ed7870cd..ac135fd628a 100644 --- a/src/OrchardCore.Modules/OrchardCore.Widgets/Views/WidgetsListPart.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Widgets/Views/WidgetsListPart.Edit.cshtml @@ -8,7 +8,7 @@ @inject OrchardCore.ContentManagement.Display.IContentItemDisplayManager ContentItemDisplayManager @{ - var widgetContentTypes = ContentDefinitionManager.ListTypeDefinitions().Where(t => t.Settings.ToObject().Stereotype == "Widget"); + var widgetContentTypes = (await ContentDefinitionManager.ListTypeDefinitionsAsync()).Where(t => t.Settings.ToObject().Stereotype == "Widget"); } diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/IContentDefinitionManager.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/IContentDefinitionManager.cs index ff204fdd753..ee9468e7965 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/IContentDefinitionManager.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/IContentDefinitionManager.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.Primitives; using OrchardCore.ContentManagement.Metadata.Builders; using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.Mvc.Utilities; -using System.Threading.Tasks; -using Microsoft.Extensions.Primitives; namespace OrchardCore.ContentManagement.Metadata { @@ -15,16 +15,16 @@ namespace OrchardCore.ContentManagement.Metadata ///
public interface IContentDefinitionManager { - IEnumerable ListTypeDefinitions(); - IEnumerable ListPartDefinitions(); + Task> ListTypeDefinitionsAsync(); + Task> ListPartDefinitionsAsync(); - ContentTypeDefinition GetTypeDefinition(string name); - ContentPartDefinition GetPartDefinition(string name); - void DeleteTypeDefinition(string name); - void DeletePartDefinition(string name); + Task GetTypeDefinitionAsync(string name); + Task GetPartDefinitionAsync(string name); + Task DeleteTypeDefinitionAsync(string name); + Task DeletePartDefinitionAsync(string name); - void StoreTypeDefinition(ContentTypeDefinition contentTypeDefinition); - void StorePartDefinition(ContentPartDefinition contentPartDefinition); + Task StoreTypeDefinitionAsync(ContentTypeDefinition contentTypeDefinition); + Task StorePartDefinitionAsync(ContentPartDefinition contentPartDefinition); /// /// Returns a serial number representing the list of types and settings for the current tenant. @@ -40,19 +40,19 @@ public interface IContentDefinitionManager public static class ContentDefinitionManagerExtensions { - public static void AlterTypeDefinition(this IContentDefinitionManager manager, string name, Action alteration) + public static async Task AlterTypeDefinitionAsync(this IContentDefinitionManager manager, string name, Action alteration) { - var typeDefinition = manager.GetTypeDefinition(name) ?? new ContentTypeDefinition(name, name.CamelFriendly()); + var typeDefinition = await manager.GetTypeDefinitionAsync(name) ?? new ContentTypeDefinition(name, name.CamelFriendly()); var builder = new ContentTypeDefinitionBuilder(typeDefinition); alteration(builder); - manager.StoreTypeDefinition(builder.Build()); + await manager.StoreTypeDefinitionAsync(builder.Build()); } - public static void AlterPartDefinition(this IContentDefinitionManager manager, string name, Action alteration) + public static async Task AlterPartDefinitionAsync(this IContentDefinitionManager manager, string name, Action alteration) { - var partDefinition = manager.GetPartDefinition(name) ?? new ContentPartDefinition(name); + var partDefinition = await manager.GetPartDefinitionAsync(name) ?? new ContentPartDefinition(name); var builder = new ContentPartDefinitionBuilder(partDefinition); alteration(builder); - manager.StorePartDefinition(builder.Build()); + await manager.StorePartDefinitionAsync(builder.Build()); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplay/ContentItemDisplayCoordinator.cs b/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplay/ContentItemDisplayCoordinator.cs index b8cf54a8a58..a510b99f241 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplay/ContentItemDisplayCoordinator.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplay/ContentItemDisplayCoordinator.cs @@ -43,7 +43,7 @@ public ContentItemDisplayCoordinator( public async Task BuildDisplayAsync(ContentItem contentItem, BuildDisplayContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); if (contentTypeDefinition == null) { @@ -150,7 +150,7 @@ public async Task BuildDisplayAsync(ContentItem contentItem, BuildDisplayContext public async Task BuildEditorAsync(ContentItem contentItem, BuildEditorContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); if (contentTypeDefinition == null) return; @@ -230,7 +230,7 @@ await _fieldDisplayDrivers.InvokeAsync(async contentDisplay => public async Task UpdateEditorAsync(ContentItem contentItem, UpdateEditorContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); if (contentTypeDefinition == null) return; diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplay/ContentPartDisplayDriverTPart.cs b/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplay/ContentPartDisplayDriverTPart.cs index 0840dace1a9..70b0d709b63 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplay/ContentPartDisplayDriverTPart.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplay/ContentPartDisplayDriverTPart.cs @@ -244,7 +244,7 @@ public virtual Task UpdateAsync(TPart part, IUpdateModel updater return UpdateAsync(part, context); } - public virtual Task UpdateAsync(TPart part, BuildPartEditorContext context) + public virtual Task UpdateAsync(TPart part, UpdatePartEditorContext context) { return UpdateAsync(part, context.Updater); } diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplayManager.cs b/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplayManager.cs index 5b7cd061375..d2620bc0d8a 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplayManager.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplayManager.cs @@ -65,7 +65,7 @@ public async Task BuildDisplayAsync(ContentItem contentItem, IUpdateMode throw new ArgumentNullException(nameof(contentItem)); } - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); var stereotype = contentTypeDefinition.Settings.ToObject().Stereotype; var actualDisplayType = string.IsNullOrEmpty(displayType) ? "Detail" : displayType; @@ -110,7 +110,7 @@ public async Task BuildEditorAsync(ContentItem contentItem, IUpdateModel throw new ArgumentNullException(nameof(contentItem)); } - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); var stereotype = contentTypeDefinition.Settings.ToObject().Stereotype; @@ -146,7 +146,7 @@ public async Task UpdateEditorAsync(ContentItem contentItem, IUpdateMode throw new ArgumentNullException(nameof(contentItem)); } - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); var stereotype = contentTypeDefinition.Settings.ToObject().Stereotype; var actualShapeType = (stereotype ?? "Content") + "_Edit"; diff --git a/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentTypeQuery.cs b/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentTypeQuery.cs index e252194c8f4..6116ecb9ca5 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentTypeQuery.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentTypeQuery.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using GraphQL.Types; @@ -35,14 +34,14 @@ public ContentTypeQuery(IHttpContextAccessor httpContextAccessor, public IStringLocalizer T { get; set; } - public Task BuildAsync(ISchema schema) + public async Task BuildAsync(ISchema schema) { var serviceProvider = _httpContextAccessor.HttpContext.RequestServices; var contentDefinitionManager = serviceProvider.GetService(); var contentTypeBuilders = serviceProvider.GetServices().ToList(); - foreach (var typeDefinition in contentDefinitionManager.ListTypeDefinitions()) + foreach (var typeDefinition in await contentDefinitionManager.ListTypeDefinitionsAsync()) { var typeType = new ContentItemType(_optionsAccessor) { @@ -76,7 +75,7 @@ public Task BuildAsync(ISchema schema) } } - return Task.FromResult(contentDefinitionManager.ChangeToken); + return contentDefinitionManager.ChangeToken; } } } diff --git a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs index 8436b010298..1fdfe9a7712 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs @@ -37,116 +37,131 @@ public ContentDefinitionManager( _partDefinitions = _memoryCache.GetOrCreate("PartDefinitions", entry => new ConcurrentDictionary()); } - public ContentTypeDefinition GetTypeDefinition(string name) + public async Task GetTypeDefinitionAsync(string name) { - return _typeDefinitions.GetOrAdd(name, n => + if (!_typeDefinitions.TryGetValue(name, out var typeDefinition)) { - var contentTypeDefinitionRecord = GetContentDefinitionRecord() + typeDefinition = await BuildAsync((await GetContentDefinitionRecordAsync()) .ContentTypeDefinitionRecords - .FirstOrDefault(x => x.Name == name); + .FirstOrDefault(type => type.Name == name)); - return Build(contentTypeDefinitionRecord); - }); + _typeDefinitions[name] = typeDefinition; + } + + return typeDefinition; } - public ContentPartDefinition GetPartDefinition(string name) + public async Task GetPartDefinitionAsync(string name) { - return _partDefinitions.GetOrAdd(name, n => + if (!_partDefinitions.TryGetValue(name, out var partDefinition)) { - return Build(GetContentDefinitionRecord() - .ContentPartDefinitionRecords - .FirstOrDefault(x => x.Name == name)); - }); + partDefinition = Build((await GetContentDefinitionRecordAsync()) + .ContentPartDefinitionRecords + .FirstOrDefault(part => part.Name == name)); + + _partDefinitions[name] = partDefinition; + } + + return partDefinition; } - public IEnumerable ListTypeDefinitions() + public async Task> ListTypeDefinitionsAsync() { - return GetContentDefinitionRecord().ContentTypeDefinitionRecords.Select(x => GetTypeDefinition(x.Name)).ToList(); + var typeDefinitions = new List(); + + foreach (var record in (await GetContentDefinitionRecordAsync()).ContentTypeDefinitionRecords) + { + typeDefinitions.Add(await GetTypeDefinitionAsync(record.Name)); + } + + return typeDefinitions; } - public IEnumerable ListPartDefinitions() + public async Task> ListPartDefinitionsAsync() { - return GetContentDefinitionRecord().ContentPartDefinitionRecords.Select(x => GetPartDefinition(x.Name)).ToList(); + var partDefinitions = new List(); + + foreach (var record in (await GetContentDefinitionRecordAsync()).ContentPartDefinitionRecords) + { + partDefinitions.Add(await GetPartDefinitionAsync(record.Name)); + } + + return partDefinitions; } - public void StoreTypeDefinition(ContentTypeDefinition contentTypeDefinition) + public async Task StoreTypeDefinitionAsync(ContentTypeDefinition contentTypeDefinition) { - Apply(contentTypeDefinition, Acquire(contentTypeDefinition)); - UpdateContentDefinitionRecord(); + await ApplyAsync(contentTypeDefinition, await AcquireAsync(contentTypeDefinition)); + await UpdateContentDefinitionRecordAsync(); } - public void StorePartDefinition(ContentPartDefinition contentPartDefinition) + public async Task StorePartDefinitionAsync(ContentPartDefinition contentPartDefinition) { - Apply(contentPartDefinition, Acquire(contentPartDefinition)); - UpdateContentDefinitionRecord(); + Apply(contentPartDefinition, await AcquireAsync(contentPartDefinition)); + await UpdateContentDefinitionRecordAsync(); } - public void DeleteTypeDefinition(string name) + public async Task DeleteTypeDefinitionAsync(string name) { - var record = GetContentDefinitionRecord().ContentTypeDefinitionRecords.FirstOrDefault(x => x.Name == name); + var record = (await GetContentDefinitionRecordAsync()).ContentTypeDefinitionRecords.FirstOrDefault(type => type.Name == name); // deletes the content type record associated if (record != null) { - GetContentDefinitionRecord().ContentTypeDefinitionRecords.Remove(record); - UpdateContentDefinitionRecord(); + (await GetContentDefinitionRecordAsync()).ContentTypeDefinitionRecords.Remove(record); + await UpdateContentDefinitionRecordAsync(); } } - public void DeletePartDefinition(string name) + public async Task DeletePartDefinitionAsync(string name) { // remove parts from current types - var typesWithPart = ListTypeDefinitions().Where(typeDefinition => typeDefinition.Parts.Any(part => part.PartDefinition.Name == name)); + var typesWithPart = (await ListTypeDefinitionsAsync()).Where(typeDefinition => typeDefinition.Parts.Any(part => part.PartDefinition.Name == name)); foreach (var typeDefinition in typesWithPart) { - this.AlterTypeDefinition(typeDefinition.Name, builder => builder.RemovePart(name)); + await this.AlterTypeDefinitionAsync(typeDefinition.Name, builder => builder.RemovePart(name)); } // delete part - var record = GetContentDefinitionRecord().ContentPartDefinitionRecords.FirstOrDefault(x => x.Name == name); + var record = (await GetContentDefinitionRecordAsync()).ContentPartDefinitionRecords.FirstOrDefault(part => part.Name == name); if (record != null) { - GetContentDefinitionRecord().ContentPartDefinitionRecords.Remove(record); - UpdateContentDefinitionRecord(); + (await GetContentDefinitionRecordAsync()).ContentPartDefinitionRecords.Remove(record); + await UpdateContentDefinitionRecordAsync(); } } - private ContentTypeDefinitionRecord Acquire(ContentTypeDefinition contentTypeDefinition) + private async Task AcquireAsync(ContentTypeDefinition contentTypeDefinition) { - var result = GetContentDefinitionRecord().ContentTypeDefinitionRecords.FirstOrDefault(x => x.Name == contentTypeDefinition.Name); + var result = (await GetContentDefinitionRecordAsync()).ContentTypeDefinitionRecords.FirstOrDefault(type => type.Name == contentTypeDefinition.Name); if (result == null) { result = new ContentTypeDefinitionRecord { Name = contentTypeDefinition.Name, DisplayName = contentTypeDefinition.DisplayName }; - GetContentDefinitionRecord().ContentTypeDefinitionRecords.Add(result); + (await GetContentDefinitionRecordAsync()).ContentTypeDefinitionRecords.Add(result); } return result; } - private ContentPartDefinitionRecord Acquire(ContentPartDefinition contentPartDefinition) + private async Task AcquireAsync(ContentPartDefinition contentPartDefinition) { - var result = GetContentDefinitionRecord().ContentPartDefinitionRecords.FirstOrDefault(x => x.Name == contentPartDefinition.Name); + var result = (await GetContentDefinitionRecordAsync()).ContentPartDefinitionRecords.FirstOrDefault(part => part.Name == contentPartDefinition.Name); if (result == null) { result = new ContentPartDefinitionRecord { Name = contentPartDefinition.Name, }; - GetContentDefinitionRecord().ContentPartDefinitionRecords.Add(result); + (await GetContentDefinitionRecordAsync()).ContentPartDefinitionRecords.Add(result); } return result; } - private ContentFieldDefinitionRecord Acquire(ContentFieldDefinition contentFieldDefinition) - { - return new ContentFieldDefinitionRecord { Name = contentFieldDefinition.Name }; - } - - private void Apply(ContentTypeDefinition model, ContentTypeDefinitionRecord record) + private Task ApplyAsync(ContentTypeDefinition model, ContentTypeDefinitionRecord record) { record.DisplayName = model.DisplayName; record.Settings = model.Settings; var toRemove = record.ContentTypePartDefinitionRecords - .Where(typePartDefinitionRecord => !model.Parts.Any(part => typePartDefinitionRecord.Name == part.Name)) + .Where(typePartDefinitionRecord => !model.Parts.Any(typePart => typePartDefinitionRecord.Name == typePart.Name)) .ToList(); foreach (var remove in toRemove) @@ -156,7 +171,7 @@ private void Apply(ContentTypeDefinition model, ContentTypeDefinitionRecord reco foreach (var part in model.Parts) { - var typePartRecord = record.ContentTypePartDefinitionRecords.FirstOrDefault(r => r.Name == part.Name); + var typePartRecord = record.ContentTypePartDefinitionRecords.FirstOrDefault(typePart => typePart.Name == part.Name); if (typePartRecord == null) { typePartRecord = new ContentTypePartDefinitionRecord @@ -172,7 +187,7 @@ private void Apply(ContentTypeDefinition model, ContentTypeDefinitionRecord reco } // Persist changes - UpdateContentDefinitionRecord(); + return UpdateContentDefinitionRecordAsync(); } private void Apply(ContentTypePartDefinition model, ContentTypePartDefinitionRecord record) @@ -215,25 +230,31 @@ private void Apply(ContentPartFieldDefinition model, ContentPartFieldDefinitionR record.Settings = model.Settings; } - ContentTypeDefinition Build(ContentTypeDefinitionRecord source) + async Task BuildAsync(ContentTypeDefinitionRecord source) { - if(source == null) + if (source == null) { return null; } + var typePartDefinitions = new List(); + foreach(var typePartDefinition in source.ContentTypePartDefinitionRecords) + { + typePartDefinitions.Add(await BuildAsync(typePartDefinition)); + } + var contentTypeDefinition = new ContentTypeDefinition( source.Name, source.DisplayName, - source.ContentTypePartDefinitionRecords.Select(Build), + typePartDefinitions, source.Settings); return contentTypeDefinition; } - ContentTypePartDefinition Build(ContentTypePartDefinitionRecord source) + async Task BuildAsync(ContentTypePartDefinitionRecord source) { - var partDefinitionRecord = GetContentDefinitionRecord().ContentPartDefinitionRecords.FirstOrDefault(x => x.Name == source.PartName); + var partDefinitionRecord = (await GetContentDefinitionRecordAsync()).ContentPartDefinitionRecords.FirstOrDefault(part => part.Name == source.PartName); return source == null ? null : new ContentTypePartDefinition( source.Name, @@ -263,7 +284,7 @@ ContentFieldDefinition Build(ContentFieldDefinitionRecord source) return source == null ? null : new ContentFieldDefinition(source.Name); } - public Task GetTypesHashAsync() + public async Task GetTypesHashAsync() { // The serial number is stored in local cache in order to prevent // loading the record if it's not necessary @@ -273,28 +294,28 @@ public Task GetTypesHashAsync() { serial = _memoryCache.Set( TypeHashCacheKey, - GetContentDefinitionRecord().Serial, + (await GetContentDefinitionRecordAsync()).Serial, _signal.GetToken(TypeHashCacheKey) ); } - return Task.FromResult(serial); + return serial; } - private ContentDefinitionRecord GetContentDefinitionRecord() + private async Task GetContentDefinitionRecordAsync() { if (_contentDefinitionRecord != null) { return _contentDefinitionRecord; } - return _contentDefinitionRecord = _contentDefinitionStore.LoadContentDefinitionAsync().GetAwaiter().GetResult(); + return _contentDefinitionRecord = await _contentDefinitionStore.LoadContentDefinitionAsync(); } - private void UpdateContentDefinitionRecord() + private async Task UpdateContentDefinitionRecordAsync() { _contentDefinitionRecord.Serial++; - _contentDefinitionStore.SaveContentDefinitionAsync(_contentDefinitionRecord).GetAwaiter().GetResult(); + await _contentDefinitionStore.SaveContentDefinitionAsync(_contentDefinitionRecord); _signal.SignalToken(TypeHashCacheKey); @@ -303,6 +324,5 @@ private void UpdateContentDefinitionRecord() _typeDefinitions.Clear(); _partDefinitions.Clear(); } - } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.ContentManagement/DefaultContentManager.cs b/src/OrchardCore/OrchardCore.ContentManagement/DefaultContentManager.cs index a29816c9e7b..c735e3c7bdb 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/DefaultContentManager.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/DefaultContentManager.cs @@ -46,7 +46,7 @@ public DefaultContentManager( public async Task NewAsync(string contentType) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentType); if (contentTypeDefinition == null) { contentTypeDefinition = new ContentTypeDefinitionBuilder().Named(contentType).Build(); @@ -178,7 +178,7 @@ public async Task GetAsync(string contentItemId, VersionOptions opt // Save the previous version _session.Save(contentItem); - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); // Check if not versionable, meaning we use only one version if (!(contentTypeDefinition?.Settings.ToObject().Versionable ?? true)) diff --git a/src/OrchardCore/OrchardCore.ContentManagement/Handlers/ContentPartHandlerCoordinator.cs b/src/OrchardCore/OrchardCore.ContentManagement/Handlers/ContentPartHandlerCoordinator.cs index 4fb533bdb2f..f549a969e6e 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/Handlers/ContentPartHandlerCoordinator.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/Handlers/ContentPartHandlerCoordinator.cs @@ -39,7 +39,7 @@ public override async Task ActivatingAsync(ActivatingContentContext context) // This method is called on New() // Adds all the parts to a content item based on the content type definition. - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentType); if (contentTypeDefinition == null) return; @@ -58,7 +58,7 @@ public override async Task ActivatingAsync(ActivatingContentContext context) public override async Task ActivatedAsync(ActivatedContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -77,7 +77,7 @@ public override async Task ActivatedAsync(ActivatedContentContext context) public override async Task CreatingAsync(CreateContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -97,7 +97,7 @@ public override async Task CreatingAsync(CreateContentContext context) public override async Task CreatedAsync(CreateContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -117,7 +117,7 @@ public override async Task CreatedAsync(CreateContentContext context) public override async Task InitializingAsync(InitializingContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -133,7 +133,7 @@ public override async Task InitializingAsync(InitializingContentContext context) public override async Task InitializedAsync(InitializingContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -158,7 +158,7 @@ public override async Task LoadingAsync(LoadContentContext context) // A part is missing if the content type is changed and an old content item is loaded, // like edited. - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) { return; @@ -195,7 +195,7 @@ public override async Task LoadingAsync(LoadContentContext context) public override async Task LoadedAsync(LoadContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -215,7 +215,7 @@ public override async Task LoadedAsync(LoadContentContext context) public override async Task PublishingAsync(PublishContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -234,7 +234,7 @@ public override async Task PublishingAsync(PublishContentContext context) public override async Task PublishedAsync(PublishContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -253,7 +253,7 @@ public override async Task PublishedAsync(PublishContentContext context) public override async Task RemovingAsync(RemoveContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -272,7 +272,7 @@ public override async Task RemovingAsync(RemoveContentContext context) public override async Task RemovedAsync(RemoveContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -291,7 +291,7 @@ public override async Task RemovedAsync(RemoveContentContext context) public override async Task UnpublishingAsync(PublishContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -310,7 +310,7 @@ public override async Task UnpublishingAsync(PublishContentContext context) public override async Task UnpublishedAsync(PublishContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -329,7 +329,7 @@ public override async Task UnpublishedAsync(PublishContentContext context) public override async Task UpdatingAsync(UpdateContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -348,7 +348,7 @@ public override async Task UpdatingAsync(UpdateContentContext context) public override async Task UpdatedAsync(UpdateContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -367,7 +367,7 @@ public override async Task UpdatedAsync(UpdateContentContext context) public override async Task VersioningAsync(VersionContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -388,7 +388,7 @@ public override async Task VersioningAsync(VersionContentContext context) public override async Task VersionedAsync(VersionContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -409,7 +409,7 @@ public override async Task VersionedAsync(VersionContentContext context) public override async Task GetContentItemAspectAsync(ContentItemAspectContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -427,7 +427,7 @@ public override async Task GetContentItemAspectAsync(ContentItemAspectContext co } public override async Task ClonedAsync(CloneContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -445,7 +445,7 @@ public override async Task ClonedAsync(CloneContentContext context) } public override async Task CloningAsync(CloneContentContext context) { - var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -463,4 +463,4 @@ public override async Task CloningAsync(CloneContentContext context) } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.Data.Abstractions/IDataMigration.cs b/src/OrchardCore/OrchardCore.Data.Abstractions/IDataMigration.cs index b205f089b6c..d6528462b05 100644 --- a/src/OrchardCore/OrchardCore.Data.Abstractions/IDataMigration.cs +++ b/src/OrchardCore/OrchardCore.Data.Abstractions/IDataMigration.cs @@ -6,4 +6,4 @@ public interface IDataMigration { ISchemaBuilder SchemaBuilder { get; set; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.Data/Migration/AutomaticDataMigrations.cs b/src/OrchardCore/OrchardCore.Data/Migration/AutomaticDataMigrations.cs index 41fddfca08c..d4cfe8b1a03 100644 --- a/src/OrchardCore/OrchardCore.Data/Migration/AutomaticDataMigrations.cs +++ b/src/OrchardCore/OrchardCore.Data/Migration/AutomaticDataMigrations.cs @@ -39,4 +39,4 @@ public override Task ActivatingAsync() return Task.CompletedTask; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.Media.Abstractions/IMediaFactorySelector.cs b/src/OrchardCore/OrchardCore.Media.Abstractions/IMediaFactorySelector.cs index b473f7f3c96..59a71725316 100644 --- a/src/OrchardCore/OrchardCore.Media.Abstractions/IMediaFactorySelector.cs +++ b/src/OrchardCore/OrchardCore.Media.Abstractions/IMediaFactorySelector.cs @@ -1,9 +1,10 @@ -using System.IO; +using System.IO; +using System.Threading.Tasks; namespace OrchardCore.Media { public interface IMediaFactorySelector { - MediaFactorySelectorResult GetMediaFactory(Stream stream, string fileName, string mimeType, string contentType); + Task GetMediaFactoryAsync(Stream stream, string fileName, string mimeType, string contentType); } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.Media.Abstractions/IMediaService.cs b/src/OrchardCore/OrchardCore.Media.Abstractions/IMediaService.cs index 89644c967b8..bd9ce0633d2 100644 --- a/src/OrchardCore/OrchardCore.Media.Abstractions/IMediaService.cs +++ b/src/OrchardCore/OrchardCore.Media.Abstractions/IMediaService.cs @@ -23,6 +23,6 @@ public interface IMediaService /// The mime-type of the file to process. /// The content type intended to be created. /// - IMediaFactory GetMediaFactory(Stream stream, string fileName, string mimeType, string contentType); + Task GetMediaFactoryAsync(Stream stream, string fileName, string mimeType, string contentType); } } diff --git a/src/OrchardCore/OrchardCore.Media.Services/ImageFactory.cs b/src/OrchardCore/OrchardCore.Media.Services/ImageFactory.cs index 0e7573acef0..68f8f7f8c53 100644 --- a/src/OrchardCore/OrchardCore.Media.Services/ImageFactory.cs +++ b/src/OrchardCore/OrchardCore.Media.Services/ImageFactory.cs @@ -20,7 +20,7 @@ public ImageFactorySelector(IContentManager contentManager, IContentDefinitionMa _contentDefinitionManager = contentDefinitionManager; } - public MediaFactorySelectorResult GetMediaFactory(Stream stream, string fileName, string mimeType, string contentType) + public async Task GetMediaFactoryAsync(Stream stream, string fileName, string mimeType, string contentType) { if (!mimeType.StartsWith("image/")) { @@ -29,7 +29,7 @@ public MediaFactorySelectorResult GetMediaFactory(Stream stream, string fileName if (!String.IsNullOrEmpty(contentType)) { - var contentDefinition = _contentDefinitionManager.GetTypeDefinition(contentType); + var contentDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentType); if (contentDefinition == null || contentDefinition.Parts.All(x => x.PartDefinition.Name != typeof(ImageMediaPart).Name)) { return null; @@ -72,4 +72,4 @@ public async Task CreateMediaAsync(Stream stream, string path, string return media; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.Media.Services/MediaService.cs b/src/OrchardCore/OrchardCore.Media.Services/MediaService.cs index f4a475c6ed1..bfd1ac91cf8 100644 --- a/src/OrchardCore/OrchardCore.Media.Services/MediaService.cs +++ b/src/OrchardCore/OrchardCore.Media.Services/MediaService.cs @@ -28,7 +28,7 @@ public async Task ImportMediaAsync(string path, string mimeType, strin using (var stream = await _mediaFileStore.GetFileStreamAsync(path)) { - var mediaFactory = GetMediaFactory(stream, file.Name, mimeType, contentType); + var mediaFactory = await GetMediaFactoryAsync(stream, file.Name, mimeType, contentType); if (mediaFactory == null) { @@ -39,11 +39,19 @@ public async Task ImportMediaAsync(string path, string mimeType, strin } } - public IMediaFactory GetMediaFactory(Stream stream, string fileName, string mimeType, string contentType) + public async Task GetMediaFactoryAsync(Stream stream, string fileName, string mimeType, string contentType) { - var requestMediaFactoryResult = _mediaFactorySelectors - .Select(x => x.GetMediaFactory(stream, fileName, mimeType, contentType)) - .Where(x => x != null) + var results = new List(); + foreach (var selector in _mediaFactorySelectors) + { + var result = await selector.GetMediaFactoryAsync(stream, fileName, mimeType, contentType); + if (result != null) + { + results.Add(result); + } + } + + var requestMediaFactoryResult = results .OrderByDescending(x => x.Priority) .FirstOrDefault(); From 53f1da1b482d34350f347b101e02cfb876347d6c Mon Sep 17 00:00:00 2001 From: jtkech Date: Sat, 20 Jul 2019 08:00:15 +0200 Subject: [PATCH 18/38] Fixes building --- src/OrchardCore.Modules/OrchardCore.Demo/Migrations.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Demo/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Demo/Migrations.cs index cb5a20161d2..58bb5e5fcf3 100644 --- a/src/OrchardCore.Modules/OrchardCore.Demo/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Demo/Migrations.cs @@ -1,4 +1,5 @@ -using OrchardCore.ContentManagement.Metadata; +using System.Threading.Tasks; +using OrchardCore.ContentManagement.Metadata; using OrchardCore.Data.Migration; namespace OrchardCore.Demo @@ -12,9 +13,9 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public int Create() + public async Task CreateAsync() { - _contentDefinitionManager.AlterTypeDefinition("Foo", builder => builder + await _contentDefinitionManager.AlterTypeDefinitionAsync("Foo", builder => builder .WithPart("TestContentPartA") .WithPart("TestContentPartB") ); @@ -22,4 +23,4 @@ public int Create() return 1; } } -} \ No newline at end of file +} From e5c79ef18bcbe530fc85fb0c5d442532231213fe Mon Sep 17 00:00:00 2001 From: jtkech Date: Sun, 21 Jul 2019 01:41:38 +0200 Subject: [PATCH 19/38] Make CreateUser command async and await all async commands --- .../OrchardCore.Flows/Migrations.cs | 2 +- .../OrchardCore.Html/Migrations.cs | 2 +- .../OrchardCore.Title/Migrations.cs | 2 +- .../OrchardCore.Users/Commands/UserCommands.cs | 9 +++++---- .../Commands/DefaultCommandHandler.cs | 15 ++++++++++++++- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Flows/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Flows/Migrations.cs index d19fd5411c7..30c631ef2c0 100644 --- a/src/OrchardCore.Modules/OrchardCore.Flows/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Flows/Migrations.cs @@ -23,7 +23,7 @@ await _contentDefinitionManager.AlterPartDefinitionAsync("FlowPart", builder => return 1; } - public async Task UpdateFrom1() + public async Task UpdateFrom1Async() { await _contentDefinitionManager.AlterPartDefinitionAsync("BagPart", builder => builder .Attachable() diff --git a/src/OrchardCore.Modules/OrchardCore.Html/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Html/Migrations.cs index 41c78b33258..49db1c1df51 100644 --- a/src/OrchardCore.Modules/OrchardCore.Html/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Html/Migrations.cs @@ -43,7 +43,7 @@ public int UpdateFrom2() return 3; } - public async Task UpdateFrom3() + public async Task UpdateFrom3Async() { // This code can be removed in RC diff --git a/src/OrchardCore.Modules/OrchardCore.Title/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Title/Migrations.cs index de139d86c39..0ade56d0a5e 100644 --- a/src/OrchardCore.Modules/OrchardCore.Title/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Title/Migrations.cs @@ -39,7 +39,7 @@ await _contentDefinitionManager.AlterPartDefinitionAsync("TitlePart", builder => return 2; } - public async Task UpdateFrom1() + public async Task UpdateFrom1Async() { // This code can be removed in RC // We are patching all content item versions by moving the Title to DisplayText diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Commands/UserCommands.cs b/src/OrchardCore.Modules/OrchardCore.Users/Commands/UserCommands.cs index 6116662619c..64c2ec5d08a 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Commands/UserCommands.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/Commands/UserCommands.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading.Tasks; using Microsoft.Extensions.Localization; using OrchardCore.Environment.Commands; using OrchardCore.Users.Models; @@ -32,17 +33,17 @@ public UserCommands(IUserService userService, [CommandName("createUser")] [CommandHelp("createUser /UserName: /Password: /Email: /Roles:{rolename,rolename,...}\r\n\t" + "Creates a new User")] [OrchardSwitches("UserName,Password,Email,Roles")] - public void CreateUser() + public async Task CreateUserAsync() { var roleNames = (Roles ?? "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); var valid = true; - _userService.CreateUserAsync(new User { UserName = UserName, Email = Email, RoleNames = roleNames, EmailConfirmed = true }, Password, (key, message) => + await _userService.CreateUserAsync(new User { UserName = UserName, Email = Email, RoleNames = roleNames, EmailConfirmed = true }, Password, (key, message) => { valid = false; Context.Output.WriteLine(message); - }).GetAwaiter().GetResult(); + }); if (valid) { @@ -50,4 +51,4 @@ public void CreateUser() } } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Commands/DefaultCommandHandler.cs b/src/OrchardCore/OrchardCore.Infrastructure/Commands/DefaultCommandHandler.cs index 8f4cf1f1c73..2c639f8c7fb 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Commands/DefaultCommandHandler.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Commands/DefaultCommandHandler.cs @@ -83,6 +83,19 @@ private async Task InvokeAsync(CommandContext context) } this.Context = context; + + if (context.CommandDescriptor.MethodInfo.ReturnType == typeof(Task)) + { + var taskResult = await (Task)context.CommandDescriptor.MethodInfo.Invoke(this, invokeParameters); + await context.Output.WriteAsync(taskResult); + return; + } + else if (typeof(Task).IsAssignableFrom(context.CommandDescriptor.MethodInfo.ReturnType)) + { + await (Task)context.CommandDescriptor.MethodInfo.Invoke(this, invokeParameters); + return; + } + var result = context.CommandDescriptor.MethodInfo.Invoke(this, invokeParameters); if (result is string) { @@ -181,4 +194,4 @@ private static object ConvertToType(Type type, string value) } } } -} \ No newline at end of file +} From f9d00bd14062d5f8d635a1cba40d102fa0495223 Mon Sep 17 00:00:00 2001 From: jtkech Date: Sun, 21 Jul 2019 03:09:25 +0200 Subject: [PATCH 20/38] More async --- .../FileContentDefinitionStore.cs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs b/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs index 35e91d4f805..6e6dcee5d16 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.Options; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using OrchardCore.ContentManagement.Metadata.Records; using OrchardCore.Environment.Shell; @@ -18,25 +19,20 @@ public FileContentDefinitionStore(IOptions shellOptions, ShellSett _shellSettings = shellSettings; } - public Task LoadContentDefinitionAsync() + public async Task LoadContentDefinitionAsync() { - - ContentDefinitionRecord result; - if (!File.Exists(Filename)) { - result = new ContentDefinitionRecord(); + return new ContentDefinitionRecord(); } - else + + using (var file = File.OpenText(Filename)) { - using (var file = File.OpenText(Filename)) + using (var reader = new JsonTextReader(file)) { - var serializer = new JsonSerializer(); - result = (ContentDefinitionRecord)serializer.Deserialize(file, typeof(ContentDefinitionRecord)); + return (await JObject.LoadAsync(reader)).ToObject(); } } - - return Task.FromResult(result); } public Task SaveContentDefinitionAsync(ContentDefinitionRecord contentDefinitionRecord) From 5c48e1b852f691648fc0b6f3a7cc4677b3e47b57 Mon Sep 17 00:00:00 2001 From: jtkech Date: Mon, 22 Jul 2019 00:42:30 +0200 Subject: [PATCH 21/38] More async --- .../FileContentDefinitionStore.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs b/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs index 6e6dcee5d16..5ef2c1d9078 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs @@ -35,16 +35,15 @@ public async Task LoadContentDefinitionAsync() } } - public Task SaveContentDefinitionAsync(ContentDefinitionRecord contentDefinitionRecord) + public async Task SaveContentDefinitionAsync(ContentDefinitionRecord contentDefinitionRecord) { using (var file = File.CreateText(Filename)) { - var serializer = new JsonSerializer(); - serializer.Formatting = Formatting.Indented; - serializer.Serialize(file, contentDefinitionRecord); + using (var writer = new JsonTextWriter(file)) + { + await JObject.FromObject(contentDefinitionRecord).WriteToAsync(writer); + } } - - return Task.CompletedTask; } private string Filename => PathExtensions.Combine( From dda50cade180dccc3589ec73910f184356707afc Mon Sep 17 00:00:00 2001 From: jtkech Date: Mon, 22 Jul 2019 03:50:07 +0200 Subject: [PATCH 22/38] Make FileContentDefinitionStore thread safe. --- .../FileContentDefinitionStore.cs | 58 ++++++++++++++----- .../ServiceCollectionExtensions.cs | 2 +- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs b/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs index 5ef2c1d9078..fa7e10645c9 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs @@ -1,55 +1,81 @@ using System.IO; +using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Options; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OrchardCore.ContentManagement.Metadata.Records; using OrchardCore.Environment.Shell; +using OrchardCore.Environment.Shell.Scope; namespace OrchardCore.ContentManagement { public class FileContentDefinitionStore : IContentDefinitionStore { private readonly IOptions _shellOptions; - private readonly ShellSettings _shellSettings; + private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); - public FileContentDefinitionStore(IOptions shellOptions, ShellSettings shellSettings) + public FileContentDefinitionStore(IOptions shellOptions) { _shellOptions = shellOptions; - _shellSettings = shellSettings; } - public async Task LoadContentDefinitionAsync() + public Task LoadContentDefinitionAsync() { - if (!File.Exists(Filename)) + var fileName = GetFilename(); + + if (!File.Exists(fileName)) { - return new ContentDefinitionRecord(); + return Task.FromResult(new ContentDefinitionRecord()); } - using (var file = File.OpenText(Filename)) + _lock.EnterReadLock(); + + try { - using (var reader = new JsonTextReader(file)) + using (var file = File.OpenText(fileName)) { - return (await JObject.LoadAsync(reader)).ToObject(); + using (var reader = new JsonTextReader(file)) + { + // We don't use 'LoadAsync' because we use a thread-affine lock type. + return Task.FromResult((JObject.Load(reader)).ToObject()); + } } } + + finally + { + _lock.ExitReadLock(); + } } - public async Task SaveContentDefinitionAsync(ContentDefinitionRecord contentDefinitionRecord) + public Task SaveContentDefinitionAsync(ContentDefinitionRecord contentDefinitionRecord) { - using (var file = File.CreateText(Filename)) + _lock.EnterWriteLock(); + + try { - using (var writer = new JsonTextWriter(file)) + using (var file = File.CreateText(GetFilename())) { - await JObject.FromObject(contentDefinitionRecord).WriteToAsync(writer); + using (var writer = new JsonTextWriter(file)) + { + // We don't use 'WriteToAsync' because we use a thread-affine lock type. + JObject.FromObject(contentDefinitionRecord).WriteTo(writer); + } } } + + finally + { + _lock.ExitWriteLock(); + } + + return Task.CompletedTask; } - private string Filename => PathExtensions.Combine( + private string GetFilename() => PathExtensions.Combine( _shellOptions.Value.ShellsApplicationDataPath, _shellOptions.Value.ShellsContainerName, - _shellSettings.Name, "ContentDefinition.json"); - + ShellScope.Context.Settings.Name, "ContentDefinition.json"); } } diff --git a/src/OrchardCore/OrchardCore.ContentManagement/ServiceCollectionExtensions.cs b/src/OrchardCore/OrchardCore.ContentManagement/ServiceCollectionExtensions.cs index 7b1afd04057..20fe2001bd4 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/ServiceCollectionExtensions.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/ServiceCollectionExtensions.cs @@ -36,7 +36,7 @@ public static IServiceCollection AddContentManagement(this IServiceCollection se public static IServiceCollection AddFileContentDefinitionStore(this IServiceCollection services) { services.RemoveAll(); - services.TryAddScoped(); + services.AddSingleton(); return services; } From 3a32e5a11c1ddf615b3a1c1ddb78b4b9dfdbeea6 Mon Sep 17 00:00:00 2001 From: jtkech Date: Mon, 22 Jul 2019 21:41:31 +0200 Subject: [PATCH 23/38] Fixes an use case that ends up with 2 latest versions --- .../OrchardCore.ContentManagement/DefaultContentManager.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/OrchardCore/OrchardCore.ContentManagement/DefaultContentManager.cs b/src/OrchardCore/OrchardCore.ContentManagement/DefaultContentManager.cs index c735e3c7bdb..0b6e48c6679 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/DefaultContentManager.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/DefaultContentManager.cs @@ -175,9 +175,7 @@ public async Task GetAsync(string contentItemId, VersionOptions opt // When draft is required and latest is published a new version is added if (contentItem.Published) { - // Save the previous version - _session.Save(contentItem); - + // We save the previous version further because this call might do a session query. var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); // Check if not versionable, meaning we use only one version @@ -187,6 +185,9 @@ public async Task GetAsync(string contentItemId, VersionOptions opt } else { + // Save the previous version + _session.Save(contentItem); + contentItem = await BuildNewVersionAsync(contentItem); } } From a95923a6f38d97b78a8b5e56394536e39ce58411 Mon Sep 17 00:00:00 2001 From: jtkech Date: Mon, 22 Jul 2019 23:47:59 +0200 Subject: [PATCH 24/38] Try to fix travis build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3ac7367efbd..b2f1189ccc2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,7 @@ os: - osx osx_image: xcode8.3 script: - - curl https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.sh | bash /dev/stdin --version 2.2.103 + - curl https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.sh | bash /dev/stdin --version 2.2.105 - if test "$TRAVIS_OS_NAME" == "linux"; then export PATH="/home/travis/.dotnet":"$PATH"; fi - if test "$TRAVIS_OS_NAME" == "osx"; then export PATH="/Users/travis/.dotnet":"$PATH"; fi - dotnet --info From 069109c5eefea66b8094e82ba6bc8c2601ead5d7 Mon Sep 17 00:00:00 2001 From: jtkech Date: Wed, 24 Jul 2019 01:32:39 +0200 Subject: [PATCH 25/38] Definition manager and store as tenant singletons for simpler and better caching. The definitions are read once in place of each time a definition for a given is not built yet. Fixes that, when the type is modified, the definitions were stored twice. --- .../ContentDefinitionManager.cs | 33 ++++--------------- .../DatabaseContentDefinitionStore.cs | 13 ++++---- .../FileContentDefinitionStore.cs | 2 +- .../ServiceCollectionExtensions.cs | 4 +-- 4 files changed, 16 insertions(+), 36 deletions(-) diff --git a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs index 1fdfe9a7712..5b096bb06df 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Primitives; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Models; @@ -16,7 +15,6 @@ public class ContentDefinitionManager : IContentDefinitionManager private const string TypeHashCacheKey = "ContentDefinitionManager:Serial"; private ContentDefinitionRecord _contentDefinitionRecord; - private readonly IMemoryCache _memoryCache; private readonly ISignal _signal; private readonly IContentDefinitionStore _contentDefinitionStore; private readonly ConcurrentDictionary _typeDefinitions; @@ -25,16 +23,14 @@ public class ContentDefinitionManager : IContentDefinitionManager public IChangeToken ChangeToken => _signal.GetToken(TypeHashCacheKey); public ContentDefinitionManager( - IMemoryCache memoryCache, ISignal signal, IContentDefinitionStore contentDefinitionStore) { _signal = signal; _contentDefinitionStore = contentDefinitionStore; - _memoryCache = memoryCache; - _typeDefinitions = _memoryCache.GetOrCreate("TypeDefinitions", entry => new ConcurrentDictionary()); - _partDefinitions = _memoryCache.GetOrCreate("PartDefinitions", entry => new ConcurrentDictionary()); + _typeDefinitions = new ConcurrentDictionary(); + _partDefinitions = new ConcurrentDictionary(); } public async Task GetTypeDefinitionAsync(string name) @@ -91,7 +87,7 @@ public async Task> ListPartDefinitionsAsync() public async Task StoreTypeDefinitionAsync(ContentTypeDefinition contentTypeDefinition) { - await ApplyAsync(contentTypeDefinition, await AcquireAsync(contentTypeDefinition)); + Apply(contentTypeDefinition, await AcquireAsync(contentTypeDefinition)); await UpdateContentDefinitionRecordAsync(); } @@ -155,7 +151,7 @@ private async Task AcquireAsync(ContentPartDefiniti return result; } - private Task ApplyAsync(ContentTypeDefinition model, ContentTypeDefinitionRecord record) + private void Apply(ContentTypeDefinition model, ContentTypeDefinitionRecord record) { record.DisplayName = model.DisplayName; record.Settings = model.Settings; @@ -185,9 +181,6 @@ private Task ApplyAsync(ContentTypeDefinition model, ContentTypeDefinitionRecord } Apply(part, typePartRecord); } - - // Persist changes - return UpdateContentDefinitionRecordAsync(); } private void Apply(ContentTypePartDefinition model, ContentTypePartDefinitionRecord record) @@ -238,7 +231,7 @@ async Task BuildAsync(ContentTypeDefinitionRecord source) } var typePartDefinitions = new List(); - foreach(var typePartDefinition in source.ContentTypePartDefinitionRecords) + foreach (var typePartDefinition in source.ContentTypePartDefinitionRecords) { typePartDefinitions.Add(await BuildAsync(typePartDefinition)); } @@ -286,20 +279,7 @@ ContentFieldDefinition Build(ContentFieldDefinitionRecord source) public async Task GetTypesHashAsync() { - // The serial number is stored in local cache in order to prevent - // loading the record if it's not necessary - - int serial; - if (!_memoryCache.TryGetValue(TypeHashCacheKey, out serial)) - { - serial = _memoryCache.Set( - TypeHashCacheKey, - (await GetContentDefinitionRecordAsync()).Serial, - _signal.GetToken(TypeHashCacheKey) - ); - } - - return serial; + return (await GetContentDefinitionRecordAsync()).Serial; } private async Task GetContentDefinitionRecordAsync() @@ -319,7 +299,6 @@ private async Task UpdateContentDefinitionRecordAsync() _signal.SignalToken(TypeHashCacheKey); - // Release cached values _typeDefinitions.Clear(); _partDefinitions.Clear(); diff --git a/src/OrchardCore/OrchardCore.ContentManagement/DatabaseContentDefinitionStore.cs b/src/OrchardCore/OrchardCore.ContentManagement/DatabaseContentDefinitionStore.cs index c0828a060fe..8cd17fd901b 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/DatabaseContentDefinitionStore.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/DatabaseContentDefinitionStore.cs @@ -1,21 +1,20 @@ using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using OrchardCore.ContentManagement.Metadata.Records; +using OrchardCore.Environment.Shell.Scope; using YesSql; namespace OrchardCore.ContentManagement { public class DatabaseContentDefinitionStore : IContentDefinitionStore { - private readonly ISession _session; - - public DatabaseContentDefinitionStore(ISession session) + public DatabaseContentDefinitionStore() { - _session = session; } public async Task LoadContentDefinitionAsync() { - var contentDefinitionRecord = await _session + var contentDefinitionRecord = await Session .Query() .FirstOrDefaultAsync(); @@ -30,9 +29,11 @@ public async Task LoadContentDefinitionAsync() public Task SaveContentDefinitionAsync(ContentDefinitionRecord contentDefinitionRecord) { - _session.Save(contentDefinitionRecord); + Session.Save(contentDefinitionRecord); return Task.CompletedTask; } + + private ISession Session => ShellScope.Services.GetRequiredService(); } } diff --git a/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs b/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs index fa7e10645c9..fac7597788a 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs @@ -38,7 +38,7 @@ public Task LoadContentDefinitionAsync() using (var reader = new JsonTextReader(file)) { // We don't use 'LoadAsync' because we use a thread-affine lock type. - return Task.FromResult((JObject.Load(reader)).ToObject()); + return Task.FromResult(JObject.Load(reader).ToObject()); } } } diff --git a/src/OrchardCore/OrchardCore.ContentManagement/ServiceCollectionExtensions.cs b/src/OrchardCore/OrchardCore.ContentManagement/ServiceCollectionExtensions.cs index 20fe2001bd4..134988058d7 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/ServiceCollectionExtensions.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/ServiceCollectionExtensions.cs @@ -16,8 +16,8 @@ public static class ServiceCollectionExtensions public static IServiceCollection AddContentManagement(this IServiceCollection services) { services.AddScoped(); - services.TryAddScoped(); - services.TryAddScoped(); + services.AddSingleton(); + services.AddSingleton(); services.TryAddScoped(); services.TryAddScoped(); services.AddSingleton(); From 09fb612396976b0dffa7914cce206842eab12731 Mon Sep 17 00:00:00 2001 From: jtkech Date: Sat, 3 Aug 2019 01:07:59 +0200 Subject: [PATCH 26/38] Tenant level and scoped ContentDefinitionCache. And begin to use some rules around caching and tokens that i will comment and to be continued in another PR. --- .../HomeRouteMiddleware.cs | 4 +- .../Services/SiteService.cs | 36 +++--- .../Records/ContentDefinitionCache.cs | 10 ++ .../Records/ContentDefinitionRecord.cs | 28 +++-- .../Records/ContentFieldDefinitionRecord.cs | 2 +- .../Records/ContentPartDefinitionRecord.cs | 18 ++- .../Records/ContentTypeDefinitionRecord.cs | 19 +++- .../ContentDefinitionManager.cs | 106 ++++++++++++------ .../DatabaseContentDefinitionStore.cs | 6 +- .../FileContentDefinitionStore.cs | 32 +++--- .../ServiceCollectionExtensions.cs | 2 + 11 files changed, 171 insertions(+), 92 deletions(-) create mode 100644 src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentDefinitionCache.cs diff --git a/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs b/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs index 6b6e836b528..8191fe2a7d3 100644 --- a/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs +++ b/src/OrchardCore.Modules/OrchardCore.HomeRoute/HomeRouteMiddleware.cs @@ -13,7 +13,6 @@ public class HomeRouteMiddleware private RouteValueDictionary _homeRoute; private IChangeToken _changeToken; - // 'HomeRoute' requires a registered 'ISiteService' implementation. public HomeRouteMiddleware(RequestDelegate next, ISiteService siteService) { _next = next; @@ -24,9 +23,8 @@ public async Task Invoke(HttpContext httpContext) { if (_changeToken?.HasChanged ?? true) { - // Assumed to be atomic as we just update reference types. - _homeRoute = (await _siteService.GetSiteSettingsAsync()).HomeRoute; _changeToken = _siteService.ChangeToken; + _homeRoute = (await _siteService.GetSiteSettingsAsync()).HomeRoute; } httpContext.Features.Set(new HomeRouteFeature diff --git a/src/OrchardCore.Modules/OrchardCore.Settings/Services/SiteService.cs b/src/OrchardCore.Modules/OrchardCore.Settings/Services/SiteService.cs index 5130d4be3c8..55fc5090c9f 100644 --- a/src/OrchardCore.Modules/OrchardCore.Settings/Services/SiteService.cs +++ b/src/OrchardCore.Modules/OrchardCore.Settings/Services/SiteService.cs @@ -41,34 +41,29 @@ public async Task GetSiteSettingsAsync() if (!_memoryCache.TryGetValue(SiteCacheKey, out site)) { var session = GetSession(); + + var changeToken = ChangeToken; site = await session.Query().FirstOrDefaultAsync(); if (site == null) { - lock (_memoryCache) + site = new SiteSettings { - if (!_memoryCache.TryGetValue(SiteCacheKey, out site)) - { - site = new SiteSettings - { - SiteSalt = Guid.NewGuid().ToString("N"), - SiteName = "My Orchard Project Application", - PageSize = 10, - MaxPageSize = 100, - MaxPagedCount = 0, - TimeZoneId = _clock.GetSystemTimeZone().TimeZoneId, - }; + SiteSalt = Guid.NewGuid().ToString("N"), + SiteName = "My Orchard Project Application", + PageSize = 10, + MaxPageSize = 100, + MaxPagedCount = 0, + TimeZoneId = _clock.GetSystemTimeZone().TimeZoneId, + }; - session.Save(site); - _memoryCache.Set(SiteCacheKey, site); - _signal.SignalToken(SiteCacheKey); - } - } + session.Save(site); + await session.FlushAsync(); + _signal.SignalToken(SiteCacheKey); } else { - _memoryCache.Set(SiteCacheKey, site); - _signal.SignalToken(SiteCacheKey); + _memoryCache.Set(SiteCacheKey, site, changeToken); } } @@ -98,8 +93,7 @@ public async Task UpdateSiteSettingsAsync(ISite site) existing.CdnBaseUrl = site.CdnBaseUrl; session.Save(existing); - - _memoryCache.Set(SiteCacheKey, site); + await session.FlushAsync(); _signal.SignalToken(SiteCacheKey); return; diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentDefinitionCache.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentDefinitionCache.cs new file mode 100644 index 00000000000..7f5b786a113 --- /dev/null +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentDefinitionCache.cs @@ -0,0 +1,10 @@ +using Microsoft.Extensions.Primitives; + +namespace OrchardCore.ContentManagement.Metadata.Records +{ + public class ContentDefinitionCache + { + public ContentDefinitionRecord ContentDefinitionRecord { get; set; } + public IChangeToken ChangeToken { get; set; } + } +} diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentDefinitionRecord.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentDefinitionRecord.cs index 0427f2bb026..827f31fedfa 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentDefinitionRecord.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentDefinitionRecord.cs @@ -1,5 +1,5 @@ -using System.Collections.Generic; -using Newtonsoft.Json; +using System.Collections.Immutable; +using System.Linq; namespace OrchardCore.ContentManagement.Metadata.Records { @@ -7,13 +7,27 @@ public class ContentDefinitionRecord { public ContentDefinitionRecord() { - ContentTypeDefinitionRecords = new List(); - ContentPartDefinitionRecords = new List(); + ContentTypeDefinitionRecords = ImmutableArray.Create(); + ContentPartDefinitionRecords = ImmutableArray.Create(); } public int Id { get; set; } - public IList ContentTypeDefinitionRecords { get; set; } - public IList ContentPartDefinitionRecords { get; set; } + public ImmutableArray ContentTypeDefinitionRecords { get; set; } + public ImmutableArray ContentPartDefinitionRecords { get; set; } public int Serial { get; set; } + + public ContentDefinitionRecord Clone() + { + return new ContentDefinitionRecord() + { + ContentTypeDefinitionRecords = ContentTypeDefinitionRecords + .Select(type => type.Clone()) + .ToImmutableArray(), + + ContentPartDefinitionRecords = ContentPartDefinitionRecords + .Select(part => part.Clone()) + .ToImmutableArray() + }; + } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentFieldDefinitionRecord.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentFieldDefinitionRecord.cs index a8b742d9699..afdd6ed3f12 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentFieldDefinitionRecord.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentFieldDefinitionRecord.cs @@ -7,4 +7,4 @@ public class ContentFieldDefinitionRecord { public string Name { get; set; } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentPartDefinitionRecord.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentPartDefinitionRecord.cs index 7db0f75be06..834f497644f 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentPartDefinitionRecord.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentPartDefinitionRecord.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Immutable; using Newtonsoft.Json.Linq; namespace OrchardCore.ContentManagement.Metadata.Records @@ -7,7 +7,7 @@ public class ContentPartDefinitionRecord { public ContentPartDefinitionRecord() { - ContentPartFieldDefinitionRecords = new List(); + ContentPartFieldDefinitionRecords = ImmutableArray.Create(); Settings = new JObject(); } @@ -19,6 +19,16 @@ public ContentPartDefinitionRecord() /// public JObject Settings { get; set; } - public IList ContentPartFieldDefinitionRecords { get; set; } + public ImmutableArray ContentPartFieldDefinitionRecords { get; set; } + + public ContentPartDefinitionRecord Clone() + { + return new ContentPartDefinitionRecord() + { + Name = Name, + Settings = new JObject(Settings), + ContentPartFieldDefinitionRecords = ContentPartFieldDefinitionRecords + }; + } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentTypeDefinitionRecord.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentTypeDefinitionRecord.cs index bc553cf3801..33002933e13 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentTypeDefinitionRecord.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentTypeDefinitionRecord.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Immutable; using Newtonsoft.Json.Linq; namespace OrchardCore.ContentManagement.Metadata.Records @@ -7,13 +7,24 @@ public class ContentTypeDefinitionRecord { public ContentTypeDefinitionRecord() { - ContentTypePartDefinitionRecords = new List(); + ContentTypePartDefinitionRecords = ImmutableArray.Create(); } public string Name { get; set; } public string DisplayName { get; set; } public JObject Settings { get; set; } - public IList ContentTypePartDefinitionRecords { get; set; } + public ImmutableArray ContentTypePartDefinitionRecords { get; set; } + + public ContentTypeDefinitionRecord Clone() + { + return new ContentTypeDefinitionRecord() + { + Name = Name, + DisplayName = DisplayName, + Settings = new JObject(Settings), + ContentTypePartDefinitionRecords = ContentTypePartDefinitionRecords + }; + } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs index 5b096bb06df..38260d1f36b 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs @@ -2,11 +2,13 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Primitives; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentManagement.Metadata.Records; using OrchardCore.Environment.Cache; +using OrchardCore.Environment.Shell.Scope; namespace OrchardCore.ContentManagement { @@ -14,8 +16,8 @@ public class ContentDefinitionManager : IContentDefinitionManager { private const string TypeHashCacheKey = "ContentDefinitionManager:Serial"; - private ContentDefinitionRecord _contentDefinitionRecord; private readonly ISignal _signal; + private ContentDefinitionCache _cache; private readonly IContentDefinitionStore _contentDefinitionStore; private readonly ConcurrentDictionary _typeDefinitions; private readonly ConcurrentDictionary _partDefinitions; @@ -33,6 +35,8 @@ public ContentDefinitionManager( _partDefinitions = new ConcurrentDictionary(); } + private ContentDefinitionCache ScopedCache => ShellScope.Services.GetRequiredService(); + public async Task GetTypeDefinitionAsync(string name) { if (!_typeDefinitions.TryGetValue(name, out var typeDefinition)) @@ -41,7 +45,10 @@ public async Task GetTypeDefinitionAsync(string name) .ContentTypeDefinitionRecords .FirstOrDefault(type => type.Name == name)); - _typeDefinitions[name] = typeDefinition; + if (!ScopedCache.ChangeToken.HasChanged) + { + _typeDefinitions[name] = typeDefinition; + } } return typeDefinition; @@ -55,7 +62,10 @@ public async Task GetPartDefinitionAsync(string name) .ContentPartDefinitionRecords .FirstOrDefault(part => part.Name == name)); - _partDefinitions[name] = partDefinition; + if (!ScopedCache.ChangeToken.HasChanged) + { + _partDefinitions[name] = partDefinition; + } } return partDefinition; @@ -104,7 +114,8 @@ public async Task DeleteTypeDefinitionAsync(string name) // deletes the content type record associated if (record != null) { - (await GetContentDefinitionRecordAsync()).ContentTypeDefinitionRecords.Remove(record); + var definition = await GetContentDefinitionRecordAsync(); + definition.ContentTypeDefinitionRecords = definition.ContentTypeDefinitionRecords.Remove(record); await UpdateContentDefinitionRecordAsync(); } } @@ -124,7 +135,8 @@ public async Task DeletePartDefinitionAsync(string name) if (record != null) { - (await GetContentDefinitionRecordAsync()).ContentPartDefinitionRecords.Remove(record); + var definition = await GetContentDefinitionRecordAsync(); + definition.ContentPartDefinitionRecords = definition.ContentPartDefinitionRecords.Remove(record); await UpdateContentDefinitionRecordAsync(); } } @@ -134,8 +146,9 @@ private async Task AcquireAsync(ContentTypeDefiniti var result = (await GetContentDefinitionRecordAsync()).ContentTypeDefinitionRecords.FirstOrDefault(type => type.Name == contentTypeDefinition.Name); if (result == null) { + var definition = await GetContentDefinitionRecordAsync(); result = new ContentTypeDefinitionRecord { Name = contentTypeDefinition.Name, DisplayName = contentTypeDefinition.DisplayName }; - (await GetContentDefinitionRecordAsync()).ContentTypeDefinitionRecords.Add(result); + definition.ContentTypeDefinitionRecords = definition.ContentTypeDefinitionRecords.Add(result); } return result; } @@ -145,8 +158,9 @@ private async Task AcquireAsync(ContentPartDefiniti var result = (await GetContentDefinitionRecordAsync()).ContentPartDefinitionRecords.FirstOrDefault(part => part.Name == contentPartDefinition.Name); if (result == null) { + var definition = await GetContentDefinitionRecordAsync(); result = new ContentPartDefinitionRecord { Name = contentPartDefinition.Name, }; - (await GetContentDefinitionRecordAsync()).ContentPartDefinitionRecords.Add(result); + definition.ContentPartDefinitionRecords = definition.ContentPartDefinitionRecords.Add(result); } return result; } @@ -162,24 +176,29 @@ private void Apply(ContentTypeDefinition model, ContentTypeDefinitionRecord reco foreach (var remove in toRemove) { - record.ContentTypePartDefinitionRecords.Remove(remove); + record.ContentTypePartDefinitionRecords = record.ContentTypePartDefinitionRecords.Remove(remove); } foreach (var part in model.Parts) { var typePartRecord = record.ContentTypePartDefinitionRecords.FirstOrDefault(typePart => typePart.Name == part.Name); + + var newTypePartRecord = new ContentTypePartDefinitionRecord + { + PartName = typePartRecord?.PartName ?? part.PartDefinition.Name, + Name = typePartRecord?.Name ?? part.Name + }; + + Apply(part, newTypePartRecord); + if (typePartRecord == null) { - typePartRecord = new ContentTypePartDefinitionRecord - { - PartName = part.PartDefinition.Name, - Name = part.Name, - Settings = part.Settings - }; - - record.ContentTypePartDefinitionRecords.Add(typePartRecord); + record.ContentTypePartDefinitionRecords = record.ContentTypePartDefinitionRecords.Add(newTypePartRecord); + } + else + { + record.ContentTypePartDefinitionRecords = record.ContentTypePartDefinitionRecords.Replace(typePartRecord, newTypePartRecord); } - Apply(part, typePartRecord); } } @@ -198,23 +217,29 @@ private void Apply(ContentPartDefinition model, ContentPartDefinitionRecord reco foreach (var remove in toRemove) { - record.ContentPartFieldDefinitionRecords.Remove(remove); + record.ContentPartFieldDefinitionRecords = record.ContentPartFieldDefinitionRecords.Remove(remove); } foreach (var field in model.Fields) { - var fieldName = field.Name; - var partFieldRecord = record.ContentPartFieldDefinitionRecords.FirstOrDefault(r => r.Name == fieldName); + var partFieldRecord = record.ContentPartFieldDefinitionRecords.FirstOrDefault(r => r.Name == field.Name); + + var newPartFieldRecord = new ContentPartFieldDefinitionRecord + { + FieldName = partFieldRecord?.FieldName ?? field.FieldDefinition.Name, + Name = partFieldRecord?.Name ?? field.Name + }; + + Apply(field, newPartFieldRecord); + if (partFieldRecord == null) { - partFieldRecord = new ContentPartFieldDefinitionRecord - { - FieldName = field.FieldDefinition.Name, - Name = field.Name - }; - record.ContentPartFieldDefinitionRecords.Add(partFieldRecord); + record.ContentPartFieldDefinitionRecords = record.ContentPartFieldDefinitionRecords.Add(newPartFieldRecord); + } + else + { + record.ContentPartFieldDefinitionRecords = record.ContentPartFieldDefinitionRecords.Replace(partFieldRecord, newPartFieldRecord); } - Apply(field, partFieldRecord); } } @@ -284,19 +309,36 @@ public async Task GetTypesHashAsync() private async Task GetContentDefinitionRecordAsync() { - if (_contentDefinitionRecord != null) + var scopedCache = ScopedCache; + + if (scopedCache.ContentDefinitionRecord != null) { - return _contentDefinitionRecord; + return scopedCache.ContentDefinitionRecord; } - return _contentDefinitionRecord = await _contentDefinitionStore.LoadContentDefinitionAsync(); + if (_cache?.ChangeToken.HasChanged ?? true) + { + var changeToken = ChangeToken; + var record = await _contentDefinitionStore.LoadContentDefinitionAsync(); + + _cache = new ContentDefinitionCache() + { + ContentDefinitionRecord = record, + ChangeToken = changeToken, + }; + } + + scopedCache.ChangeToken = _cache.ChangeToken; + + return scopedCache.ContentDefinitionRecord = _cache.ContentDefinitionRecord.Clone(); } private async Task UpdateContentDefinitionRecordAsync() { - _contentDefinitionRecord.Serial++; - await _contentDefinitionStore.SaveContentDefinitionAsync(_contentDefinitionRecord); + var scopedRecord = ScopedCache.ContentDefinitionRecord; + scopedRecord.Serial++; + await _contentDefinitionStore.SaveContentDefinitionAsync(scopedRecord); _signal.SignalToken(TypeHashCacheKey); // Release cached values diff --git a/src/OrchardCore/OrchardCore.ContentManagement/DatabaseContentDefinitionStore.cs b/src/OrchardCore/OrchardCore.ContentManagement/DatabaseContentDefinitionStore.cs index 8cd17fd901b..8ab9e6adec1 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/DatabaseContentDefinitionStore.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/DatabaseContentDefinitionStore.cs @@ -29,9 +29,9 @@ public async Task LoadContentDefinitionAsync() public Task SaveContentDefinitionAsync(ContentDefinitionRecord contentDefinitionRecord) { - Session.Save(contentDefinitionRecord); - - return Task.CompletedTask; + var session = Session; + session.Save(contentDefinitionRecord); + return session.FlushAsync(); } private ISession Session => ShellScope.Services.GetRequiredService(); diff --git a/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs b/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs index fac7597788a..e2e75072a8f 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/FileContentDefinitionStore.cs @@ -13,23 +13,25 @@ namespace OrchardCore.ContentManagement public class FileContentDefinitionStore : IContentDefinitionStore { private readonly IOptions _shellOptions; - private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); + private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1); public FileContentDefinitionStore(IOptions shellOptions) { _shellOptions = shellOptions; } - public Task LoadContentDefinitionAsync() + public async Task LoadContentDefinitionAsync() { var fileName = GetFilename(); if (!File.Exists(fileName)) { - return Task.FromResult(new ContentDefinitionRecord()); + var contentDefinitionRecord = new ContentDefinitionRecord(); + await SaveContentDefinitionAsync(contentDefinitionRecord); + return contentDefinitionRecord; } - _lock.EnterReadLock(); + await _semaphore.WaitAsync(); try { @@ -37,21 +39,20 @@ public Task LoadContentDefinitionAsync() { using (var reader = new JsonTextReader(file)) { - // We don't use 'LoadAsync' because we use a thread-affine lock type. - return Task.FromResult(JObject.Load(reader).ToObject()); + return (await JObject.LoadAsync(reader)).ToObject(); } } } finally { - _lock.ExitReadLock(); + _semaphore.Release(); } } - public Task SaveContentDefinitionAsync(ContentDefinitionRecord contentDefinitionRecord) + public async Task SaveContentDefinitionAsync(ContentDefinitionRecord contentDefinitionRecord) { - _lock.EnterWriteLock(); + await _semaphore.WaitAsync(); try { @@ -59,23 +60,20 @@ public Task SaveContentDefinitionAsync(ContentDefinitionRecord contentDefinition { using (var writer = new JsonTextWriter(file)) { - // We don't use 'WriteToAsync' because we use a thread-affine lock type. - JObject.FromObject(contentDefinitionRecord).WriteTo(writer); + await JObject.FromObject(contentDefinitionRecord).WriteToAsync(writer); } } } finally { - _lock.ExitWriteLock(); + _semaphore.Release(); } - - return Task.CompletedTask; } private string GetFilename() => PathExtensions.Combine( - _shellOptions.Value.ShellsApplicationDataPath, - _shellOptions.Value.ShellsContainerName, - ShellScope.Context.Settings.Name, "ContentDefinition.json"); + _shellOptions.Value.ShellsApplicationDataPath, + _shellOptions.Value.ShellsContainerName, + ShellScope.Context.Settings.Name, "ContentDefinition.json"); } } diff --git a/src/OrchardCore/OrchardCore.ContentManagement/ServiceCollectionExtensions.cs b/src/OrchardCore/OrchardCore.ContentManagement/ServiceCollectionExtensions.cs index 134988058d7..faa9311b985 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/ServiceCollectionExtensions.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/ServiceCollectionExtensions.cs @@ -8,6 +8,7 @@ using OrchardCore.Data.Migration; using OrchardCore.Environment.Cache; using YesSql.Indexes; +using OrchardCore.ContentManagement.Metadata.Records; namespace OrchardCore.ContentManagement { @@ -15,6 +16,7 @@ public static class ServiceCollectionExtensions { public static IServiceCollection AddContentManagement(this IServiceCollection services) { + services.AddScoped(); services.AddScoped(); services.AddSingleton(); services.AddSingleton(); From 65b6dd140b068be4149f5f34d5ef8fadbdde3b43 Mon Sep 17 00:00:00 2001 From: jtkech Date: Sun, 4 Aug 2019 01:25:45 +0200 Subject: [PATCH 27/38] Little tweak --- .../ContentDefinitionManager.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs index 38260d1f36b..eddd741f105 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs @@ -316,21 +316,23 @@ private async Task GetContentDefinitionRecordAsync() return scopedCache.ContentDefinitionRecord; } - if (_cache?.ChangeToken.HasChanged ?? true) + var cache = _cache; + + if (cache?.ChangeToken.HasChanged ?? true) { var changeToken = ChangeToken; var record = await _contentDefinitionStore.LoadContentDefinitionAsync(); - _cache = new ContentDefinitionCache() + cache = _cache = new ContentDefinitionCache() { ContentDefinitionRecord = record, ChangeToken = changeToken, }; } - scopedCache.ChangeToken = _cache.ChangeToken; + scopedCache.ChangeToken = cache.ChangeToken; - return scopedCache.ContentDefinitionRecord = _cache.ContentDefinitionRecord.Clone(); + return scopedCache.ContentDefinitionRecord = cache.ContentDefinitionRecord.Clone(); } private async Task UpdateContentDefinitionRecordAsync() From 8d7f810ef2cadb3abfcb6144839a6bdad0a16e98 Mon Sep 17 00:00:00 2001 From: jtkech Date: Mon, 5 Aug 2019 02:09:03 +0200 Subject: [PATCH 28/38] Last tweaks --- .../OrchardCore.Settings/Services/SiteService.cs | 4 ++-- .../ContentDefinitionManager.cs | 12 ++++++------ .../DatabaseContentDefinitionStore.cs | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Settings/Services/SiteService.cs b/src/OrchardCore.Modules/OrchardCore.Settings/Services/SiteService.cs index 1c74428f83d..1c09468a025 100644 --- a/src/OrchardCore.Modules/OrchardCore.Settings/Services/SiteService.cs +++ b/src/OrchardCore.Modules/OrchardCore.Settings/Services/SiteService.cs @@ -58,7 +58,7 @@ public async Task GetSiteSettingsAsync() }; session.Save(site); - await session.FlushAsync(); + await session.CommitAsync(); _signal.SignalToken(SiteCacheKey); } else @@ -94,7 +94,7 @@ public async Task UpdateSiteSettingsAsync(ISite site) existing.AppendVersion = site.AppendVersion; session.Save(existing); - await session.FlushAsync(); + await session.CommitAsync(); _signal.SignalToken(SiteCacheKey); return; diff --git a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs index eddd741f105..ac4bc6033f7 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs @@ -39,7 +39,7 @@ public ContentDefinitionManager( public async Task GetTypeDefinitionAsync(string name) { - if (!_typeDefinitions.TryGetValue(name, out var typeDefinition)) + if (!_typeDefinitions.TryGetValue(name, out var typeDefinition) || (_cache?.ChangeToken.HasChanged ?? true)) { typeDefinition = await BuildAsync((await GetContentDefinitionRecordAsync()) .ContentTypeDefinitionRecords @@ -56,7 +56,7 @@ public async Task GetTypeDefinitionAsync(string name) public async Task GetPartDefinitionAsync(string name) { - if (!_partDefinitions.TryGetValue(name, out var partDefinition)) + if (!_partDefinitions.TryGetValue(name, out var partDefinition) || (_cache?.ChangeToken.HasChanged ?? true)) { partDefinition = Build((await GetContentDefinitionRecordAsync()) .ContentPartDefinitionRecords @@ -323,6 +323,10 @@ private async Task GetContentDefinitionRecordAsync() var changeToken = ChangeToken; var record = await _contentDefinitionStore.LoadContentDefinitionAsync(); + // Release cached values + _typeDefinitions.Clear(); + _partDefinitions.Clear(); + cache = _cache = new ContentDefinitionCache() { ContentDefinitionRecord = record, @@ -342,10 +346,6 @@ private async Task UpdateContentDefinitionRecordAsync() await _contentDefinitionStore.SaveContentDefinitionAsync(scopedRecord); _signal.SignalToken(TypeHashCacheKey); - - // Release cached values - _typeDefinitions.Clear(); - _partDefinitions.Clear(); } } } diff --git a/src/OrchardCore/OrchardCore.ContentManagement/DatabaseContentDefinitionStore.cs b/src/OrchardCore/OrchardCore.ContentManagement/DatabaseContentDefinitionStore.cs index 8ab9e6adec1..2dd3b4bcd61 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/DatabaseContentDefinitionStore.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/DatabaseContentDefinitionStore.cs @@ -31,7 +31,7 @@ public Task SaveContentDefinitionAsync(ContentDefinitionRecord contentDefinition { var session = Session; session.Save(contentDefinitionRecord); - return session.FlushAsync(); + return session.CommitAsync(); } private ISession Session => ShellScope.Services.GetRequiredService(); From d8bec61f4bd73e99294febebe9f07c769c319669 Mon Sep 17 00:00:00 2001 From: jtkech Date: Tue, 6 Aug 2019 03:25:50 +0200 Subject: [PATCH 29/38] my bad --- .../Metadata/Records/ContentDefinitionRecord.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentDefinitionRecord.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentDefinitionRecord.cs index 827f31fedfa..69650e10579 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentDefinitionRecord.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentDefinitionRecord.cs @@ -26,7 +26,9 @@ public ContentDefinitionRecord Clone() ContentPartDefinitionRecords = ContentPartDefinitionRecords .Select(part => part.Clone()) - .ToImmutableArray() + .ToImmutableArray(), + + Serial = Serial }; } } From 3412e1763dbf86dcc5d1618a7bab7739a8c35815 Mon Sep 17 00:00:00 2001 From: jtkech Date: Wed, 7 Aug 2019 05:36:43 +0200 Subject: [PATCH 30/38] Revert some changes and some tweaks --- .../OrchardCore.Settings/Services/SiteService.cs | 2 -- .../ContentDefinitionManager.cs | 8 +++++--- .../DatabaseContentDefinitionStore.cs | 5 ++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Settings/Services/SiteService.cs b/src/OrchardCore.Modules/OrchardCore.Settings/Services/SiteService.cs index 1c09468a025..ccc0ca12774 100644 --- a/src/OrchardCore.Modules/OrchardCore.Settings/Services/SiteService.cs +++ b/src/OrchardCore.Modules/OrchardCore.Settings/Services/SiteService.cs @@ -58,7 +58,6 @@ public async Task GetSiteSettingsAsync() }; session.Save(site); - await session.CommitAsync(); _signal.SignalToken(SiteCacheKey); } else @@ -94,7 +93,6 @@ public async Task UpdateSiteSettingsAsync(ISite site) existing.AppendVersion = site.AppendVersion; session.Save(existing); - await session.CommitAsync(); _signal.SignalToken(SiteCacheKey); return; diff --git a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs index ac4bc6033f7..ef9207ce951 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs @@ -327,15 +327,17 @@ private async Task GetContentDefinitionRecordAsync() _typeDefinitions.Clear(); _partDefinitions.Clear(); - cache = _cache = new ContentDefinitionCache() + _cache = new ContentDefinitionCache() { - ContentDefinitionRecord = record, ChangeToken = changeToken, + ContentDefinitionRecord = record.Clone() }; + + scopedCache.ChangeToken = changeToken; + return scopedCache.ContentDefinitionRecord = record; } scopedCache.ChangeToken = cache.ChangeToken; - return scopedCache.ContentDefinitionRecord = cache.ContentDefinitionRecord.Clone(); } diff --git a/src/OrchardCore/OrchardCore.ContentManagement/DatabaseContentDefinitionStore.cs b/src/OrchardCore/OrchardCore.ContentManagement/DatabaseContentDefinitionStore.cs index 2dd3b4bcd61..78c0c97855d 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/DatabaseContentDefinitionStore.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/DatabaseContentDefinitionStore.cs @@ -29,9 +29,8 @@ public async Task LoadContentDefinitionAsync() public Task SaveContentDefinitionAsync(ContentDefinitionRecord contentDefinitionRecord) { - var session = Session; - session.Save(contentDefinitionRecord); - return session.CommitAsync(); + Session.Save(contentDefinitionRecord); + return Task.CompletedTask; } private ISession Session => ShellScope.Services.GetRequiredService(); From 5960f745fef303f4585d0d0807e62f6242c67078 Mon Sep 17 00:00:00 2001 From: jtkech Date: Sun, 11 Aug 2019 04:33:41 +0200 Subject: [PATCH 31/38] Little updates for some syncing between the caching and async branches. --- .../OrchardCore.Abstractions/ISignal.cs | 19 ++++++++++++++- .../ContentDefinitionManager.cs | 23 +++++++++++-------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/OrchardCore/OrchardCore.Abstractions/ISignal.cs b/src/OrchardCore/OrchardCore.Abstractions/ISignal.cs index cbf181403aa..0bb31839c62 100644 --- a/src/OrchardCore/OrchardCore.Abstractions/ISignal.cs +++ b/src/OrchardCore/OrchardCore.Abstractions/ISignal.cs @@ -1,4 +1,6 @@ -using Microsoft.Extensions.Primitives; +using System.Threading.Tasks; +using Microsoft.Extensions.Primitives; +using OrchardCore.Environment.Shell.Scope; namespace OrchardCore.Environment.Cache { @@ -8,4 +10,19 @@ public interface ISignal void SignalToken(string key); } + + public static class SignalExtensions + { + /// + /// A 'SignalToken' deferred at the end of the shell scope. + /// + public static void DeferredSignalToken(this ISignal signal, string key) + { + ShellScope.RegisterBeforeDispose(scope => + { + signal.SignalToken(key); + return Task.CompletedTask; + }); + } + } } diff --git a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs index ef9207ce951..ef35952e96e 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs @@ -14,7 +14,7 @@ namespace OrchardCore.ContentManagement { public class ContentDefinitionManager : IContentDefinitionManager { - private const string TypeHashCacheKey = "ContentDefinitionManager:Serial"; + private const string CacheKey = nameof(ContentDefinitionManager); private readonly ISignal _signal; private ContentDefinitionCache _cache; @@ -22,7 +22,7 @@ public class ContentDefinitionManager : IContentDefinitionManager private readonly ConcurrentDictionary _typeDefinitions; private readonly ConcurrentDictionary _partDefinitions; - public IChangeToken ChangeToken => _signal.GetToken(TypeHashCacheKey); + public IChangeToken ChangeToken => _signal.GetToken(CacheKey); public ContentDefinitionManager( ISignal signal, @@ -39,12 +39,13 @@ public ContentDefinitionManager( public async Task GetTypeDefinitionAsync(string name) { - if (!_typeDefinitions.TryGetValue(name, out var typeDefinition) || (_cache?.ChangeToken.HasChanged ?? true)) + if (!_typeDefinitions.TryGetValue(name, out var typeDefinition)) { typeDefinition = await BuildAsync((await GetContentDefinitionRecordAsync()) .ContentTypeDefinitionRecords .FirstOrDefault(type => type.Name == name)); + // Don't cache a value based on a stale definition. if (!ScopedCache.ChangeToken.HasChanged) { _typeDefinitions[name] = typeDefinition; @@ -56,12 +57,13 @@ public async Task GetTypeDefinitionAsync(string name) public async Task GetPartDefinitionAsync(string name) { - if (!_partDefinitions.TryGetValue(name, out var partDefinition) || (_cache?.ChangeToken.HasChanged ?? true)) + if (!_partDefinitions.TryGetValue(name, out var partDefinition)) { partDefinition = Build((await GetContentDefinitionRecordAsync()) .ContentPartDefinitionRecords .FirstOrDefault(part => part.Name == name)); + // Don't cache a value based on a stale definition. if (!ScopedCache.ChangeToken.HasChanged) { _partDefinitions[name] = partDefinition; @@ -323,10 +325,6 @@ private async Task GetContentDefinitionRecordAsync() var changeToken = ChangeToken; var record = await _contentDefinitionStore.LoadContentDefinitionAsync(); - // Release cached values - _typeDefinitions.Clear(); - _partDefinitions.Clear(); - _cache = new ContentDefinitionCache() { ChangeToken = changeToken, @@ -347,7 +345,14 @@ private async Task UpdateContentDefinitionRecordAsync() scopedRecord.Serial++; await _contentDefinitionStore.SaveContentDefinitionAsync(scopedRecord); - _signal.SignalToken(TypeHashCacheKey); + + // Cache invalidation after committing the session. + _signal.DeferredSignalToken(CacheKey); + + // In case of multiple scoped mutations, types / parts may need to be + // rebuilt while in the same scope, so we release cached results here. + _typeDefinitions.Clear(); + _partDefinitions.Clear(); } } } From 3948aaabb26a7ed8b71e4ccdcdec1bb67babeb69 Mon Sep 17 00:00:00 2001 From: jtkech Date: Sun, 11 Aug 2019 07:00:42 +0200 Subject: [PATCH 32/38] Ensures that a deferred signal for a given key is sent once at the end of the scope. --- .../OrchardCore.Abstractions/ISignal.cs | 17 ----------- .../Shell/Scope/ShellScope.cs | 28 +++++++++++++++++-- .../ContentDefinitionManager.cs | 6 ++-- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/OrchardCore/OrchardCore.Abstractions/ISignal.cs b/src/OrchardCore/OrchardCore.Abstractions/ISignal.cs index 0bb31839c62..f2bdf606a38 100644 --- a/src/OrchardCore/OrchardCore.Abstractions/ISignal.cs +++ b/src/OrchardCore/OrchardCore.Abstractions/ISignal.cs @@ -1,6 +1,4 @@ -using System.Threading.Tasks; using Microsoft.Extensions.Primitives; -using OrchardCore.Environment.Shell.Scope; namespace OrchardCore.Environment.Cache { @@ -10,19 +8,4 @@ public interface ISignal void SignalToken(string key); } - - public static class SignalExtensions - { - /// - /// A 'SignalToken' deferred at the end of the shell scope. - /// - public static void DeferredSignalToken(this ISignal signal, string key) - { - ShellScope.RegisterBeforeDispose(scope => - { - signal.SignalToken(key); - return Task.CompletedTask; - }); - } - } } diff --git a/src/OrchardCore/OrchardCore.Abstractions/Shell/Scope/ShellScope.cs b/src/OrchardCore/OrchardCore.Abstractions/Shell/Scope/ShellScope.cs index 25157aa92d4..66b4c55d8c5 100644 --- a/src/OrchardCore/OrchardCore.Abstractions/Shell/Scope/ShellScope.cs +++ b/src/OrchardCore/OrchardCore.Abstractions/Shell/Scope/ShellScope.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using OrchardCore.Environment.Cache; using OrchardCore.Environment.Shell.Builders; using OrchardCore.Environment.Shell.Models; using OrchardCore.Modules; @@ -23,6 +24,7 @@ public class ShellScope : IServiceScope private readonly IServiceScope _serviceScope; private readonly List> _beforeDispose = new List>(); + private readonly HashSet _deferredSignals = new HashSet(); private readonly List> _deferredTasks = new List>(); private bool _disposeShellContext = false; @@ -177,15 +179,25 @@ public async Task ActivateShellAsync() private void BeforeDispose(Func callback) => _beforeDispose.Add(callback); /// - /// Adds a Task to be executed in a new scope at the end of 'BeforeDisposeAsync()'. + /// Adds a Signal (if not already adedd) to be sent just after 'BeforeDisposeAsync()'. + /// + private void DeferredSignal(string key) => _deferredSignals.Add(key); + + /// + /// Adds a Task to be executed in a new scope after 'BeforeDisposeAsync()'. /// private void DeferredTask(Func task) => _deferredTasks.Add(task); /// - /// Registers a delegate to be invoked just before the current shell scope will be disposed. + /// Registers a delegate to be invoked before the current shell scope will be disposed. /// public static void RegisterBeforeDispose(Func callback) => Current?.BeforeDispose(callback); + /// + /// Adds a Signal to be sent just before the current shell scope will be disposed. + /// + public static void AddDeferredSignal(string key) => Current?.DeferredSignal(key); + /// /// Adds a Task to be executed in a new scope once the current shell scope has been disposed. /// @@ -198,6 +210,16 @@ public async Task BeforeDisposeAsync() await callback(this); } + if (_deferredSignals.Any()) + { + var signal = ShellContext.ServiceProvider.GetRequiredService(); + + foreach (var key in _deferredSignals) + { + signal.SignalToken(key); + } + } + _disposeShellContext = await TerminateShellAsync(); var deferredTasks = _deferredTasks.ToArray(); @@ -310,4 +332,4 @@ public void Dispose() DisposeAsync().GetAwaiter().GetResult(); } } -} \ No newline at end of file +} diff --git a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs index ef35952e96e..1779717d699 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs @@ -347,10 +347,10 @@ private async Task UpdateContentDefinitionRecordAsync() await _contentDefinitionStore.SaveContentDefinitionAsync(scopedRecord); // Cache invalidation after committing the session. - _signal.DeferredSignalToken(CacheKey); + ShellScope.AddDeferredSignal(CacheKey); - // In case of multiple scoped mutations, types / parts may need to be - // rebuilt while in the same scope, so we release cached results here. + // In case of multiple scoped updates, types and parts may need to be rebuilt while + // in the same scope, so we don't defer the release of the cached building results. _typeDefinitions.Clear(); _partDefinitions.Clear(); } From f0d4d6691c9cf51c277a3f8c019edb9866574a2b Mon Sep 17 00:00:00 2001 From: jtkech Date: Sun, 11 Aug 2019 22:57:15 +0200 Subject: [PATCH 33/38] Re-introduces and uses the DeferredSignalToken extension helper. --- src/OrchardCore/OrchardCore.Abstractions/ISignal.cs | 12 ++++++++++++ .../Shell/Scope/ShellScope.cs | 4 ++-- .../ContentDefinitionManager.cs | 4 ++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/OrchardCore/OrchardCore.Abstractions/ISignal.cs b/src/OrchardCore/OrchardCore.Abstractions/ISignal.cs index f2bdf606a38..04ff3af8b03 100644 --- a/src/OrchardCore/OrchardCore.Abstractions/ISignal.cs +++ b/src/OrchardCore/OrchardCore.Abstractions/ISignal.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.Primitives; +using OrchardCore.Environment.Shell.Scope; namespace OrchardCore.Environment.Cache { @@ -8,4 +9,15 @@ public interface ISignal void SignalToken(string key); } + + public static class SignalExtensions + { + /// + /// Adds a Signal (if not already present) to be sent at the end of the shell scope. + /// + public static void DeferredSignalToken(this ISignal signal, string key) + { + ShellScope.AddDeferredSignal(key); + } + } } diff --git a/src/OrchardCore/OrchardCore.Abstractions/Shell/Scope/ShellScope.cs b/src/OrchardCore/OrchardCore.Abstractions/Shell/Scope/ShellScope.cs index 66b4c55d8c5..c3e59a2c6a7 100644 --- a/src/OrchardCore/OrchardCore.Abstractions/Shell/Scope/ShellScope.cs +++ b/src/OrchardCore/OrchardCore.Abstractions/Shell/Scope/ShellScope.cs @@ -179,7 +179,7 @@ public async Task ActivateShellAsync() private void BeforeDispose(Func callback) => _beforeDispose.Add(callback); /// - /// Adds a Signal (if not already adedd) to be sent just after 'BeforeDisposeAsync()'. + /// Adds a Signal (if not already present) to be sent just after 'BeforeDisposeAsync()'. /// private void DeferredSignal(string key) => _deferredSignals.Add(key); @@ -194,7 +194,7 @@ public async Task ActivateShellAsync() public static void RegisterBeforeDispose(Func callback) => Current?.BeforeDispose(callback); /// - /// Adds a Signal to be sent just before the current shell scope will be disposed. + /// Adds a Signal (if not already present) to be sent just before the current shell scope will be disposed. /// public static void AddDeferredSignal(string key) => Current?.DeferredSignal(key); diff --git a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs index 1779717d699..e502bc56f38 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement/ContentDefinitionManager.cs @@ -347,10 +347,10 @@ private async Task UpdateContentDefinitionRecordAsync() await _contentDefinitionStore.SaveContentDefinitionAsync(scopedRecord); // Cache invalidation after committing the session. - ShellScope.AddDeferredSignal(CacheKey); + _signal.DeferredSignalToken(CacheKey); // In case of multiple scoped updates, types and parts may need to be rebuilt while - // in the same scope, so we don't defer the release of the cached building results. + // in the same scope, so we don't defer the clearing of the related cached results. _typeDefinitions.Clear(); _partDefinitions.Clear(); } From da60023b7b3823d725ab5df0a59e46cd1ed0f557 Mon Sep 17 00:00:00 2001 From: jtkech Date: Wed, 14 Aug 2019 02:33:51 +0200 Subject: [PATCH 34/38] More async calls --- .../Services/LayerFilter.cs | 2 +- .../JavaScriptWorkflowScriptEvaluator.cs | 2 +- .../FileProviders/FileInfoExtensions.cs | 23 ++++++++++++ .../LiquidViewTemplate.cs | 8 ++-- .../ShapePlacementParsingStrategy.cs | 7 ++-- .../Scripting/IScriptingEngine.cs | 3 +- .../Scripting/IScriptingManager.cs | 3 +- .../Scripting/DefaultScriptingManager.cs | 9 +++-- .../Scripting/Files/FilesScriptEngine.cs | 12 +++--- .../Services/RecipeExecutor.cs | 25 ++++++------- .../Services/RecipeReader.cs | 8 ++-- .../VariablesMethodProvider.cs | 4 +- .../JavaScriptEngine.cs | 37 +++++++------------ 13 files changed, 78 insertions(+), 65 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Layers/Services/LayerFilter.cs b/src/OrchardCore.Modules/OrchardCore.Layers/Services/LayerFilter.cs index 4ba6c4efb96..7274d60011d 100644 --- a/src/OrchardCore.Modules/OrchardCore.Layers/Services/LayerFilter.cs +++ b/src/OrchardCore.Modules/OrchardCore.Layers/Services/LayerFilter.cs @@ -106,7 +106,7 @@ public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultE } else { - display = Convert.ToBoolean(engine.Evaluate(scope, layer.Rule)); + display = Convert.ToBoolean(await engine.EvaluateAsync(scope, layer.Rule)); } layersCache[layer.Rule] = display; diff --git a/src/OrchardCore.Modules/OrchardCore.Workflows/Scripting/JavaScriptWorkflowScriptEvaluator.cs b/src/OrchardCore.Modules/OrchardCore.Workflows/Scripting/JavaScriptWorkflowScriptEvaluator.cs index e5a9f300dec..1daeab0db99 100644 --- a/src/OrchardCore.Modules/OrchardCore.Workflows/Scripting/JavaScriptWorkflowScriptEvaluator.cs +++ b/src/OrchardCore.Modules/OrchardCore.Workflows/Scripting/JavaScriptWorkflowScriptEvaluator.cs @@ -46,7 +46,7 @@ public async Task EvaluateAsync(WorkflowExpression expression, Workflow await _workflowContextHandlers.InvokeAsync(x => x.EvaluatingScriptAsync(expressionContext), _logger); var methodProviders = scopedMethodProviders.Concat(expressionContext.ScopedMethodProviders); - return (T)_scriptingManager.Evaluate(directive, null, null, methodProviders); + return (T)await _scriptingManager.EvaluateAsync(directive, null, null, methodProviders); } } } diff --git a/src/OrchardCore/OrchardCore.Abstractions/Modules/FileProviders/FileInfoExtensions.cs b/src/OrchardCore/OrchardCore.Abstractions/Modules/FileProviders/FileInfoExtensions.cs index fa8ab4c9df0..eca97c0d427 100644 --- a/src/OrchardCore/OrchardCore.Abstractions/Modules/FileProviders/FileInfoExtensions.cs +++ b/src/OrchardCore/OrchardCore.Abstractions/Modules/FileProviders/FileInfoExtensions.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.IO; +using System.Threading.Tasks; using Microsoft.Extensions.FileProviders; namespace OrchardCore.Modules.FileProviders @@ -27,5 +28,27 @@ public static IEnumerable ReadAllLines(this IFileInfo fileInfo) return lines; } + + public static async Task> ReadAllLinesAsync(this IFileInfo fileInfo) + { + var lines = new List(); + + if (fileInfo?.Exists ?? false) + { + using (var reader = fileInfo.CreateReadStream()) + { + using (var sr = new StreamReader(reader)) + { + string line; + while ((line = await sr.ReadLineAsync()) != null) + { + lines.Add(line); + } + } + } + } + + return lines; + } } } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement.Liquid/LiquidViewTemplate.cs b/src/OrchardCore/OrchardCore.DisplayManagement.Liquid/LiquidViewTemplate.cs index b8bec6fe327..b4dd95f0eed 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement.Liquid/LiquidViewTemplate.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement.Liquid/LiquidViewTemplate.cs @@ -105,7 +105,7 @@ internal static async Task RenderAsync(RazorPage page) var fileProviderAccessor = services.GetRequiredService(); var isDevelopment = services.GetRequiredService().IsDevelopment(); - var template = Parse(path, fileProviderAccessor.FileProvider, Cache, isDevelopment); + var template = await ParseAsync(path, fileProviderAccessor.FileProvider, Cache, isDevelopment); var context = new TemplateContext(); await context.ContextualizeAsync(page, (object)page.Model); @@ -114,9 +114,9 @@ internal static async Task RenderAsync(RazorPage page) await template.RenderAsync(options, services, page.Output, HtmlEncoder.Default, context); } - public static LiquidViewTemplate Parse(string path, IFileProvider fileProvider, IMemoryCache cache, bool isDevelopment) + public static Task ParseAsync(string path, IFileProvider fileProvider, IMemoryCache cache, bool isDevelopment) { - return cache.GetOrCreate(path, entry => + return cache.GetOrCreateAsync(path, async entry => { entry.SetSlidingExpiration(TimeSpan.FromHours(1)); var fileInfo = fileProvider.GetFileInfo(path); @@ -130,7 +130,7 @@ public static LiquidViewTemplate Parse(string path, IFileProvider fileProvider, { using (var sr = new StreamReader(stream)) { - if (TryParse(sr.ReadToEnd(), out var template, out var errors)) + if (TryParse(await sr.ReadToEndAsync(), out var template, out var errors)) { return template; } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs index 095486fb2b6..706abc607eb 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs @@ -39,11 +39,11 @@ public async Task DiscoverAsync(ShapeTableBuilder builder) foreach (var featureDescriptor in enabledFeatures) { - ProcessFeatureDescriptor(builder, featureDescriptor); + await ProcessFeatureDescriptorAsync(builder, featureDescriptor); } } - private void ProcessFeatureDescriptor(ShapeTableBuilder builder, IFeatureInfo featureDescriptor) + private async Task ProcessFeatureDescriptorAsync(ShapeTableBuilder builder, IFeatureInfo featureDescriptor) { // TODO : (ngm) Replace with configuration Provider and read from that. // Dont use JSON Deserializer directly. @@ -58,8 +58,7 @@ private void ProcessFeatureDescriptor(ShapeTableBuilder builder, IFeatureInfo fe { using (var jtr = new JsonTextReader(reader)) { - JsonSerializer serializer = new JsonSerializer(); - var placementFile = serializer.Deserialize(jtr); + var placementFile = (await JObject.LoadAsync(jtr)).ToObject(); ProcessPlacementFile(builder, featureDescriptor, placementFile); } } diff --git a/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Scripting/IScriptingEngine.cs b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Scripting/IScriptingEngine.cs index dba5f819152..de2899c36df 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Scripting/IScriptingEngine.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Scripting/IScriptingEngine.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using Microsoft.Extensions.FileProviders; namespace OrchardCore.Scripting @@ -7,7 +8,7 @@ namespace OrchardCore.Scripting public interface IScriptingEngine { string Prefix { get; } - object Evaluate(IScriptingScope scope, string script); + Task EvaluateAsync(IScriptingScope scope, string script); IScriptingScope CreateScope(IEnumerable methods, IServiceProvider serviceProvider, IFileProvider fileProvider, string basePath); } } diff --git a/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Scripting/IScriptingManager.cs b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Scripting/IScriptingManager.cs index 7eecd8b00e5..f01c632e115 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Scripting/IScriptingManager.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Scripting/IScriptingManager.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading.Tasks; using Microsoft.Extensions.FileProviders; namespace OrchardCore.Scripting @@ -23,7 +24,7 @@ public interface IScriptingManager /// An optional instance. /// A list of method providers scoped to the script evaluation. /// The result of the script if any. - object Evaluate(string directive, IFileProvider fileProvider, string basePath, IEnumerable scopedMethodProviders); + Task EvaluateAsync(string directive, IFileProvider fileProvider, string basePath, IEnumerable scopedMethodProviders); /// /// The list of available method providers for this diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/DefaultScriptingManager.cs b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/DefaultScriptingManager.cs index 5397ef4d2b6..97b69e0cbbd 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/DefaultScriptingManager.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/DefaultScriptingManager.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Microsoft.Extensions.FileProviders; using OrchardCore.Environment.Shell.Scope; @@ -19,7 +20,7 @@ public DefaultScriptingManager( public IList GlobalMethodProviders { get; } - public object Evaluate(string directive, + public Task EvaluateAsync(string directive, IFileProvider fileProvider, string basePath, IEnumerable scopedMethodProviders) @@ -28,7 +29,7 @@ public object Evaluate(string directive, if (directiveIndex == -1 || directiveIndex >= directive.Length - 2) { - return directive; + return Task.FromResult((object)directive); } var prefix = directive.Substring(0, directiveIndex); @@ -37,12 +38,12 @@ public object Evaluate(string directive, var engine = GetScriptingEngine(prefix); if (engine == null) { - return directive; + return Task.FromResult((object)directive); } var methodProviders = scopedMethodProviders != null ? GlobalMethodProviders.Concat(scopedMethodProviders) : GlobalMethodProviders; var scope = engine.CreateScope(methodProviders.SelectMany(x => x.GetMethods()), ShellScope.Services, fileProvider, basePath); - return engine.Evaluate(scope, script); + return engine.EvaluateAsync(scope, script); } public IScriptingEngine GetScriptingEngine(string prefix) diff --git a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs index d8710014dfa..c19bad16508 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs @@ -1,13 +1,11 @@ using System; using System.Collections.Generic; using System.IO; +using System.Threading.Tasks; using Microsoft.Extensions.FileProviders; namespace OrchardCore.Scripting.Files { - /// - /// Provides - /// public class FilesScriptEngine : IScriptingEngine { public string Prefix => "file"; @@ -17,7 +15,7 @@ public IScriptingScope CreateScope(IEnumerable methods, IServicePr return new FilesScriptScope(fileProvider, basePath); } - public object Evaluate(IScriptingScope scope, string script) + public async Task EvaluateAsync(IScriptingScope scope, string script) { if (scope == null) { @@ -42,11 +40,11 @@ public object Evaluate(IScriptingScope scope, string script) { using (var streamReader = new StreamReader(fileStream)) { - return streamReader.ReadToEnd(); + return await streamReader.ReadToEndAsync(); } } } - else if(script.StartsWith("base64('") && script.EndsWith("')")) + else if (script.StartsWith("base64('") && script.EndsWith("')")) { var filePath = script.Substring(8, script.Length - 10); var fileInfo = fileScope.FileProvider.GetRelativeFileInfo(fileScope.BasePath, filePath); @@ -59,7 +57,7 @@ public object Evaluate(IScriptingScope scope, string script) { using (var ms = new MemoryStream()) { - fileStream.CopyTo(ms); + await fileStream.CopyToAsync(ms); return Convert.ToBase64String(ms.ToArray()); } } diff --git a/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeExecutor.cs b/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeExecutor.cs index d7d3976856e..8bf85caf436 100644 --- a/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeExecutor.cs +++ b/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeExecutor.cs @@ -4,7 +4,6 @@ using System.Runtime.ExceptionServices; using System.Threading; using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; @@ -61,23 +60,23 @@ public async Task ExecuteAsync(string executionId, RecipeDescriptor reci using (var reader = new JsonTextReader(file)) { // Go to Steps, then iterate. - while (reader.Read()) + while (await reader.ReadAsync()) { if (reader.Path == "variables") { - reader.Read(); + await reader.ReadAsync(); - var variables = JObject.Load(reader); + var variables = await JObject.LoadAsync(reader); _variablesMethodProvider = new VariablesMethodProvider(variables); } if (reader.Path == "steps" && reader.TokenType == JsonToken.StartArray) { - while (reader.Read() && reader.Depth > 1) + while (await reader.ReadAsync() && reader.Depth > 1) { if (reader.Depth == 2) { - var child = JObject.Load(reader); + var child = await JObject.LoadAsync(reader); var recipeStep = new RecipeExecutionContext { @@ -163,7 +162,7 @@ await shellScope.UsingAsync(async scope => scriptingManager.GlobalMethodProviders.Add(_environmentMethodProvider); // Substitutes the script elements by their actual values - EvaluateScriptNodes(recipeStep, scriptingManager); + await EvaluateScriptNodesAsync(recipeStep, scriptingManager); foreach (var recipeStepHandler in recipeStepHandlers) { @@ -189,7 +188,7 @@ await shellScope.UsingAsync(async scope => /// /// Traverse all the nodes of the recipe steps and replaces their value if they are scripted. /// - private void EvaluateScriptNodes(RecipeExecutionContext context, IScriptingManager scriptingManager) + private Task EvaluateScriptNodesAsync(RecipeExecutionContext context, IScriptingManager scriptingManager) { if (_variablesMethodProvider != null) { @@ -197,13 +196,13 @@ private void EvaluateScriptNodes(RecipeExecutionContext context, IScriptingManag scriptingManager.GlobalMethodProviders.Add(_variablesMethodProvider); } - EvaluateJsonTree(scriptingManager, context, context.Step); + return EvaluateJsonTreeAsync(scriptingManager, context, context.Step); } /// /// Traverse all the nodes of the json document and replaces their value if they are scripted. /// - private void EvaluateJsonTree(IScriptingManager scriptingManager, RecipeExecutionContext context, JToken node) + private async Task EvaluateJsonTreeAsync(IScriptingManager scriptingManager, RecipeExecutionContext context, JToken node) { switch (node.Type) { @@ -211,13 +210,13 @@ private void EvaluateJsonTree(IScriptingManager scriptingManager, RecipeExecutio var array = (JArray)node; for (var i = 0; i < array.Count; i++) { - EvaluateJsonTree(scriptingManager, context, array[i]); + await EvaluateJsonTreeAsync(scriptingManager, context, array[i]); } break; case JTokenType.Object: foreach (var property in (JObject)node) { - EvaluateJsonTree(scriptingManager, context, property.Value); + await EvaluateJsonTreeAsync(scriptingManager, context, property.Value); } break; @@ -229,7 +228,7 @@ private void EvaluateJsonTree(IScriptingManager scriptingManager, RecipeExecutio while (value.StartsWith("[") && value.EndsWith("]")) { value = value.Trim('[', ']'); - value = (scriptingManager.Evaluate(value, context.RecipeDescriptor.FileProvider, context.RecipeDescriptor.BasePath, null) ?? "").ToString(); + value = (await scriptingManager.EvaluateAsync(value, context.RecipeDescriptor.FileProvider, context.RecipeDescriptor.BasePath, null) ?? "").ToString(); ((JValue)node).Value = value; } break; diff --git a/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeReader.cs b/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeReader.cs index 79ac58e35c3..85211e16fd4 100644 --- a/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeReader.cs +++ b/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeReader.cs @@ -2,13 +2,14 @@ using System.Threading.Tasks; using Microsoft.Extensions.FileProviders; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using OrchardCore.Recipes.Models; namespace OrchardCore.Recipes.Services { public class RecipeReader : IRecipeReader { - public Task GetRecipeDescriptor(string recipeBasePath, IFileInfo recipeFileInfo, IFileProvider recipeFileProvider) + public async Task GetRecipeDescriptor(string recipeBasePath, IFileInfo recipeFileInfo, IFileProvider recipeFileProvider) { // TODO: Try to optimize by only reading the required metadata instead of the whole file @@ -18,14 +19,13 @@ public Task GetRecipeDescriptor(string recipeBasePath, IFileIn { using (var jsonReader = new JsonTextReader(reader)) { - var serializer = new JsonSerializer(); - var recipeDescriptor = serializer.Deserialize(jsonReader); + var recipeDescriptor = (await JObject.LoadAsync(jsonReader)).ToObject(); recipeDescriptor.FileProvider = recipeFileProvider; recipeDescriptor.BasePath = recipeBasePath; recipeDescriptor.RecipeFileInfo = recipeFileInfo; - return Task.FromResult(recipeDescriptor); + return recipeDescriptor; } } } diff --git a/src/OrchardCore/OrchardCore.Recipes.Core/VariablesMethodProvider.cs b/src/OrchardCore/OrchardCore.Recipes.Core/VariablesMethodProvider.cs index 6cafcf5ef91..2c618665f8c 100644 --- a/src/OrchardCore/OrchardCore.Recipes.Core/VariablesMethodProvider.cs +++ b/src/OrchardCore/OrchardCore.Recipes.Core/VariablesMethodProvider.cs @@ -14,7 +14,7 @@ public VariablesMethodProvider(JObject variables) _globalMethod = new GlobalMethod { Name = "variables", - Method = serviceprovider => (Func) (name => + Method = serviceprovider => (Func)(name => { var value = variables[name].Value(); @@ -22,7 +22,7 @@ public VariablesMethodProvider(JObject variables) while (value.StartsWith("[") && value.EndsWith("]")) { value = value.Trim('[', ']'); - value = (ScriptingManager.Evaluate(value, null, null, null) ?? "").ToString(); + value = (ScriptingManager.EvaluateAsync(value, null, null, null).GetAwaiter().GetResult() ?? "").ToString(); variables[name] = new JValue(value); } diff --git a/src/OrchardCore/OrchardCore.Scripting.JavaScript/JavaScriptEngine.cs b/src/OrchardCore/OrchardCore.Scripting.JavaScript/JavaScriptEngine.cs index 37360f93e6b..583c8c0bbd5 100644 --- a/src/OrchardCore/OrchardCore.Scripting.JavaScript/JavaScriptEngine.cs +++ b/src/OrchardCore/OrchardCore.Scripting.JavaScript/JavaScriptEngine.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using Esprima; using Jint; using Microsoft.Extensions.Caching.Memory; @@ -9,11 +10,11 @@ namespace OrchardCore.Scripting.JavaScript { public class JavaScriptEngine : IScriptingEngine { - private readonly IMemoryCache _memoryCache; + private readonly IMemoryCache _memoryCache; - public JavaScriptEngine(IMemoryCache memoryCache) + public JavaScriptEngine(IMemoryCache memoryCache) { - _memoryCache = memoryCache; + _memoryCache = memoryCache; } public string Prefix => "js"; @@ -21,8 +22,8 @@ public JavaScriptEngine(IMemoryCache memoryCache) public IScriptingScope CreateScope(IEnumerable methods, IServiceProvider serviceProvider, IFileProvider fileProvider, string basePath) { var engine = new Engine(); - - foreach(var method in methods) + + foreach (var method in methods) { engine.SetValue(method.Name, method.Method(serviceProvider)); } @@ -30,7 +31,7 @@ public IScriptingScope CreateScope(IEnumerable methods, IServicePr return new JavaScriptScope(engine, serviceProvider); } - public object Evaluate(IScriptingScope scope, string script) + public Task EvaluateAsync(IScriptingScope scope, string script) { if (scope == null) { @@ -44,25 +45,15 @@ public object Evaluate(IScriptingScope scope, string script) throw new ArgumentException($"Expected a scope of type {nameof(JavaScriptScope)}", nameof(scope)); } - var parsedAst = _memoryCache.GetOrCreate(script, entry => - { - var parser = new JavaScriptParser(script); - return parser.ParseProgram(); - }); - - var result = jsScope.Engine.Execute(parsedAst).GetCompletionValue()?.ToObject(); + var parsedAst = _memoryCache.GetOrCreate(script, entry => + { + var parser = new JavaScriptParser(script); + return parser.ParseProgram(); + }); - return result; - } - } + var result = jsScope.Engine.Execute(parsedAst).GetCompletionValue()?.ToObject(); - public class MethodProxy - { - public IList Arguments { get; set; } - public Func, object> Callback { get; set; } - public object Invoke() - { - return Callback(null, Arguments); + return Task.FromResult(result); } } } From 1d35be3ed9905d09ca58867eff860e43f02930fe Mon Sep 17 00:00:00 2001 From: jtkech Date: Wed, 21 Aug 2019 00:05:43 +0200 Subject: [PATCH 35/38] Revert back "ContentDefinitionManager" to its non async version. --- .../Drivers/AliasPartDisplayDriver.cs | 24 +- .../Handlers/AliasPartHandler.cs | 6 +- .../OrchardCore.Alias/Migrations.cs | 11 +- .../Drivers/AutoroutePartDisplay.cs | 8 +- .../Handlers/AutoroutePartHandler.cs | 6 +- .../OrchardCore.Autoroute/Migrations.cs | 7 +- .../Controllers/ContentPickerController.cs | 4 +- ...ntentLocalizationPartHandlerCoordinator.cs | 4 +- .../Records/Migrations.cs | 5 +- .../Controllers/AdminController.cs | 94 +++---- .../DefaultContentDefinitionDisplayManager.cs | 8 +- .../RecipeSteps/ContentDefinitionStep.cs | 24 +- .../Services/ContentDefinitionService.cs | 128 +++++---- .../Services/DefaultStereotypesProvider.cs | 9 +- .../Services/IContentDefinitionService.cs | 45 ++- .../Services/IStereotypesProvider.cs | 5 +- .../Services/StereotypeService.cs | 15 +- .../SelectContentTypesViewComponent.cs | 9 +- .../ViewModels/SelectContentTypesViewModel.cs | 11 +- .../Views/Admin/Edit.cshtml | 16 +- ...efinitionDeploymentStep.Fields.Edit.cshtml | 5 +- ...nitionDeploymentStep.Fields.Summary.cshtml | 8 +- .../OrchardCore.Contents/AdminMenu.cs | 4 +- .../AdminNodes/ContentTypesAdminNodeDriver.cs | 13 +- .../ContentTypesAdminNodeNavigationBuilder.cs | 15 +- .../Controllers/AdminController.cs | 30 +- .../Drivers/ContentsDriver.cs | 9 +- .../Drivers/DateEditorDriver.cs | 20 +- .../Drivers/OwnerEditorDriver.cs | 10 +- .../Indexing/ContentItemIndexCoordinator.cs | 4 +- .../OrchardCore.Contents/Migrations.cs | 9 +- .../Security/ContentTypePermissions.cs | 20 +- .../TagHelpers/ContentLinkTagHelper.cs | 2 +- .../Views/Admin/Create.cshtml | 2 +- .../Views/Admin/Edit.cshtml | 2 +- .../ContentDeploymentStep.Fields.Edit.cshtml | 2 +- ...ontentDeploymentStep.Fields.Summary.cshtml | 2 +- ...ntTypesAdminNode.Fields.TreeSummary.cshtml | 2 +- .../Drivers/ContentEventDisplayDriver.cs | 10 +- .../Drivers/CreateContentTaskDisplay.cs | 6 +- .../OrchardCore.CustomSettings/AdminMenu.cs | 8 +- .../CustomSettingsDeploymentSource.cs | 6 +- .../CustomSettingsDeploymentStepDriver.cs | 6 +- .../Drivers/CustomSettingsDisplayDriver.cs | 6 +- .../OrchardCore.CustomSettings/Permissions.cs | 11 +- .../Recipes/CustomSettingsStep.cs | 4 +- .../Services/CustomSettingsService.cs | 60 ++-- .../OrchardCore.Demo/Migrations.cs | 7 +- .../FacebookPluginPartDisplayDriver.cs | 30 +- .../Widgets/Migrations.cs | 9 +- .../Drivers/BagPartDisplay.cs | 16 +- .../OrchardCore.Flows/Migrations.cs | 13 +- .../Settings/BagPartSettingsDisplayDriver.cs | 8 +- .../Views/FlowPart.Edit.cshtml | 2 +- .../Views/Widget-Bag.Edit.cshtml | 2 +- .../Views/Widget-Flow.Edit.cshtml | 4 +- .../OrchardCore.Forms/Migrations.cs | 41 ++- .../Drivers/HtmlBodyPartDisplay.cs | 2 +- .../Handlers/HtmlBodyPartHandler.cs | 5 +- .../OrchardCore.Html/Migrations.cs | 14 +- .../Views/Admin/Index.cshtml | 2 +- .../OrchardCore.Liquid/Migrations.cs | 9 +- .../AdminNodes/ListsAdminNodeDriver.cs | 8 +- .../ListsAdminNodeNavigationBuilder.cs | 2 +- .../Drivers/ListPartDisplayDriver.cs | 24 +- .../OrchardCore.Lists/Migrations.cs | 9 +- .../RemotePublishing/MetaWeblogHandler.cs | 24 +- .../Services/ListPartContentAdminFilter.cs | 4 +- .../Settings/ListPartSettingsDisplayDriver.cs | 8 +- .../ListsAdminNode.Fields.TreeSummary.cshtml | 2 +- .../Drivers/MarkdownBodyPartDisplay.cs | 8 +- .../Handlers/MarkdownBodyPartHandler.cs | 5 +- .../OrchardCore.Markdown/Migrations.cs | 9 +- .../Controllers/AdminController.cs | 8 +- .../Views/Admin/Create.cshtml | 2 +- .../OrchardCore.Menu/Views/Admin/Edit.cshtml | 2 +- .../Views/MenuPart.Edit.cshtml | 2 +- .../OrchardCore.ReCaptcha/Forms/Migrations.cs | 13 +- .../Services/SiteService.cs | 34 ++- .../Controllers/AdminController.cs | 6 +- .../Indexing/TaxonomyIndex.cs | 4 +- .../OrchardCore.Taxonomies/Migrations.cs | 5 +- .../Views/Admin/Create.cshtml | 2 +- .../Views/Admin/Edit.cshtml | 2 +- .../Views/TaxonomyPart.Edit.cshtml | 4 +- .../OrchardCore.Title/Migrations.cs | 14 +- .../Drivers/WidgetsListPartDisplay.cs | 6 +- .../OrchardCore.Widgets/Migrations.cs | 9 +- .../Views/Widget-List.Edit.cshtml | 4 +- .../Views/WidgetsListPart.Edit.cshtml | 2 +- .../OrchardCore.Abstractions/ISignal.cs | 12 - .../FileProviders/FileInfoExtensions.cs | 23 -- .../Shell/Scope/ShellScope.cs | 28 +- .../IContentDefinitionManager.cs | 34 +-- .../Records/ContentDefinitionCache.cs | 10 - .../Records/ContentDefinitionRecord.cs | 30 +- .../Records/ContentFieldDefinitionRecord.cs | 2 +- .../Records/ContentPartDefinitionRecord.cs | 18 +- .../ContentPartFieldDefinitionRecord.cs | 2 +- .../Records/ContentTypeDefinitionRecord.cs | 19 +- .../ContentItemDisplayCoordinator.cs | 6 +- .../ContentDisplayManager.cs | 6 +- .../Queries/ContentTypeQuery.cs | 7 +- .../ContentDefinitionManager.cs | 260 +++++++----------- .../DatabaseContentDefinitionStore.cs | 14 +- .../DefaultContentManager.cs | 4 +- .../FileContentDefinitionStore.cs | 67 ++--- .../Handlers/ContentPartHandlerCoordinator.cs | 44 +-- .../ServiceCollectionExtensions.cs | 8 +- .../IDataMigration.cs | 2 +- .../Migration/AutomaticDataMigrations.cs | 2 +- .../IMediaFactorySelector.cs | 5 +- .../IMediaService.cs | 2 +- .../ImageFactory.cs | 6 +- .../MediaService.cs | 18 +- 115 files changed, 751 insertions(+), 979 deletions(-) delete mode 100644 src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Records/ContentDefinitionCache.cs diff --git a/src/OrchardCore.Modules/OrchardCore.Alias/Drivers/AliasPartDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.Alias/Drivers/AliasPartDisplayDriver.cs index d39f3421aa5..bf3d6d413de 100644 --- a/src/OrchardCore.Modules/OrchardCore.Alias/Drivers/AliasPartDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Alias/Drivers/AliasPartDisplayDriver.cs @@ -1,16 +1,16 @@ using System.Linq; using System.Threading.Tasks; -using Microsoft.Extensions.Localization; -using OrchardCore.Alias.Indexes; -using OrchardCore.Alias.Models; -using OrchardCore.Alias.Settings; -using OrchardCore.Alias.ViewModels; using OrchardCore.ContentManagement.Display.ContentDisplay; using OrchardCore.ContentManagement.Metadata; using OrchardCore.DisplayManagement.ModelBinding; using OrchardCore.DisplayManagement.Views; -using OrchardCore.Mvc.ModelBinding; +using OrchardCore.Alias.Models; +using OrchardCore.Alias.Settings; +using OrchardCore.Alias.ViewModels; using YesSql; +using OrchardCore.Alias.Indexes; +using Microsoft.Extensions.Localization; +using OrchardCore.Mvc.ModelBinding; namespace OrchardCore.Alias.Drivers { @@ -32,12 +32,12 @@ public AliasPartDisplayDriver( public override IDisplayResult Edit(AliasPart aliasPart) { - return Initialize("AliasPart_Edit", m => BuildViewModelAsync(m, aliasPart)); + return Initialize("AliasPart_Edit", m => BuildViewModel(m, aliasPart)); } public override async Task UpdateAsync(AliasPart model, IUpdateModel updater) { - var settings = await GetAliasPartSettingsAsync(model); + var settings = GetAliasPartSettings(model); await updater.TryUpdateModelAsync(model, Prefix, t => t.Alias); @@ -46,18 +46,18 @@ public override async Task UpdateAsync(AliasPart model, IUpdateM return Edit(model); } - public async Task GetAliasPartSettingsAsync(AliasPart part) + public AliasPartSettings GetAliasPartSettings(AliasPart part) { - var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType); + var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(p => p.PartDefinition.Name == nameof(AliasPart)); var settings = contentTypePartDefinition.GetSettings(); return settings; } - private async Task BuildViewModelAsync(AliasPartViewModel model, AliasPart part) + private void BuildViewModel(AliasPartViewModel model, AliasPart part) { - var settings = await GetAliasPartSettingsAsync(part); + var settings = GetAliasPartSettings(part); model.Alias = part.Alias; model.AliasPart = part; diff --git a/src/OrchardCore.Modules/OrchardCore.Alias/Handlers/AliasPartHandler.cs b/src/OrchardCore.Modules/OrchardCore.Alias/Handlers/AliasPartHandler.cs index 30424109f8b..676f87941c6 100644 --- a/src/OrchardCore.Modules/OrchardCore.Alias/Handlers/AliasPartHandler.cs +++ b/src/OrchardCore.Modules/OrchardCore.Alias/Handlers/AliasPartHandler.cs @@ -45,7 +45,7 @@ public async override Task UpdatedAsync(UpdateContentContext context, AliasPart return; } - var pattern = await GetPatternAsync(part); + var pattern = GetPattern(part); if (!String.IsNullOrEmpty(pattern)) { @@ -60,9 +60,9 @@ public async override Task UpdatedAsync(UpdateContentContext context, AliasPart /// /// Get the pattern from the AutoroutePartSettings property for its type /// - private async Task GetPatternAsync(AliasPart part) + private string GetPattern(AliasPart part) { - var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType); + var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => String.Equals(x.PartDefinition.Name, "AliasPart", StringComparison.Ordinal)); var pattern = contentTypePartDefinition.GetSettings().Pattern; diff --git a/src/OrchardCore.Modules/OrchardCore.Alias/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Alias/Migrations.cs index bf86bef48d3..97f25f826d5 100644 --- a/src/OrchardCore.Modules/OrchardCore.Alias/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Alias/Migrations.cs @@ -1,9 +1,8 @@ -using System.Threading.Tasks; -using OrchardCore.Alias.Indexes; -using OrchardCore.Alias.Models; -using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Settings; +using OrchardCore.ContentManagement.Metadata; using OrchardCore.Data.Migration; +using OrchardCore.Alias.Indexes; +using OrchardCore.Alias.Models; namespace OrchardCore.Alias { @@ -16,9 +15,9 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public async Task CreateAsync() + public int Create() { - await _contentDefinitionManager.AlterPartDefinitionAsync(nameof(AliasPart), builder => builder + _contentDefinitionManager.AlterPartDefinition(nameof(AliasPart), builder => builder .Attachable() .WithDescription("Provides a way to define custom aliases for content items.")); diff --git a/src/OrchardCore.Modules/OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs b/src/OrchardCore.Modules/OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs index f456b78c8e7..5b27096e147 100644 --- a/src/OrchardCore.Modules/OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs +++ b/src/OrchardCore.Modules/OrchardCore.Autoroute/Drivers/AutoroutePartDisplay.cs @@ -68,13 +68,13 @@ public override IDisplayResult Edit(AutoroutePart autoroutePart) model.IsHomepage = true; } - model.Settings = await GetSettingsAsync(autoroutePart); + model.Settings = GetSettings(autoroutePart); }); } - private async Task GetSettingsAsync(AutoroutePart autoroutePart) + private AutoroutePartSettings GetSettings(AutoroutePart autoroutePart) { - var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(autoroutePart.ContentItem.ContentType); + var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(autoroutePart.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => String.Equals(x.PartDefinition.Name, nameof(AutoroutePart), StringComparison.Ordinal)); return contentTypePartDefinition.Settings.ToObject(); } @@ -85,7 +85,7 @@ public override async Task UpdateAsync(AutoroutePart model, IUpd await updater.TryUpdateModelAsync(viewModel, Prefix, t => t.Path, t => t.UpdatePath); - var settings = await GetSettingsAsync(model); + var settings = GetSettings(model); if (settings.AllowCustomPath) { diff --git a/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs b/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs index 2e927ec6ce9..f70009bacf9 100644 --- a/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs +++ b/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs @@ -114,7 +114,7 @@ public override async Task UpdatedAsync(UpdateContentContext context, AutorouteP return; } - var pattern = await GetPatternAsync(part); + var pattern = GetPattern(part); if (!String.IsNullOrEmpty(pattern)) { @@ -149,9 +149,9 @@ private Task RemoveTagAsync(AutoroutePart part) /// /// Get the pattern from the AutoroutePartSettings property for its type /// - private async Task GetPatternAsync(AutoroutePart part) + private string GetPattern(AutoroutePart part) { - var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType); + var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => String.Equals(x.PartDefinition.Name, "AutoroutePart", StringComparison.Ordinal)); var pattern = contentTypePartDefinition.Settings.ToObject().Pattern; diff --git a/src/OrchardCore.Modules/OrchardCore.Autoroute/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Autoroute/Migrations.cs index 6e0821e8e8a..f242cdba118 100644 --- a/src/OrchardCore.Modules/OrchardCore.Autoroute/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Autoroute/Migrations.cs @@ -1,4 +1,3 @@ -using System.Threading.Tasks; using OrchardCore.Autoroute.Drivers; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Settings; @@ -16,9 +15,9 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public async Task CreateAsync() + public int Create() { - await _contentDefinitionManager.AlterPartDefinitionAsync("AutoroutePart", builder => builder + _contentDefinitionManager.AlterPartDefinition("AutoroutePart", builder => builder .Attachable() .WithDescription("Provides a custom url for your content item.")); @@ -35,4 +34,4 @@ await _contentDefinitionManager.AlterPartDefinitionAsync("AutoroutePart", builde return 1; } } -} +} \ No newline at end of file diff --git a/src/OrchardCore.Modules/OrchardCore.ContentFields/Controllers/ContentPickerController.cs b/src/OrchardCore.Modules/OrchardCore.ContentFields/Controllers/ContentPickerController.cs index fcfed974f61..8b4d89dfad3 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentFields/Controllers/ContentPickerController.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentFields/Controllers/ContentPickerController.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; using System.Linq; +using OrchardCore.Admin; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; -using OrchardCore.Admin; using OrchardCore.ContentFields.Settings; using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Metadata; @@ -32,7 +32,7 @@ public async Task List(string part, string field, string query) return BadRequest("Part and field are required parameters"); } - var partFieldDefinition = (await _contentDefinitionManager.GetPartDefinitionAsync(part))?.Fields + var partFieldDefinition = _contentDefinitionManager.GetPartDefinition(part)?.Fields .FirstOrDefault(f => f.Name == field); var fieldSettings = partFieldDefinition?.Settings.ToObject(); diff --git a/src/OrchardCore.Modules/OrchardCore.ContentLocalization/Handlers/ContentLocalizationPartHandlerCoordinator.cs b/src/OrchardCore.Modules/OrchardCore.ContentLocalization/Handlers/ContentLocalizationPartHandlerCoordinator.cs index a66933d52c5..0a2cdf0808e 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentLocalization/Handlers/ContentLocalizationPartHandlerCoordinator.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentLocalization/Handlers/ContentLocalizationPartHandlerCoordinator.cs @@ -33,7 +33,7 @@ ILogger logger public override async Task LocalizingAsync(LocalizationContentContext context) { - var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); + var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; @@ -52,7 +52,7 @@ public override async Task LocalizingAsync(LocalizationContentContext context) public override async Task LocalizedAsync(LocalizationContentContext context) { - var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); + var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); if (contentTypeDefinition == null) return; diff --git a/src/OrchardCore.Modules/OrchardCore.ContentLocalization/Records/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.ContentLocalization/Records/Migrations.cs index 4d2ea46db5d..acfb3c771e5 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentLocalization/Records/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentLocalization/Records/Migrations.cs @@ -1,4 +1,3 @@ -using System.Threading.Tasks; using OrchardCore.ContentLocalization.Models; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Settings; @@ -15,9 +14,9 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public async Task CreateAsync() + public int Create() { - await _contentDefinitionManager.AlterPartDefinitionAsync(nameof(LocalizationPart), builder => builder + _contentDefinitionManager.AlterPartDefinition(nameof(LocalizationPart), builder => builder .Attachable() .WithDescription("Provides a way to create localized version of content.")); diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Controllers/AdminController.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Controllers/AdminController.cs index b2ec348d476..71308d7ace4 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Controllers/AdminController.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Controllers/AdminController.cs @@ -72,7 +72,7 @@ public async Task List() return View("List", new ListContentTypesViewModel { - Types = await _contentDefinitionService.GetTypesAsync() + Types = _contentDefinitionService.GetTypes() }); } @@ -103,7 +103,7 @@ public async Task CreatePOST(CreateTypeViewModel viewModel) ModelState.AddModelError("Name", S["The Content Type Id can't be empty."]); } - if ((await _contentDefinitionService.GetTypesAsync()).Any(t => String.Equals(t.Name.Trim(), viewModel.Name.Trim(), StringComparison.OrdinalIgnoreCase))) + if (_contentDefinitionService.GetTypes().Any(t => String.Equals(t.Name.Trim(), viewModel.Name.Trim(), StringComparison.OrdinalIgnoreCase))) { ModelState.AddModelError("Name", S["A type with the same Id already exists."]); } @@ -113,7 +113,7 @@ public async Task CreatePOST(CreateTypeViewModel viewModel) ModelState.AddModelError("Name", S["The technical name must start with a letter."]); } - if ((await _contentDefinitionService.GetTypesAsync()).Any(t => String.Equals(t.DisplayName.Trim(), viewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase))) + if (_contentDefinitionService.GetTypes().Any(t => String.Equals(t.DisplayName.Trim(), viewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase))) { ModelState.AddModelError("DisplayName", S["A type with the same Display Name already exists."]); } @@ -124,7 +124,7 @@ public async Task CreatePOST(CreateTypeViewModel viewModel) return View(viewModel); } - var contentTypeDefinition = await _contentDefinitionService.AddTypeAsync(viewModel.Name, viewModel.DisplayName); + var contentTypeDefinition = _contentDefinitionService.AddType(viewModel.Name, viewModel.DisplayName); var typeViewModel = new EditTypeViewModel(contentTypeDefinition); @@ -139,7 +139,7 @@ public async Task Edit(string id) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var typeViewModel = await _contentDefinitionService.GetTypeAsync(id); + var typeViewModel = _contentDefinitionService.GetType(id); if (typeViewModel == null) { @@ -158,7 +158,7 @@ public async Task EditPOST(string id, EditTypeViewModel viewModel) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(id); + var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(id); if (contentTypeDefinition == null) { @@ -178,12 +178,12 @@ public async Task EditPOST(string id, EditTypeViewModel viewModel) } else { - var ownedPartDefinition = await _contentDefinitionManager.GetPartDefinitionAsync(contentTypeDefinition.Name); + var ownedPartDefinition = _contentDefinitionManager.GetPartDefinition(contentTypeDefinition.Name); if (ownedPartDefinition != null && viewModel.OrderedFieldNames != null) { - await _contentDefinitionService.AlterPartFieldsOrderAsync(ownedPartDefinition, viewModel.OrderedFieldNames); + _contentDefinitionService.AlterPartFieldsOrder(ownedPartDefinition, viewModel.OrderedFieldNames); } - await _contentDefinitionService.AlterTypePartsOrderAsync(contentTypeDefinition, viewModel.OrderedPartNames); + _contentDefinitionService.AlterTypePartsOrder(contentTypeDefinition, viewModel.OrderedPartNames); _notifier.Success(T["\"{0}\" settings have been saved.", contentTypeDefinition.Name]); } @@ -197,12 +197,12 @@ public async Task Delete(string id) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var typeViewModel = await _contentDefinitionService.GetTypeAsync(id); + var typeViewModel = _contentDefinitionService.GetType(id); if (typeViewModel == null) return NotFound(); - await _contentDefinitionService.RemoveTypeAsync(id, true); + _contentDefinitionService.RemoveType(id, true); _notifier.Success(T["\"{0}\" has been removed.", typeViewModel.DisplayName]); @@ -216,7 +216,7 @@ public async Task AddPartsTo(string id) return Unauthorized(); } - var typeViewModel = await _contentDefinitionService.GetTypeAsync(id); + var typeViewModel = _contentDefinitionService.GetType(id); if (typeViewModel == null) return NotFound(); @@ -226,7 +226,7 @@ public async Task AddPartsTo(string id) var viewModel = new AddPartsViewModel { Type = typeViewModel, - PartSelections = (await _contentDefinitionService.GetPartsAsync(metadataPartsOnly: false)) + PartSelections = _contentDefinitionService.GetParts(metadataPartsOnly: false) .Where(cpd => !typePartNames.Contains(cpd.Name) && cpd.Settings.ToObject().Attachable) .Select(cpd => new PartSelectionViewModel { PartName = cpd.Name, PartDisplayName = cpd.DisplayName, PartDescription = cpd.Description }) .ToList() @@ -242,12 +242,12 @@ public async Task AddReusablePartTo(string id) return Unauthorized(); } - var typeViewModel = await _contentDefinitionService.GetTypeAsync(id); + var typeViewModel = _contentDefinitionService.GetType(id); if (typeViewModel == null) return NotFound(); - var reusableParts = (await _contentDefinitionService.GetPartsAsync(metadataPartsOnly: false)) + var reusableParts = _contentDefinitionService.GetParts(metadataPartsOnly: false) .Where(cpd => cpd.Settings.ToObject().Attachable && cpd.Settings.ToObject().Reusable); @@ -270,7 +270,7 @@ public async Task AddPartsToPOST(string id) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var typeViewModel = await _contentDefinitionService.GetTypeAsync(id); + var typeViewModel = _contentDefinitionService.GetType(id); if (typeViewModel == null) return NotFound(); @@ -284,7 +284,7 @@ public async Task AddPartsToPOST(string id) var partsToAdd = viewModel.PartSelections.Where(ps => ps.IsSelected).Select(ps => ps.PartName); foreach (var partToAdd in partsToAdd) { - await _contentDefinitionService.AddPartToTypeAsync(partToAdd, typeViewModel.Name); + _contentDefinitionService.AddPartToType(partToAdd, typeViewModel.Name); _notifier.Success(T["The \"{0}\" part has been added.", partToAdd]); } @@ -303,7 +303,7 @@ public async Task AddReusablePartToPOST(string id) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var typeViewModel = await _contentDefinitionService.GetTypeAsync(id); + var typeViewModel = _contentDefinitionService.GetType(id); if (typeViewModel == null) return NotFound(); @@ -326,7 +326,7 @@ public async Task AddReusablePartToPOST(string id) var partToAdd = viewModel.SelectedPartName; - await _contentDefinitionService.AddReusablePartToTypeAsync(viewModel.Name, viewModel.DisplayName, viewModel.Description, partToAdd, typeViewModel.Name); + _contentDefinitionService.AddReusablePartToType(viewModel.Name, viewModel.DisplayName, viewModel.Description, partToAdd, typeViewModel.Name); if (!ModelState.IsValid) { @@ -347,13 +347,13 @@ public async Task RemovePartPOST(string id, string name) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var typeViewModel = await _contentDefinitionService.GetTypeAsync(id); + var typeViewModel = _contentDefinitionService.GetType(id); if (typeViewModel == null || !typeViewModel.TypeDefinition.Parts.Any(p => p.Name == name)) return NotFound(); - await _contentDefinitionService.RemovePartFromTypeAsync(name, id); + _contentDefinitionService.RemovePartFromType(name, id); _notifier.Success(T["The \"{0}\" part has been removed.", name]); @@ -372,7 +372,7 @@ public async Task ListParts() return View(new ListContentPartsViewModel { // only user-defined parts (not code as they are not configurable) - Parts = await _contentDefinitionService.GetPartsAsync(true/*metadataPartsOnly*/) + Parts = _contentDefinitionService.GetParts(true/*metadataPartsOnly*/) }); } @@ -394,7 +394,7 @@ public async Task CreatePartPOST(CreatePartViewModel viewModel) { ModelState.AddModelError("Name", S["Name is Required."]); } - else if (await _contentDefinitionManager.GetPartDefinitionAsync(viewModel.Name) != null) + else if (_contentDefinitionManager.GetPartDefinition(viewModel.Name) != null) { ModelState.AddModelError("Name", S["Cannot add part named '{0}'. It already exists.", viewModel.Name]); } @@ -402,7 +402,7 @@ public async Task CreatePartPOST(CreatePartViewModel viewModel) if (!ModelState.IsValid) return View(viewModel); - var partViewModel = await _contentDefinitionService.AddPartAsync(viewModel); + var partViewModel = _contentDefinitionService.AddPart(viewModel); if (partViewModel == null) { @@ -420,7 +420,7 @@ public async Task EditPart(string id) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var contentPartDefinition = await _contentDefinitionManager.GetPartDefinitionAsync(id); + var contentPartDefinition = _contentDefinitionManager.GetPartDefinition(id); if (contentPartDefinition == null) { @@ -440,7 +440,7 @@ public async Task EditPartPOST(string id, string[] orderedFieldNam if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var contentPartDefinition = await _contentDefinitionManager.GetPartDefinitionAsync(id); + var contentPartDefinition = _contentDefinitionManager.GetPartDefinition(id); if (contentPartDefinition == null) { @@ -457,7 +457,7 @@ public async Task EditPartPOST(string id, string[] orderedFieldNam } else { - await _contentDefinitionService.AlterPartFieldsOrderAsync(contentPartDefinition, orderedFieldNames); + _contentDefinitionService.AlterPartFieldsOrder(contentPartDefinition, orderedFieldNames); _notifier.Success(T["The settings of \"{0}\" have been saved.", contentPartDefinition.Name]); } @@ -471,12 +471,12 @@ public async Task DeletePart(string id) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var partViewModel = await _contentDefinitionService.GetPartAsync(id); + var partViewModel = _contentDefinitionService.GetPart(id); if (partViewModel == null) return NotFound(); - await _contentDefinitionService.RemovePartAsync(id); + _contentDefinitionService.RemovePart(id); _notifier.Information(T["\"{0}\" has been removed.", partViewModel.DisplayName]); @@ -488,7 +488,7 @@ public async Task AddFieldTo(string id, string returnUrl = null) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var partViewModel = await _contentDefinitionService.GetPartAsync(id); + var partViewModel = _contentDefinitionService.GetPart(id); if (partViewModel == null) { @@ -498,7 +498,7 @@ public async Task AddFieldTo(string id, string returnUrl = null) var viewModel = new AddFieldViewModel { Part = partViewModel.PartDefinition, - Fields = (await _contentDefinitionService.GetFieldsAsync()).Select(x => x.Name).OrderBy(x => x).ToList() + Fields = _contentDefinitionService.GetFields().Select(x => x.Name).OrderBy(x => x).ToList() }; ViewData["ReturnUrl"] = returnUrl; @@ -511,7 +511,7 @@ public async Task AddFieldToPOST(AddFieldViewModel viewModel, stri if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var partViewModel = await _contentDefinitionService.GetPartAsync(id); + var partViewModel = _contentDefinitionService.GetPart(id); if (partViewModel == null) { @@ -557,7 +557,7 @@ public async Task AddFieldToPOST(AddFieldViewModel viewModel, stri if (!ModelState.IsValid) { viewModel.Part = partDefinition; - viewModel.Fields = (await _contentDefinitionService.GetFieldsAsync()).Select(x => x.Name).OrderBy(x => x).ToList(); + viewModel.Fields = _contentDefinitionService.GetFields().Select(x => x.Name).OrderBy(x => x).ToList(); _session.Cancel(); @@ -565,7 +565,7 @@ public async Task AddFieldToPOST(AddFieldViewModel viewModel, stri return View(viewModel); } - await _contentDefinitionService.AddFieldToPartAsync(viewModel.Name, viewModel.DisplayName, viewModel.FieldTypeName, partDefinition.Name); + _contentDefinitionService.AddFieldToPart(viewModel.Name, viewModel.DisplayName, viewModel.FieldTypeName, partDefinition.Name); _notifier.Success(T["The field \"{0}\" has been added.", viewModel.DisplayName]); @@ -584,7 +584,7 @@ public async Task EditField(string id, string name, string returnU if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var partViewModel = await _contentDefinitionService.GetPartAsync(id); + var partViewModel = _contentDefinitionService.GetPart(id); if (partViewModel == null) { @@ -626,14 +626,14 @@ public async Task EditFieldPOST(string id, EditFieldViewModel view return NotFound(); } - var partViewModel = await _contentDefinitionService.GetPartAsync(id); + var partViewModel = _contentDefinitionService.GetPart(id); if (partViewModel == null) { return NotFound(); } - var field = (await _contentDefinitionManager.GetPartDefinitionAsync(id)).Fields.FirstOrDefault(x => x.Name == viewModel.Name); + var field = _contentDefinitionManager.GetPartDefinition(id).Fields.FirstOrDefault(x => x.Name == viewModel.Name); if (field == null) { @@ -652,7 +652,7 @@ public async Task EditFieldPOST(string id, EditFieldViewModel view ModelState.AddModelError("DisplayName", S["The Display Name name can't be empty."]); } - if ((await _contentDefinitionService.GetPartAsync(partViewModel.Name)).PartDefinition.Fields.Any(t => t.Name != viewModel.Name && String.Equals(t.DisplayName().Trim(), viewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase))) + if (_contentDefinitionService.GetPart(partViewModel.Name).PartDefinition.Fields.Any(t => t.Name != viewModel.Name && String.Equals(t.DisplayName().Trim(), viewModel.DisplayName.Trim(), StringComparison.OrdinalIgnoreCase))) { ModelState.AddModelError("DisplayName", S["A field with the same Display Name already exists."]); } @@ -668,10 +668,10 @@ public async Task EditFieldPOST(string id, EditFieldViewModel view _notifier.Information(T["Display name changed to {0}.", viewModel.DisplayName]); } - await _contentDefinitionService.AlterFieldAsync(partViewModel, viewModel); + _contentDefinitionService.AlterField(partViewModel, viewModel); // Refresh the local field variable in case it has been altered - field = (await _contentDefinitionManager.GetPartDefinitionAsync(id)).Fields.FirstOrDefault(x => x.Name == viewModel.Name); + field = _contentDefinitionManager.GetPartDefinition(id).Fields.FirstOrDefault(x => x.Name == viewModel.Name); viewModel.Shape = await _contentDefinitionDisplayManager.UpdatePartFieldEditorAsync(field, this); @@ -695,7 +695,7 @@ public async Task EditFieldPOST(string id, EditFieldViewModel view else { // Redirect to the type editor if a type exists with this name - var typeViewModel = await _contentDefinitionService.GetTypeAsync(id); + var typeViewModel = _contentDefinitionService.GetType(id); if (typeViewModel != null) { return RedirectToAction("Edit", new { id }); @@ -711,7 +711,7 @@ public async Task RemoveFieldFromPOST(string id, string name) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var partViewModel = await _contentDefinitionService.GetPartAsync(id); + var partViewModel = _contentDefinitionService.GetPart(id); if (partViewModel == null) { @@ -725,11 +725,11 @@ public async Task RemoveFieldFromPOST(string id, string name) return NotFound(); } - await _contentDefinitionService.RemoveFieldFromPartAsync(name, partViewModel.Name); + _contentDefinitionService.RemoveFieldFromPart(name, partViewModel.Name); _notifier.Success(T["The \"{0}\" field has been removed.", field.DisplayName()]); - if (await _contentDefinitionService.GetTypeAsync(id) != null) + if (_contentDefinitionService.GetType(id) != null) { return RedirectToAction("Edit", new { id }); } @@ -745,7 +745,7 @@ public async Task EditTypePart(string id, string name) if (!await _authorizationService.AuthorizeAsync(User, Permissions.EditContentTypes)) return Unauthorized(); - var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(id); + var typeDefinition = _contentDefinitionManager.GetTypeDefinition(id); if (typeDefinition == null) { @@ -784,7 +784,7 @@ public async Task EditTypePartPOST(string id, EditTypePartViewMode return NotFound(); } - var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(id); + var typeDefinition = _contentDefinitionManager.GetTypeDefinition(id); if (typeDefinition == null) { @@ -826,7 +826,7 @@ public async Task EditTypePartPOST(string id, EditTypePartViewMode } } - await _contentDefinitionService.AlterTypePartAsync(viewModel); + _contentDefinitionService.AlterTypePart(viewModel); viewModel.Shape = await _contentDefinitionDisplayManager.UpdateTypePartEditorAsync(part, this); diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Editors/DefaultContentDefinitionDisplayManager.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Editors/DefaultContentDefinitionDisplayManager.cs index 626b64629ba..65132cf7461 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Editors/DefaultContentDefinitionDisplayManager.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Editors/DefaultContentDefinitionDisplayManager.cs @@ -84,7 +84,7 @@ public async Task UpdateTypeEditorAsync(ContentTypeDefinition contentTy var layout = await _layoutAccessor.GetLayoutAsync(); - await _contentDefinitionManager.AlterTypeDefinitionAsync(contentTypeDefinition.Name, typeBuilder => + _contentDefinitionManager.AlterTypeDefinition(contentTypeDefinition.Name, typeBuilder => { var typeContext = new UpdateTypeEditorContext( typeBuilder, @@ -143,7 +143,7 @@ public async Task UpdatePartEditorAsync(ContentPartDefinition contentPa UpdatePartEditorContext partContext = null; var layout = await _layoutAccessor.GetLayoutAsync(); - await _contentDefinitionManager.AlterPartDefinitionAsync(contentPartDefinition.Name, partBuilder => + _contentDefinitionManager.AlterPartDefinition(contentPartDefinition.Name, partBuilder => { partContext = new UpdatePartEditorContext( partBuilder, @@ -201,7 +201,7 @@ public async Task UpdateTypePartEditorAsync(ContentTypePartDefinition c dynamic typePartDefinitionShape = await CreateContentShapeAsync("ContentTypePartDefinition_Edit"); var layout = await _layoutAccessor.GetLayoutAsync(); - await _contentDefinitionManager.AlterTypeDefinitionAsync(contentTypePartDefinition.ContentTypeDefinition.Name, typeBuilder => + _contentDefinitionManager.AlterTypeDefinition(contentTypePartDefinition.ContentTypeDefinition.Name, typeBuilder => { typeBuilder.WithPart(contentTypePartDefinition.Name, async typePartBuilder => @@ -267,7 +267,7 @@ public async Task UpdatePartFieldEditorAsync(ContentPartFieldDefinition var layout = await _layoutAccessor.GetLayoutAsync(); - await _contentDefinitionManager.AlterPartDefinitionAsync(contentPartDefinition.Name, partBuilder => + _contentDefinitionManager.AlterPartDefinition(contentPartDefinition.Name, partBuilder => { partBuilder.WithField(contentPartFieldDefinition.Name, async partFieldBuilder => { diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/RecipeSteps/ContentDefinitionStep.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/RecipeSteps/ContentDefinitionStep.cs index 07260e31a03..b321c56ec3b 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/RecipeSteps/ContentDefinitionStep.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/RecipeSteps/ContentDefinitionStep.cs @@ -1,8 +1,8 @@ using System; using System.Threading.Tasks; -using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentManagement.Metadata.Records; +using OrchardCore.ContentManagement.Metadata; using OrchardCore.Recipes.Models; using OrchardCore.Recipes.Services; @@ -20,35 +20,37 @@ public ContentDefinitionStep(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public async Task ExecuteAsync(RecipeExecutionContext context) + public Task ExecuteAsync(RecipeExecutionContext context) { if (!String.Equals(context.Name, "ContentDefinition", StringComparison.OrdinalIgnoreCase)) { - return; + return Task.CompletedTask; } var step = context.Step.ToObject(); foreach (var contentType in step.ContentTypes) { - var newType = await _contentDefinitionManager.GetTypeDefinitionAsync(contentType.Name) + var newType = _contentDefinitionManager.GetTypeDefinition(contentType.Name) ?? new ContentTypeDefinition(contentType.Name, contentType.DisplayName); - await UpdateContentTypeAsync(newType, contentType); + UpdateContentType(newType, contentType); } foreach (var contentPart in step.ContentParts) { - var newPart = await _contentDefinitionManager.GetPartDefinitionAsync(contentPart.Name) + var newPart = _contentDefinitionManager.GetPartDefinition(contentPart.Name) ?? new ContentPartDefinition(contentPart.Name); - await UpdateContentPartAsync(newPart, contentPart); + UpdateContentPart(newPart, contentPart); } + + return Task.CompletedTask; } - private async Task UpdateContentTypeAsync(ContentTypeDefinition type, ContentTypeDefinitionRecord record) + private void UpdateContentType(ContentTypeDefinition type, ContentTypeDefinitionRecord record) { - await _contentDefinitionManager.AlterTypeDefinitionAsync(type.Name, builder => + _contentDefinitionManager.AlterTypeDefinition(type.Name, builder => { if (!String.IsNullOrEmpty(record.DisplayName)) { @@ -63,9 +65,9 @@ await _contentDefinitionManager.AlterTypeDefinitionAsync(type.Name, builder => }); } - private async Task UpdateContentPartAsync(ContentPartDefinition part, ContentPartDefinitionRecord record) + private void UpdateContentPart(ContentPartDefinition part, ContentPartDefinitionRecord record) { - await _contentDefinitionManager.AlterPartDefinitionAsync(part.Name, builder => + _contentDefinitionManager.AlterPartDefinition(part.Name, builder => { builder.MergeSettings(record.Settings); diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/ContentDefinitionService.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/ContentDefinitionService.cs index a28b7a31747..681975865dc 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/ContentDefinitionService.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/ContentDefinitionService.cs @@ -1,13 +1,13 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentManagement.Metadata.Settings; +using OrchardCore.ContentManagement.Records; using OrchardCore.ContentTypes.Events; using OrchardCore.ContentTypes.ViewModels; using OrchardCore.Modules; @@ -49,17 +49,17 @@ public ContentDefinitionService( public ILogger Logger { get; } public IStringLocalizer T { get; set; } - public async Task> GetTypesAsync() + public IEnumerable GetTypes() { - return (await _contentDefinitionManager - .ListTypeDefinitionsAsync()) + return _contentDefinitionManager + .ListTypeDefinitions() .Select(ctd => new EditTypeViewModel(ctd)) .OrderBy(m => m.DisplayName); } - public async Task GetTypeAsync(string name) + public EditTypeViewModel GetType(string name) { - var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(name); + var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(name); if (contentTypeDefinition == null) { @@ -69,7 +69,7 @@ public async Task GetTypeAsync(string name) return new EditTypeViewModel(contentTypeDefinition); } - public async Task AddTypeAsync(string name, string displayName) + public ContentTypeDefinition AddType(string name, string displayName) { if (String.IsNullOrWhiteSpace(displayName)) { @@ -78,7 +78,7 @@ public async Task AddTypeAsync(string name, string displa if (String.IsNullOrWhiteSpace(name)) { - name = await GenerateContentTypeNameFromDisplayNameAsync(displayName); + name = GenerateContentTypeNameFromDisplayName(displayName); } else { @@ -88,55 +88,53 @@ public async Task AddTypeAsync(string name, string displa } } - while (await _contentDefinitionManager.GetTypeDefinitionAsync(name) != null) - { + while (_contentDefinitionManager.GetTypeDefinition(name) != null) name = VersionName(name); - } var contentTypeDefinition = new ContentTypeDefinition(name, displayName); - await _contentDefinitionManager.StoreTypeDefinitionAsync(contentTypeDefinition); + _contentDefinitionManager.StoreTypeDefinition(contentTypeDefinition); // Ensure it has its own part - await _contentDefinitionManager.AlterTypeDefinitionAsync(name, builder => builder.WithPart(name)); - await _contentDefinitionManager.AlterTypeDefinitionAsync(name, cfg => cfg.Creatable().Draftable().Versionable().Listable().Securable()); + _contentDefinitionManager.AlterTypeDefinition(name, builder => builder.WithPart(name)); + _contentDefinitionManager.AlterTypeDefinition(name, cfg => cfg.Creatable().Draftable().Versionable().Listable().Securable()); _contentDefinitionEventHandlers.Invoke(x => x.ContentTypeCreated(new ContentTypeCreatedContext { ContentTypeDefinition = contentTypeDefinition }), Logger); return contentTypeDefinition; } - public async Task RemoveTypeAsync(string name, bool deleteContent) + public void RemoveType(string name, bool deleteContent) { // first remove all attached parts - var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(name); + var typeDefinition = _contentDefinitionManager.GetTypeDefinition(name); var partDefinitions = typeDefinition.Parts.ToArray(); foreach (var partDefinition in partDefinitions) { - await RemovePartFromTypeAsync(partDefinition.PartDefinition.Name, name); + RemovePartFromType(partDefinition.PartDefinition.Name, name); // delete the part if it's its own part if (partDefinition.PartDefinition.Name == name) { - await RemovePartAsync(name); + RemovePart(name); } } - await _contentDefinitionManager.DeleteTypeDefinitionAsync(name); + _contentDefinitionManager.DeleteTypeDefinition(name); _contentDefinitionEventHandlers.Invoke(x => x.ContentTypeRemoved(new ContentTypeRemovedContext { ContentTypeDefinition = typeDefinition }), Logger); } - public async Task AddPartToTypeAsync(string partName, string typeName) + public void AddPartToType(string partName, string typeName) { - await _contentDefinitionManager.AlterTypeDefinitionAsync(typeName, typeBuilder => typeBuilder.WithPart(partName)); + _contentDefinitionManager.AlterTypeDefinition(typeName, typeBuilder => typeBuilder.WithPart(partName)); _contentDefinitionEventHandlers.Invoke(x => x.ContentPartAttached(new ContentPartAttachedContext { ContentTypeName = typeName, ContentPartName = partName }), Logger); } - public async Task AddReusablePartToTypeAsync(string name, string displayName, string description, string partName, string typeName) + public void AddReusablePartToType(string name, string displayName, string description, string partName, string typeName) { - await _contentDefinitionManager.AlterTypeDefinitionAsync(typeName, typeBuilder => typeBuilder.WithPart(name, partName, cfg => + _contentDefinitionManager.AlterTypeDefinition(typeName, typeBuilder => typeBuilder.WithPart(name, partName, cfg => { cfg.WithDisplayName(displayName); cfg.WithDescription(description); @@ -145,19 +143,19 @@ await _contentDefinitionManager.AlterTypeDefinitionAsync(typeName, typeBuilder = _contentDefinitionEventHandlers.Invoke(x => x.ContentPartAttached(new ContentPartAttachedContext { ContentTypeName = typeName, ContentPartName = partName }), Logger); } - public async Task RemovePartFromTypeAsync(string partName, string typeName) + public void RemovePartFromType(string partName, string typeName) { - await _contentDefinitionManager.AlterTypeDefinitionAsync(typeName, typeBuilder => typeBuilder.RemovePart(partName)); + _contentDefinitionManager.AlterTypeDefinition(typeName, typeBuilder => typeBuilder.RemovePart(partName)); _contentDefinitionEventHandlers.Invoke(x => x.ContentPartDetached(new ContentPartDetachedContext { ContentTypeName = typeName, ContentPartName = partName }), Logger); } - public async Task> GetPartsAsync(bool metadataPartsOnly) + public IEnumerable GetParts(bool metadataPartsOnly) { - var typeNames = new HashSet((await GetTypesAsync()).Select(ctd => ctd.Name)); + var typeNames = new HashSet(GetTypes().Select(ctd => ctd.Name)); // user-defined parts // except for those parts with the same name as a type (implicit type's part or a mistake) - var userContentParts = (await _contentDefinitionManager.ListPartDefinitionsAsync()) + var userContentParts = _contentDefinitionManager.ListPartDefinitions() .Where(cpd => !typeNames.Contains(cpd.Name)) .Select(cpd => new EditPartViewModel(cpd)) .ToDictionary( @@ -178,13 +176,13 @@ public async Task> GetPartsAsync(bool metadataPar .OrderBy(m => m.DisplayName); } - public async Task GetPartAsync(string name) + public EditPartViewModel GetPart(string name) { - var contentPartDefinition = await _contentDefinitionManager.GetPartDefinitionAsync(name); + var contentPartDefinition = _contentDefinitionManager.GetPartDefinition(name); if (contentPartDefinition == null) { - var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(name); + var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(name); if (contentTypeDefinition == null) { @@ -199,17 +197,17 @@ public async Task GetPartAsync(string name) return viewModel; } - public async Task AddPartAsync(CreatePartViewModel partViewModel) + public EditPartViewModel AddPart(CreatePartViewModel partViewModel) { var name = partViewModel.Name; - if (await _contentDefinitionManager.GetPartDefinitionAsync(name) != null) + if (_contentDefinitionManager.GetPartDefinition(name) != null) throw new Exception(T["Cannot add part named '{0}'. It already exists.", name]); if (!string.IsNullOrEmpty(name)) { - await _contentDefinitionManager.AlterPartDefinitionAsync(name, builder => builder.Attachable()); - var partDefinition = await _contentDefinitionManager.GetPartDefinitionAsync(name); + _contentDefinitionManager.AlterPartDefinition(name, builder => builder.Attachable()); + var partDefinition = _contentDefinitionManager.GetPartDefinition(name); _contentDefinitionEventHandlers.Invoke(x => x.ContentPartCreated(new ContentPartCreatedContext { ContentPartDefinition = partDefinition }), Logger); return new EditPartViewModel(partDefinition); } @@ -217,9 +215,9 @@ public async Task AddPartAsync(CreatePartViewModel partViewMo return null; } - public async Task RemovePartAsync(string name) + public void RemovePart(string name) { - var partDefinition = await _contentDefinitionManager.GetPartDefinitionAsync(name); + var partDefinition = _contentDefinitionManager.GetPartDefinition(name); if (partDefinition == null) { @@ -230,42 +228,42 @@ public async Task RemovePartAsync(string name) var fieldDefinitions = partDefinition.Fields.ToArray(); foreach (var fieldDefinition in fieldDefinitions) { - await RemoveFieldFromPartAsync(fieldDefinition.Name, name); + RemoveFieldFromPart(fieldDefinition.Name, name); } - await _contentDefinitionManager.DeletePartDefinitionAsync(name); + _contentDefinitionManager.DeletePartDefinition(name); _contentDefinitionEventHandlers.Invoke(x => x.ContentPartRemoved(new ContentPartRemovedContext { ContentPartDefinition = partDefinition }), Logger); } - public Task> GetFieldsAsync() + public IEnumerable GetFields() { - return Task.FromResult((IEnumerable)_contentFields.Select(x => x.GetType()).ToArray()); + return _contentFields.Select(x => x.GetType()).ToList(); } - public Task AddFieldToPartAsync(string fieldName, string fieldTypeName, string partName) + public void AddFieldToPart(string fieldName, string fieldTypeName, string partName) { - return AddFieldToPartAsync(fieldName, fieldName, fieldTypeName, partName); + AddFieldToPart(fieldName, fieldName, fieldTypeName, partName); } - public async Task AddFieldToPartAsync(string fieldName, string displayName, string fieldTypeName, string partName) + public void AddFieldToPart(string fieldName, string displayName, string fieldTypeName, string partName) { if (String.IsNullOrEmpty(fieldName)) { throw new ArgumentException(nameof(fieldName)); } - var partDefinition = await _contentDefinitionManager.GetPartDefinitionAsync(partName); - var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(partName); + var partDefinition = _contentDefinitionManager.GetPartDefinition(partName); + var typeDefinition = _contentDefinitionManager.GetTypeDefinition(partName); // If the type exists ensure it has its own part if (typeDefinition != null) { - await _contentDefinitionManager.AlterTypeDefinitionAsync(partName, builder => builder.WithPart(partName)); + _contentDefinitionManager.AlterTypeDefinition(partName, builder => builder.WithPart(partName)); } fieldName = fieldName.ToSafeName(); - await _contentDefinitionManager.AlterPartDefinitionAsync(partName, + _contentDefinitionManager.AlterPartDefinition(partName, partBuilder => partBuilder.WithField(fieldName, fieldBuilder => fieldBuilder.OfType(fieldTypeName).WithDisplayName(displayName))); _contentDefinitionEventHandlers.Invoke(x => x.ContentFieldAttached(new ContentFieldAttachedContext @@ -277,9 +275,9 @@ await _contentDefinitionManager.AlterPartDefinitionAsync(partName, }), Logger); } - public async Task RemoveFieldFromPartAsync(string fieldName, string partName) + public void RemoveFieldFromPart(string fieldName, string partName) { - await _contentDefinitionManager.AlterPartDefinitionAsync(partName, typeBuilder => typeBuilder.RemoveField(fieldName)); + _contentDefinitionManager.AlterPartDefinition(partName, typeBuilder => typeBuilder.RemoveField(fieldName)); _contentDefinitionEventHandlers.Invoke(x => x.ContentFieldDetached(new ContentFieldDetachedContext { ContentPartName = partName, @@ -287,9 +285,9 @@ public async Task RemoveFieldFromPartAsync(string fieldName, string partName) }), Logger); } - public Task AlterFieldAsync(EditPartViewModel partViewModel, EditFieldViewModel fieldViewModel) + public void AlterField(EditPartViewModel partViewModel, EditFieldViewModel fieldViewModel) { - return _contentDefinitionManager.AlterPartDefinitionAsync(partViewModel.Name, partBuilder => + _contentDefinitionManager.AlterPartDefinition(partViewModel.Name, partBuilder => { partBuilder.WithField(fieldViewModel.Name, fieldBuilder => { @@ -300,11 +298,11 @@ public Task AlterFieldAsync(EditPartViewModel partViewModel, EditFieldViewModel }); } - public Task AlterTypePartAsync(EditTypePartViewModel typePartViewModel) + public void AlterTypePart(EditTypePartViewModel typePartViewModel) { var typeDefinition = typePartViewModel.TypePartDefinition.ContentTypeDefinition; - return _contentDefinitionManager.AlterTypeDefinitionAsync(typeDefinition.Name, type => + _contentDefinitionManager.AlterTypeDefinition(typeDefinition.Name, type => { type.WithPart(typePartViewModel.Name, typePartViewModel.TypePartDefinition.PartDefinition, part => { @@ -315,9 +313,9 @@ public Task AlterTypePartAsync(EditTypePartViewModel typePartViewModel) }); } - public Task AlterTypePartsOrderAsync(ContentTypeDefinition typeDefinition, string[] partNames) + public void AlterTypePartsOrder(ContentTypeDefinition typeDefinition, string[] partNames) { - return _contentDefinitionManager.AlterTypeDefinitionAsync(typeDefinition.Name, type => + _contentDefinitionManager.AlterTypeDefinition(typeDefinition.Name, type => { for (var i = 0; i < partNames.Length; i++) { @@ -330,9 +328,9 @@ public Task AlterTypePartsOrderAsync(ContentTypeDefinition typeDefinition, strin }); } - public Task AlterPartFieldsOrderAsync(ContentPartDefinition partDefinition, string[] fieldNames) + public void AlterPartFieldsOrder(ContentPartDefinition partDefinition, string[] fieldNames) { - return _contentDefinitionManager.AlterPartDefinitionAsync(partDefinition.Name, type => + _contentDefinitionManager.AlterPartDefinition(partDefinition.Name, type => { for (var i = 0; i < fieldNames.Length; i++) { @@ -345,28 +343,26 @@ public Task AlterPartFieldsOrderAsync(ContentPartDefinition partDefinition, stri }); } - public async Task GenerateContentTypeNameFromDisplayNameAsync(string displayName) + public string GenerateContentTypeNameFromDisplayName(string displayName) { displayName = displayName.ToSafeName(); - while (await _contentDefinitionManager.GetTypeDefinitionAsync(displayName) != null) - { + while (_contentDefinitionManager.GetTypeDefinition(displayName) != null) displayName = VersionName(displayName); - } return displayName; } - public async Task GenerateFieldNameFromDisplayNameAsync(string partName, string displayName) + public string GenerateFieldNameFromDisplayName(string partName, string displayName) { IEnumerable fieldDefinitions; - var part = await _contentDefinitionManager.GetPartDefinitionAsync(partName); + var part = _contentDefinitionManager.GetPartDefinition(partName); displayName = displayName.ToSafeName(); if (part == null) { - var type = await _contentDefinitionManager.GetTypeDefinitionAsync(partName); + var type = _contentDefinitionManager.GetTypeDefinition(partName); if (type == null) { @@ -416,4 +412,4 @@ private static string VersionName(string name) return string.Format("{0}-{1}", name, version); } } -} +} \ No newline at end of file diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/DefaultStereotypesProvider.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/DefaultStereotypesProvider.cs index a6a28c7584a..7c4c070de7a 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/DefaultStereotypesProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/DefaultStereotypesProvider.cs @@ -1,6 +1,6 @@ +using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; namespace OrchardCore.ContentTypes.Services { @@ -12,12 +12,11 @@ public DefaultStereotypesProvider(IContentDefinitionService contentDefinitionSer _contentDefinitionService = contentDefinitionService; } - public async Task> GetStereotypesAsync() + public IEnumerable GetStereotypes() { - // Harvest all available stereotypes by finding out about the stereotype of all content types - var stereotypes = (await _contentDefinitionService.GetTypesAsync()).Where(x => x.Settings["Stereotype"] != null).Select(x => x.Settings["Stereotype"].ToString()).Distinct(); + var stereotypes = _contentDefinitionService.GetTypes().Where(x => x.Settings["Stereotype"] != null).Select(x => x.Settings["Stereotype"].ToString()).Distinct(); return stereotypes.Select(x => new StereotypeDescription { DisplayName = x, Stereotype = x }); } } -} +} \ No newline at end of file diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/IContentDefinitionService.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/IContentDefinitionService.cs index 485087f136c..36d7f659120 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/IContentDefinitionService.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/IContentDefinitionService.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentTypes.ViewModels; @@ -8,30 +7,30 @@ namespace OrchardCore.ContentTypes.Services { public interface IContentDefinitionService { - Task> GetTypesAsync(); - Task GetTypeAsync(string name); - Task AddTypeAsync(string name, string displayName); - Task RemoveTypeAsync(string name, bool deleteContent); - Task AddPartToTypeAsync(string partName, string typeName); - Task AddReusablePartToTypeAsync(string name, string displayName, string description, string partName, string typeName); - Task RemovePartFromTypeAsync(string partName, string typeName); - Task GenerateContentTypeNameFromDisplayNameAsync(string displayName); - Task GenerateFieldNameFromDisplayNameAsync(string partName, string displayName); + IEnumerable GetTypes(); + EditTypeViewModel GetType(string name); + ContentTypeDefinition AddType(string name, string displayName); + void RemoveType(string name, bool deleteContent); + void AddPartToType(string partName, string typeName); + void AddReusablePartToType(string name, string displayName, string description, string partName, string typeName); + void RemovePartFromType(string partName, string typeName); + string GenerateContentTypeNameFromDisplayName(string displayName); + string GenerateFieldNameFromDisplayName(string partName, string displayName); - Task> GetPartsAsync(bool metadataPartsOnly); - Task GetPartAsync(string name); - Task AddPartAsync(CreatePartViewModel partViewModel); - Task RemovePartAsync(string name); + IEnumerable GetParts(bool metadataPartsOnly); + EditPartViewModel GetPart(string name); + EditPartViewModel AddPart(CreatePartViewModel partViewModel); + void RemovePart(string name); - Task> GetFieldsAsync(); - Task AddFieldToPartAsync(string fieldName, string fieldTypeName, string partName); - Task AddFieldToPartAsync(string fieldName, string displayName, string fieldTypeName, string partName); - Task RemoveFieldFromPartAsync(string fieldName, string partName); - Task AlterFieldAsync(EditPartViewModel partViewModel, EditFieldViewModel fieldViewModel); + IEnumerable GetFields(); + void AddFieldToPart(string fieldName, string fieldTypeName, string partName); + void AddFieldToPart(string fieldName, string displayName, string fieldTypeName, string partName); + void RemoveFieldFromPart(string fieldName, string partName); + void AlterField(EditPartViewModel partViewModel, EditFieldViewModel fieldViewModel); - Task AlterTypePartAsync(EditTypePartViewModel partViewModel); + void AlterTypePart(EditTypePartViewModel partViewModel); - Task AlterTypePartsOrderAsync(ContentTypeDefinition typeDefinition, string[] partNames); - Task AlterPartFieldsOrderAsync(ContentPartDefinition partDefinition, string[] fieldNames); + void AlterTypePartsOrder(ContentTypeDefinition typeDefinition, string[] partNames); + void AlterPartFieldsOrder(ContentPartDefinition partDefinition, string[] fieldNames); } -} +} \ No newline at end of file diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/IStereotypesProvider.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/IStereotypesProvider.cs index c4d4e007582..b9689c57f79 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/IStereotypesProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/IStereotypesProvider.cs @@ -1,11 +1,10 @@ using System.Collections.Generic; -using System.Threading.Tasks; namespace OrchardCore.ContentTypes.Services { public interface IStereotypesProvider { - Task> GetStereotypesAsync(); + IEnumerable GetStereotypes(); } public class StereotypeDescription @@ -13,4 +12,4 @@ public class StereotypeDescription public string Stereotype { get; set; } public string DisplayName { get; set; } } -} +} \ No newline at end of file diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/StereotypeService.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/StereotypeService.cs index c8a43dcab0b..17358cfc601 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/StereotypeService.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/StereotypeService.cs @@ -1,11 +1,11 @@ using System.Collections.Generic; -using System.Threading.Tasks; +using System.Linq; namespace OrchardCore.ContentTypes.Services { public interface IStereotypeService { - Task> GetStereotypesAsync(); + IEnumerable GetStereotypes(); } public class StereotypeService : IStereotypeService @@ -17,14 +17,9 @@ public StereotypeService(IEnumerable providers) _providers = providers; } - public async Task> GetStereotypesAsync() + public IEnumerable GetStereotypes() { - var stereotypes = new List(); - foreach (var provider in _providers) - { - stereotypes.AddRange(await provider.GetStereotypesAsync()); - } - return stereotypes; + return _providers.SelectMany(x => x.GetStereotypes()); } } -} +} \ No newline at end of file diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewComponents/SelectContentTypesViewComponent.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewComponents/SelectContentTypesViewComponent.cs index 6b11f169c9b..4f848206a05 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewComponents/SelectContentTypesViewComponent.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewComponents/SelectContentTypesViewComponent.cs @@ -1,11 +1,10 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; -using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Settings; +using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentTypes.ViewModels; +using System.Collections.Generic; namespace OrchardCore.ContentTypes.ViewComponents { @@ -18,14 +17,14 @@ public SelectContentTypesViewComponent(IContentDefinitionManager contentDefiniti _contentDefinitionManager = contentDefinitionManager; } - public async Task InvokeAsync(IEnumerable selectedContentTypes, string htmlName, string stereotype) + public IViewComponentResult Invoke(IEnumerable selectedContentTypes, string htmlName, string stereotype) { if (selectedContentTypes == null) { selectedContentTypes = new string[0]; } - var contentTypes = await ContentTypeSelection.BuildAsync(_contentDefinitionManager, selectedContentTypes); + var contentTypes = ContentTypeSelection.Build(_contentDefinitionManager, selectedContentTypes); if (!String.IsNullOrEmpty(stereotype)) { diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewModels/SelectContentTypesViewModel.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewModels/SelectContentTypesViewModel.cs index cd46c31bb91..f915272a636 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewModels/SelectContentTypesViewModel.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewModels/SelectContentTypesViewModel.cs @@ -1,8 +1,7 @@ -using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; -using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Models; +using OrchardCore.ContentManagement.Metadata; +using System.Collections.Generic; namespace OrchardCore.ContentTypes.ViewModels { @@ -17,10 +16,10 @@ public class ContentTypeSelection public bool IsSelected { get; set; } public ContentTypeDefinition ContentTypeDefinition { get; set; } - public static async Task BuildAsync(IContentDefinitionManager contentDefinitionManager, IEnumerable selectedContentTypes) + public static ContentTypeSelection[] Build(IContentDefinitionManager contentDefinitionManager, IEnumerable selectedContentTypes) { - var contentTypes = (await contentDefinitionManager - .ListTypeDefinitionsAsync()) + var contentTypes = contentDefinitionManager + .ListTypeDefinitions() .Select(x => new ContentTypeSelection { diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/Edit.cshtml index 045424364d7..bc0cd1a3c42 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/Edit.cshtml @@ -7,16 +7,14 @@ @{ var typePart = Model.TypeDefinition.Parts.FirstOrDefault(x => String.Equals(x.Name, Model.TypeDefinition.Name, StringComparison.OrdinalIgnoreCase)); - var dynamicParts = new List(); - foreach (var part in Model.TypeDefinition.Parts) - { - var defaultPosition = (await ContentDefinitionManager.GetPartDefinitionAsync(part.PartDefinition.Name))?.DefaultPosition() ?? "5"; - dynamicParts.Add(new { Part = part, Order = int.Parse(part.Settings["Position"]?.ToString() ?? defaultPosition) }); - } - - var orderedParts = dynamicParts + var orderedParts = Model.TypeDefinition.Parts + .Select(part => + { + var defaultPosition = ContentDefinitionManager.GetPartDefinition(part.PartDefinition.Name)?.DefaultPosition() ?? "5"; + return new { Part = part, Order = int.Parse(part.Settings["Position"]?.ToString() ?? defaultPosition) }; + }) .OrderBy(x => x.Order) - .Select(x => (ContentTypePartDefinition)x.Part); + .Select(x => x.Part); var orderedFields = typePart == null ? Enumerable.Empty() : typePart.PartDefinition.Fields .Select(field => new { Field = field, Order = int.Parse(field.Settings["Position"]?.ToString() ?? "0") }) diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Items/ContentDefinitionDeploymentStep.Fields.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Items/ContentDefinitionDeploymentStep.Fields.Edit.cshtml index e627827f5f4..a5cbf62533f 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Items/ContentDefinitionDeploymentStep.Fields.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Items/ContentDefinitionDeploymentStep.Fields.Edit.cshtml @@ -5,8 +5,8 @@ var contentTypes = (string[])Model.ContentTypes; var contentParts = (string[])Model.ContentParts; - var allTypes = await ContentDefinitionManager.ListTypeDefinitionsAsync(); - var allParts = await ContentDefinitionManager.ListPartDefinitionsAsync(); + var allTypes = ContentDefinitionManager.ListTypeDefinitions(); + var allParts = ContentDefinitionManager.ListPartDefinitions(); var avaParts = allParts.Where(x => !allTypes.Any(y => y.Name == x.Name)); } @@ -147,3 +147,4 @@ }); }); + diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Items/ContentDefinitionDeploymentStep.Fields.Summary.cshtml b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Items/ContentDefinitionDeploymentStep.Fields.Summary.cshtml index 40eb16ef40d..af6a7b4dec9 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Items/ContentDefinitionDeploymentStep.Fields.Summary.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Items/ContentDefinitionDeploymentStep.Fields.Summary.cshtml @@ -15,14 +15,14 @@ else var contentTypes = Model.Value.ContentTypes; var contentParts = Model.Value.ContentParts; - var allTypes = await ContentDefinitionManager.ListTypeDefinitionsAsync(); - var allParts = await ContentDefinitionManager.ListPartDefinitionsAsync(); + var allTypes = ContentDefinitionManager.ListTypeDefinitions(); + var allParts = ContentDefinitionManager.ListPartDefinitions(); var avaParts = allParts.Where(x => !allTypes.Any(y => y.Name == x.Name)); if (contentTypes?.Length > 0) { - foreach (var def in await ContentDefinitionManager.ListTypeDefinitionsAsync()) + foreach (var def in ContentDefinitionManager.ListTypeDefinitions()) { if (contentTypes.Contains(def.Name)) { @@ -41,4 +41,4 @@ else } } } -} +} \ No newline at end of file diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/AdminMenu.cs b/src/OrchardCore.Modules/OrchardCore.Contents/AdminMenu.cs index 216a6888b3f..a44c0d7d166 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/AdminMenu.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/AdminMenu.cs @@ -34,7 +34,7 @@ public async Task BuildNavigationAsync(string name, NavigationBuilder builder) return; } - var contentTypeDefinitions = (await _contentDefinitionManager.ListTypeDefinitionsAsync()).OrderBy(d => d.Name); + var contentTypeDefinitions = _contentDefinitionManager.ListTypeDefinitions().OrderBy(d => d.Name); builder.Add(T["Content"], "1.4", content => content .AddClass("content").Id("content") @@ -65,4 +65,4 @@ await builder.AddAsync(T["New"], "-1", async newMenu => } } } -} +} \ No newline at end of file diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/AdminNodes/ContentTypesAdminNodeDriver.cs b/src/OrchardCore.Modules/OrchardCore.Contents/AdminNodes/ContentTypesAdminNodeDriver.cs index 1b09ad060e7..b884f1ea4f0 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/AdminNodes/ContentTypesAdminNodeDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/AdminNodes/ContentTypesAdminNodeDriver.cs @@ -1,9 +1,11 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.DisplayManagement.Handlers; +using OrchardCore.DisplayManagement.ModelBinding; using OrchardCore.DisplayManagement.Views; using OrchardCore.Navigation; @@ -25,12 +27,13 @@ public override IDisplayResult Display(ContentTypesAdminNode treeNode) ); } - public override async Task EditAsync(ContentTypesAdminNode treeNode, BuildEditorContext context) + public override IDisplayResult Edit(ContentTypesAdminNode treeNode) { - var listable = (await _contentDefinitionManager.ListTypeDefinitionsAsync()) + var listable = _contentDefinitionManager.ListTypeDefinitions() .Where(ctd => ctd.Settings.ToObject().Listable) .OrderBy(ctd => ctd.DisplayName).ToList(); + var entries = listable.Select(x => new ContentTypeEntryViewModel { ContentTypeId = x.Name, @@ -47,14 +50,14 @@ public override async Task EditAsync(ContentTypesAdminNode treeN }).Location("Content"); } - public override async Task UpdateAsync(ContentTypesAdminNode treeNode, UpdateEditorContext context) + public override async Task UpdateAsync(ContentTypesAdminNode treeNode, IUpdateModel updater) { // Initializes the value to empty otherwise the model is not updated if no type is selected. treeNode.ContentTypes = Array.Empty(); var model = new ContentTypesAdminNodeViewModel(); - if (await context.Updater.TryUpdateModelAsync(model, Prefix, x => x.ShowAll, x => x.IconClass, x => x.ContentTypes)) + if (await updater.TryUpdateModelAsync(model, Prefix, x => x.ShowAll, x => x.IconClass, x => x.ContentTypes)) { treeNode.ShowAll = model.ShowAll; @@ -65,7 +68,7 @@ public override async Task UpdateAsync(ContentTypesAdminNode tre .ToArray(); }; - return await EditAsync(treeNode, context); + return Edit(treeNode); } } } diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/AdminNodes/ContentTypesAdminNodeNavigationBuilder.cs b/src/OrchardCore.Modules/OrchardCore.Contents/AdminNodes/ContentTypesAdminNodeNavigationBuilder.cs index 0ca88c4ba26..3785d64d7a1 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/AdminNodes/ContentTypesAdminNodeNavigationBuilder.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/AdminNodes/ContentTypesAdminNodeNavigationBuilder.cs @@ -35,6 +35,7 @@ public ContentTypesAdminNodeNavigationBuilder( public string Name => typeof(ContentTypesAdminNode).Name; + public async Task BuildNavigationAsync(MenuItem menuItem, NavigationBuilder builder, IEnumerable treeNodeBuilders) { var node = menuItem as ContentTypesAdminNode; @@ -45,7 +46,7 @@ public async Task BuildNavigationAsync(MenuItem menuItem, NavigationBuilder buil } // Add ContentTypes specific children - var typesToShow = await GetContentTypesToShowAsync(node); + var typesToShow = GetContentTypesToShow(node); foreach (var ctd in typesToShow) { builder.Add(new LocalizedString(ctd.DisplayName, ctd.DisplayName), cTypeMenu => @@ -60,6 +61,7 @@ public async Task BuildNavigationAsync(MenuItem menuItem, NavigationBuilder buil }); } + // Add external children foreach (var childNode in node.Items) { @@ -73,13 +75,16 @@ public async Task BuildNavigationAsync(MenuItem menuItem, NavigationBuilder buil _logger.LogError(e, "An exception occurred while building the '{MenuItem}' child Menu Item.", childNode.GetType().Name); } } + } - private async Task> GetContentTypesToShowAsync(ContentTypesAdminNode node) + private IEnumerable GetContentTypesToShow(ContentTypesAdminNode node) { - var typesToShow = (await _contentDefinitionManager.ListTypeDefinitionsAsync()) + + var typesToShow = _contentDefinitionManager.ListTypeDefinitions() .Where(ctd => ctd.Settings.ToObject().Listable); + if (!node.ShowAll) { node.ContentTypes = node.ContentTypes ?? (new ContentTypeEntry[] { }); @@ -87,6 +92,7 @@ private async Task> GetContentTypesToShowAsyn typesToShow = typesToShow .Where(ctd => node.ContentTypes.ToList() .Any(s => String.Equals(ctd.Name, s.ContentTypeId, StringComparison.OrdinalIgnoreCase))); + } return typesToShow.OrderBy(t => t.DisplayName); @@ -105,6 +111,7 @@ private List GetIconClasses(ContentTypeDefinition contentType, ContentTy .FirstOrDefault(); return AddPrefixToClasses(typeEntry.IconClass); + } } @@ -116,5 +123,7 @@ private List AddPrefixToClasses(string unprefixed) .ToList() ?? new List(); } + } + } diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Controllers/AdminController.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Controllers/AdminController.cs index a89f434d149..666db85c0e7 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Controllers/AdminController.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Controllers/AdminController.cs @@ -108,7 +108,7 @@ public async Task List(ListContentsViewModel model, PagerParamete if (!string.IsNullOrEmpty(model.Options.SelectedContentType)) { - var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(model.Options.SelectedContentType); + var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(model.Options.SelectedContentType); if (contentTypeDefinition == null) return NotFound(); @@ -321,13 +321,15 @@ public async Task Create(string id) public Task CreatePOST(string id, [Bind(Prefix = "submit.Save")] string submitSave, string returnUrl) { var stayOnSamePage = submitSave == "submit.SaveAndContinue"; - return CreatePOST(id, returnUrl, stayOnSamePage, async contentItem => + return CreatePOST(id, returnUrl, stayOnSamePage, contentItem => { - var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); + var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); _notifier.Success(string.IsNullOrWhiteSpace(typeDefinition.DisplayName) ? T["Your content draft has been saved."] : T["Your {0} draft has been saved.", typeDefinition.DisplayName]); + + return Task.CompletedTask; }); } @@ -349,7 +351,7 @@ public async Task CreateAndPublishPOST(string id, [Bind(Prefix = { await _contentManager.PublishAsync(contentItem); - var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); + var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); _notifier.Success(string.IsNullOrWhiteSpace(typeDefinition.DisplayName) ? T["Your content has been published."] @@ -437,13 +439,15 @@ public async Task Edit(string contentItemId) public Task EditPOST(string contentItemId, [Bind(Prefix = "submit.Save")] string submitSave, string returnUrl) { var stayOnSamePage = submitSave == "submit.SaveAndContinue"; - return EditPOST(contentItemId, returnUrl, stayOnSamePage, async contentItem => + return EditPOST(contentItemId, returnUrl, stayOnSamePage, contentItem => { - var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); + var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); _notifier.Success(string.IsNullOrWhiteSpace(typeDefinition.DisplayName) ? T["Your content draft has been saved."] : T["Your {0} draft has been saved.", typeDefinition.DisplayName]); + + return Task.CompletedTask; }); } @@ -468,7 +472,7 @@ public async Task EditAndPublishPOST(string contentItemId, [Bind( { await _contentManager.PublishAsync(contentItem); - var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); + var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); _notifier.Success(string.IsNullOrWhiteSpace(typeDefinition.DisplayName) ? T["Your content has been published."] @@ -573,7 +577,7 @@ public async Task DiscardDraft(string contentItemId, string retur if (contentItem != null) { - var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); + var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); await _contentManager.DiscardDraftAsync(contentItem); @@ -597,7 +601,7 @@ public async Task Remove(string contentItemId, string returnUrl) if (contentItem != null) { - var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); + var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); await _contentManager.RemoveAsync(contentItem); @@ -625,7 +629,7 @@ public async Task Publish(string contentItemId, string returnUrl) await _contentManager.PublishAsync(contentItem); - var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); + var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); if (string.IsNullOrEmpty(typeDefinition.DisplayName)) { @@ -655,7 +659,7 @@ public async Task Unpublish(string contentItemId, string returnUr await _contentManager.UnpublishAsync(contentItem); - var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); + var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); if (string.IsNullOrEmpty(typeDefinition.DisplayName)) { @@ -672,7 +676,7 @@ public async Task Unpublish(string contentItemId, string returnUr private async Task> GetCreatableTypesAsync() { var creatable = new List(); - foreach (var ctd in await _contentDefinitionManager.ListTypeDefinitionsAsync()) + foreach (var ctd in _contentDefinitionManager.ListTypeDefinitions()) { if (ctd.Settings.ToObject().Creatable) { @@ -689,7 +693,7 @@ private async Task> GetCreatableTypesAsync() private async Task> GetListableTypesAsync() { var listable = new List(); - foreach (var ctd in await _contentDefinitionManager.ListTypeDefinitionsAsync()) + foreach (var ctd in _contentDefinitionManager.ListTypeDefinitions()) { if (ctd.Settings.ToObject().Listable) { diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/ContentsDriver.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/ContentsDriver.cs index 58ce7d94a65..e1892658bc7 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/ContentsDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/ContentsDriver.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Threading.Tasks; using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Display.ContentDisplay; using OrchardCore.ContentManagement.Display.ViewModels; @@ -20,14 +19,14 @@ public ContentsDriver(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public override async Task DisplayAsync(ContentItem model, IUpdateModel updater) + public override IDisplayResult Display(ContentItem model, IUpdateModel updater) { // We add custom alternates. This could be done generically to all shapes coming from ContentDisplayDriver but right now it's // only necessary on this shape. Otherwise c.f. ContentPartDisplayDriver var contentsMetadataShape = Shape("ContentsMetadata", new ContentItemViewModel(model)).Location("Detail", "Content:before"); - var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(model.ContentType); + var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(model.ContentType); if (contentTypeDefinition != null) { @@ -56,9 +55,9 @@ public override async Task DisplayAsync(ContentItem model, IUpda ); } - public override async Task EditAsync(ContentItem contentItem, IUpdateModel updater) + public override IDisplayResult Edit(ContentItem contentItem, IUpdateModel updater) { - var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); + var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); if (contentTypeDefinition == null) { diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/DateEditorDriver.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/DateEditorDriver.cs index 66c99020e5a..586b62c4614 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/DateEditorDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/DateEditorDriver.cs @@ -2,10 +2,10 @@ using System.Linq; using System.Threading.Tasks; using OrchardCore.ContentManagement.Display.ContentDisplay; -using OrchardCore.ContentManagement.Display.Models; using OrchardCore.ContentManagement.Metadata; using OrchardCore.Contents.Models; using OrchardCore.Contents.ViewModels; +using OrchardCore.DisplayManagement.ModelBinding; using OrchardCore.DisplayManagement.Views; using OrchardCore.Modules; @@ -22,9 +22,9 @@ public DateEditorDriver(IContentDefinitionManager contentDefinitionManager, ILoc _localClock = localClock; } - public override async Task EditAsync(CommonPart part, BuildPartEditorContext context) + public override IDisplayResult Edit(CommonPart part) { - var settings = await GetSettingsAsync(part); + var settings = GetSettings(part); if (settings.DisplayDateEditor) { @@ -37,14 +37,14 @@ public override async Task EditAsync(CommonPart part, BuildPartE return null; } - public override async Task UpdateAsync(CommonPart part, UpdatePartEditorContext context) + public override async Task UpdateAsync(CommonPart part, IUpdateModel updater) { - var settings = await GetSettingsAsync(part); + var settings = GetSettings(part); if (settings.DisplayDateEditor) { var model = new DateEditorViewModel(); - await context.Updater.TryUpdateModelAsync(model, Prefix); + await updater.TryUpdateModelAsync(model, Prefix); if (model.LocalDateTime == null) { @@ -56,14 +56,14 @@ public override async Task UpdateAsync(CommonPart part, UpdatePa } } - return await EditAsync(part, context); + return Edit(part); } - public async Task GetSettingsAsync(CommonPart part) + public CommonPartSettings GetSettings(CommonPart part) { - var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType); + var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => String.Equals(x.PartDefinition.Name, "CommonPart", StringComparison.Ordinal)); return contentTypePartDefinition.GetSettings(); } } -} +} \ No newline at end of file diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/OwnerEditorDriver.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/OwnerEditorDriver.cs index 25bed35731b..c732eb649a0 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/OwnerEditorDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/OwnerEditorDriver.cs @@ -46,7 +46,7 @@ public override async Task EditAsync(CommonPart part, BuildPartE return null; } - var settings = await GetSettingsAsync(part); + var settings = GetSettings(part); if (settings.DisplayOwnerEditor) { @@ -68,7 +68,7 @@ public override async Task UpdateAsync(CommonPart part, UpdatePa return null; } - var settings = await GetSettingsAsync(part); + var settings = GetSettings(part); if (!settings.DisplayOwnerEditor) { @@ -107,11 +107,11 @@ public override async Task UpdateAsync(CommonPart part, UpdatePa return await EditAsync(part, context); } - public async Task GetSettingsAsync(CommonPart part) + public CommonPartSettings GetSettings(CommonPart part) { - var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType); + var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType); var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => String.Equals(x.PartDefinition.Name, "CommonPart", StringComparison.Ordinal)); return contentTypePartDefinition.GetSettings(); } } -} +} \ No newline at end of file diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Indexing/ContentItemIndexCoordinator.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Indexing/ContentItemIndexCoordinator.cs index 06ebc133539..a64d3747ad4 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Indexing/ContentItemIndexCoordinator.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Indexing/ContentItemIndexCoordinator.cs @@ -1,10 +1,10 @@ using System.Collections.Generic; using System.Threading.Tasks; +using OrchardCore.Modules; using Microsoft.Extensions.Logging; using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Metadata; using OrchardCore.Indexing; -using OrchardCore.Modules; namespace OrchardCore.Contents.Indexing { @@ -36,7 +36,7 @@ public ContentItemIndexCoordinator( public async Task BuildIndexAsync(BuildIndexContext context) { - var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType); + var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType); if (contentTypeDefinition == null) { diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Migrations.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Migrations.cs index c667dcb700e..38bcb070359 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Migrations.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Migrations.cs @@ -1,6 +1,5 @@ -using System.Threading.Tasks; -using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Settings; +using OrchardCore.ContentManagement.Metadata; using OrchardCore.Data.Migration; namespace OrchardCore.Contents @@ -14,13 +13,13 @@ public Migrations(IContentDefinitionManager contentDefinitionManager) _contentDefinitionManager = contentDefinitionManager; } - public async Task CreateAsync() + public int Create() { - await _contentDefinitionManager.AlterPartDefinitionAsync("CommonPart", builder => builder + _contentDefinitionManager.AlterPartDefinition("CommonPart", builder => builder .Attachable() .WithDescription("Provides an editor for the common properties of a content item.")); return 1; } } -} +} \ No newline at end of file diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Security/ContentTypePermissions.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Security/ContentTypePermissions.cs index c702340b5ed..8198693bb79 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Security/ContentTypePermissions.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Security/ContentTypePermissions.cs @@ -1,15 +1,14 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; +using System.Collections.Generic; using OrchardCore.ContentManagement.Metadata; using OrchardCore.ContentManagement.Metadata.Models; -using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.Security.Permissions; +using OrchardCore.ContentManagement.Metadata.Settings; namespace OrchardCore.Contents.Security { - public class ContentTypePermissions : IAsyncPermissionProvider + public class ContentTypePermissions : IPermissionProvider { private static readonly Permission PublishContent = new Permission("Publish_{0}", "Publish or unpublish {0} for others", new[] { Permissions.PublishContent }); private static readonly Permission PublishOwnContent = new Permission("PublishOwn_{0}", "Publish or unpublish {0}", new[] { PublishContent, Permissions.PublishOwnContent }); @@ -42,28 +41,19 @@ public ContentTypePermissions(IContentDefinitionManager contentDefinitionManager _contentDefinitionManager = contentDefinitionManager; } - // Sync version for backward compatibility. public IEnumerable GetPermissions() - { - return GetPermissionsAsync().GetAwaiter().GetResult(); - } - - public async Task> GetPermissionsAsync() { // manage rights only for Securable types - var securableTypes = (await _contentDefinitionManager.ListTypeDefinitionsAsync()) + var securableTypes = _contentDefinitionManager.ListTypeDefinitions() .Where(ctd => ctd.Settings.ToObject().Securable); - var permissions = new List(); foreach (var typeDefinition in securableTypes) { foreach (var permissionTemplate in PermissionTemplates.Values) { - permissions.Add(CreateDynamicPermission(permissionTemplate, typeDefinition)); + yield return CreateDynamicPermission(permissionTemplate, typeDefinition); } } - - return permissions; } public IEnumerable GetDefaultStereotypes() diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/TagHelpers/ContentLinkTagHelper.cs b/src/OrchardCore.Modules/OrchardCore.Contents/TagHelpers/ContentLinkTagHelper.cs index b09634b49b7..b26953a3369 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/TagHelpers/ContentLinkTagHelper.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/TagHelpers/ContentLinkTagHelper.cs @@ -160,7 +160,7 @@ public override async Task ProcessAsync(TagHelperContext tagHelperContext, TagHe } else { - var typeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); + var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); output.Content.Append(typeDefinition.ToString()); } } diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Admin/Create.cshtml b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Admin/Create.cshtml index 9c8ef6e8534..8f2ba0ae5c0 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Admin/Create.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Admin/Create.cshtml @@ -6,7 +6,7 @@ @{ ContentItem contentItem = Model.ContentItem; - var contentTypeDefinition = await ContentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); + var contentTypeDefinition = ContentDefinitionManager.GetTypeDefinition(contentItem.ContentType); var typeDisplayName = contentTypeDefinition?.DisplayName ?? contentItem.ContentType.CamelFriendly(); } diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Admin/Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Admin/Edit.cshtml index 605c3a0a33b..6c86fbfb59a 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Admin/Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Admin/Edit.cshtml @@ -6,7 +6,7 @@ @{ ContentItem contentItem = Model.ContentItem; - var contentTypeDefinition = await ContentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); + var contentTypeDefinition = ContentDefinitionManager.GetTypeDefinition(contentItem.ContentType); var typeDisplayName = contentTypeDefinition?.DisplayName ?? contentItem.ContentType.CamelFriendly(); } diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/ContentDeploymentStep.Fields.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/ContentDeploymentStep.Fields.Edit.cshtml index e786f479eff..df8589f49a1 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/ContentDeploymentStep.Fields.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/ContentDeploymentStep.Fields.Edit.cshtml @@ -10,7 +10,7 @@