diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/AbpAspNetCoreMvcUIBasicThemeModule.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/AbpAspNetCoreMvcUIBasicThemeModule.cs index 6076dfe0c0..b6ce0ba270 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/AbpAspNetCoreMvcUIBasicThemeModule.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/AbpAspNetCoreMvcUIBasicThemeModule.cs @@ -18,6 +18,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic services.Configure(options => { options.Themes.Add(); + + if (options.DefaultThemeName == null) + { + options.DefaultThemeName = BasicTheme.Name; + } }); services.Configure(options => diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/BasicTheme.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/BasicTheme.cs index cd9ce2d1e0..1301631bb2 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/BasicTheme.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/BasicTheme.cs @@ -3,8 +3,11 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic { + [ThemeName(Name)] public class BasicTheme : ITheme, ITransientDependency { + public const string Name = "Basic"; + public string DefaultLayout => "~/Views/Shared/_AppLayout.cshtml"; public string GetLayoutOrNull(string name) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/DefaultThemeManager.cs b/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/DefaultThemeManager.cs index de2341293d..2eb3130823 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/DefaultThemeManager.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/DefaultThemeManager.cs @@ -1,7 +1,5 @@ using System; -using System.Collections.Generic; using System.Linq; -using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; @@ -16,39 +14,39 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theming protected ThemingOptions Options { get; } - protected Lazy> Themes { get; } - - private readonly IHttpContextAccessor _httpContextAccessor; - public DefaultThemeManager( IOptions options, - IServiceProvider serviceProvider, - IHttpContextAccessor httpContextAccessor) + IServiceProvider serviceProvider) { - _httpContextAccessor = httpContextAccessor; ServiceProvider = serviceProvider; Options = options.Value; - Themes = new Lazy>(CreateThemeList, true); } protected virtual ITheme GetCurrentTheme() { - return Themes.Value.First(); - ////TODO: Temporary code! - - //var currentTheme = _httpContextAccessor.HttpContext.Items["_AbpCurrentTheme"] as ITheme; - //if (currentTheme != null) - //{ - // return currentTheme; - //} - - //_httpContextAccessor.HttpContext.Items["_AbpCurrentTheme"] = currentTheme = RandomHelper.GetRandomOf(Themes.Value.ToArray()); - //return currentTheme; + var themeInfo = GetCurrentThemeInfo(); + return (ITheme) ServiceProvider.GetRequiredService(themeInfo.ThemeType); } - protected virtual List CreateThemeList() + protected virtual ThemeInfo GetCurrentThemeInfo() { - return Options.Themes.Select(t => (ITheme) ServiceProvider.GetRequiredService(t)).ToList(); + if (!Options.Themes.Any()) + { + throw new AbpException($"No theme registered! Use {nameof(ThemingOptions)} to register themes."); + } + + if (Options.DefaultThemeName == null) + { + return Options.Themes.Values.First(); + } + + var themeInfo = Options.Themes.Values.FirstOrDefault(t => t.Name == Options.DefaultThemeName); + if (themeInfo == null) + { + throw new AbpException("Default theme is configured but it's not found in the registered themes: " + Options.DefaultThemeName); + } + + return themeInfo; } } } \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/ThemeDictionary.cs b/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/ThemeDictionary.cs new file mode 100644 index 0000000000..ed70153ef1 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/ThemeDictionary.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Theming +{ + public class ThemeDictionary : Dictionary + { + public ThemeInfo Add() + where TTheme : ITheme + { + return Add(typeof(TTheme)); + } + + public ThemeInfo Add(Type themeType) + { + if (ContainsKey(themeType)) + { + throw new AbpException("This theme is already added before: " + themeType.AssemblyQualifiedName); + } + + return this[themeType] = new ThemeInfo(themeType); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/ThemeInfo.cs b/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/ThemeInfo.cs new file mode 100644 index 0000000000..1a4c0f6566 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/ThemeInfo.cs @@ -0,0 +1,25 @@ +using System; +using JetBrains.Annotations; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Theming +{ + public class ThemeInfo + { + public Type ThemeType { get; } + + public string Name { get; } + + public ThemeInfo([NotNull] Type themeType) + { + Check.NotNull(themeType, nameof(themeType)); + + if (!typeof(ITheme).IsAssignableFrom(themeType)) + { + throw new AbpException($"Given {nameof(themeType)} ({themeType.AssemblyQualifiedName}) should be type of {typeof(ITheme).AssemblyQualifiedName}"); + } + + ThemeType = themeType; + Name = ThemeNameAttribute.GetName(themeType); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/ThemeNameAttribute.cs b/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/ThemeNameAttribute.cs new file mode 100644 index 0000000000..bb3208c6c1 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/ThemeNameAttribute.cs @@ -0,0 +1,24 @@ +using System; +using System.Linq; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Theming +{ + [AttributeUsage(AttributeTargets.Class)] + public class ThemeNameAttribute : Attribute + { + public string Name { get; set; } + + public ThemeNameAttribute(string name) + { + Name = name; + } + + public static string GetName(Type themeType) + { + return themeType + .GetCustomAttributes(true) + .OfType() + .FirstOrDefault()?.Name ?? themeType.Name; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/ThemingOptions.cs b/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/ThemingOptions.cs index dc6f81451b..58de144e88 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/ThemingOptions.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI/UI/Theming/ThemingOptions.cs @@ -1,14 +1,14 @@ -using Volo.Abp.Collections; - -namespace Volo.Abp.AspNetCore.Mvc.UI.Theming +namespace Volo.Abp.AspNetCore.Mvc.UI.Theming { public class ThemingOptions { - public TypeList Themes { get; } + public ThemeDictionary Themes { get; } + + public string DefaultThemeName { get; set; } public ThemingOptions() { - Themes = new TypeList(); + Themes = new ThemeDictionary(); } } }