using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Web.Caching; using SixLabors.ImageSharp.Web.Commands; using SixLabors.ImageSharp.Web.DependencyInjection; using SixLabors.ImageSharp.Web.Processors; using SixLabors.ImageSharp.Web.Providers; using Smidge; using Smidge.Nuglify; using Umbraco.Core.Configuration.Models; using Umbraco.Web.Common.ApplicationModels; namespace Umbraco.Extensions { public static class UmbracoWebServiceCollectionExtensions { /// /// Registers the web components needed for Umbraco /// /// /// /// public static IServiceCollection AddUmbracoWebComponents(this IServiceCollection services, IConfiguration configuration) { services.ConfigureOptions(); services.TryAddEnumerable(ServiceDescriptor.Transient()); services.TryAddEnumerable(ServiceDescriptor.Transient()); services.AddUmbracoImageSharp(configuration); return services; } /// /// Adds Image Sharp with Umbraco settings /// /// /// /// public static IServiceCollection AddUmbracoImageSharp(this IServiceCollection services, IConfiguration configuration) { var imagingSettings = configuration.GetSection(Core.Constants.Configuration.ConfigImaging) .Get() ?? new ImagingSettings(); services.AddImageSharp(options => { options.Configuration = SixLabors.ImageSharp.Configuration.Default; options.BrowserMaxAge = imagingSettings.Cache.BrowserMaxAge; options.CacheMaxAge = imagingSettings.Cache.CacheMaxAge; options.CachedNameLength = imagingSettings.Cache.CachedNameLength; options.OnParseCommandsAsync = context => { RemoveIntParamenterIfValueGreatherThen(context.Commands, ResizeWebProcessor.Width, imagingSettings.Resize.MaxWidth); RemoveIntParamenterIfValueGreatherThen(context.Commands, ResizeWebProcessor.Height, imagingSettings.Resize.MaxHeight); return Task.CompletedTask; }; options.OnBeforeSaveAsync = _ => Task.CompletedTask; options.OnProcessedAsync = _ => Task.CompletedTask; options.OnPrepareResponseAsync = _ => Task.CompletedTask; }) .SetRequestParser() .SetMemoryAllocator(provider => ArrayPoolMemoryAllocator.CreateWithMinimalPooling()) .Configure(options => { options.CacheFolder = imagingSettings.Cache.CacheFolder; }) .SetCache() .SetCacheHash() .AddProvider() .AddProcessor() .AddProcessor() .AddProcessor(); return services; } /// /// Adds the Umbraco runtime minifier /// /// /// /// public static IServiceCollection AddUmbracoRuntimeMinifier(this IServiceCollection services, IConfiguration configuration) { services.AddSmidge(configuration.GetSection(Core.Constants.Configuration.ConfigRuntimeMinification)); services.AddSmidgeNuglify(); return services; } private static void RemoveIntParamenterIfValueGreatherThen(IDictionary commands, string parameter, int maxValue) { if (commands.TryGetValue(parameter, out var command)) { if (int.TryParse(command, out var i)) { if (i > maxValue) { commands.Remove(parameter); } } } } /// /// Options for globally configuring MVC for Umbraco /// /// /// We generally don't want to change the global MVC settings since we want to be unobtrusive as possible but some /// global mods are needed - so long as they don't interfere with normal user usages of MVC. /// private class UmbracoMvcConfigureOptions : IConfigureOptions { // TODO: we can inject params with DI here public UmbracoMvcConfigureOptions() { } // TODO: we can configure global mvc options here if we need to public void Configure(MvcOptions options) { } } } }