Revise bundling system

pull/301/head
Halil ibrahim Kalkan 8 years ago
parent 1cb00b6662
commit 6b3668bf18

@ -1,13 +1,14 @@
@using Volo.Abp.AspNetCore.Mvc.AntiForgery
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.MainNavbar
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.PageAlerts
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components
@inject IAbpAntiForgeryManager AbpAntiForgeryManager
@inject IBrandingProvider BrandingProvider
@{
Layout = null;
AbpAntiForgeryManager.SetCookie();
var containerClass = ViewBag.FluidLayout == true ? "container-fluid" : "container";
var containerClass = ViewBag.FluidLayout == true ? "container-fluid" : "container"; //TODO: Better and type-safe options
}
<!DOCTYPE html>
@ -19,7 +20,7 @@
<title>@(ViewBag.Title == null ? BrandingProvider.AppName : ViewBag.Title)</title>
<vc:abp-style-bundle name="GlobalStyles"></vc:abp-style-bundle>
<abp-style-bundle name="@StandardBundles.Styles.Global" />
<link rel="stylesheet" type="text/css" href="~/views/shared/_AppLayout.css" />
@ -30,12 +31,11 @@
@(await Component.InvokeAsync<MainNavbarViewComponent>())
<div class="@containerClass">
@* TODO: Create option to select 'container' or 'container-fluid' *@
@(await Component.InvokeAsync<PageAlertsViewComponent>())
@RenderBody()
</div>
<vc:abp-script-bundle name="GlobalScripts"></vc:abp-script-bundle>
<abp-script-bundle name="@StandardBundles.Scripts.Global" />
<script type="text/javascript" src="~/Abp/ApplicationConfigurationScript"></script>
<script type="text/javascript" src="~/Abp/ServiceProxyScript"></script>

@ -1,6 +1,6 @@
@using Volo.Abp.AspNetCore.Mvc.AntiForgery
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.MainNavbar
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.PageAlerts
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components
@inject IAbpAntiForgeryManager AbpAntiForgeryManager
@inject IBrandingProvider BrandingProvider
@ -18,7 +18,7 @@
<title>@(ViewBag.Title == null ? BrandingProvider.AppName : ViewBag.Title)</title>
<vc:abp-style-bundle name="GlobalStyles"></vc:abp-style-bundle>
<abp-style-bundle name="@StandardBundles.Styles.Global" />
<link rel="stylesheet" type="text/css" href="~/views/shared/_AppLayout.css" />
@ -31,7 +31,7 @@
@RenderBody()
</div>
<vc:abp-script-bundle name="GlobalScripts"></vc:abp-script-bundle>
<abp-script-bundle name="@StandardBundles.Scripts.Global" />
<script type="text/javascript" src="~/Abp/ApplicationConfigurationScript"></script>
<script type="text/javascript" src="~/Abp/ServiceProxyScript"></script>

@ -1,6 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
@ -22,42 +23,13 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared
{
options
.StyleBundles
.Add("GlobalStyles")
.AddFiles(
"/libs/font-awesome/css/font-awesome.css",
"/libs/bootstrap/css/bootstrap.css",
"/libs/datatables.net-bs4/css/dataTables.bootstrap4.css",
"/libs/toastr/toastr.min.css",
"/libs/abp/aspnetcore.mvc.ui.theme.shared/datatables/datatables.css"
);
.Add(StandardBundles.Styles.Global)
.AddContributors(typeof(SharedThemeGlobalStyleContributor));
options
.ScriptBundles
.Add("GlobalScripts")
.AddFiles(
"/libs/jquery/jquery.js",
"/libs/bootstrap/js/bootstrap.bundle.js",
"/libs/jquery-validation/jquery.validate.js",
"/libs/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
"/libs/jquery-form/jquery.form.min.js",
"/libs/datatables.net/js/jquery.dataTables.js",
"/libs/datatables.net-bs4/js/dataTables.bootstrap4.js",
"/libs/sweetalert/sweetalert.min.js",
"/libs/toastr/toastr.min.js",
"/libs/abp/core/abp.js",
"/libs/abp/jquery/abp.dom.js",
"/libs/abp/jquery/abp.ajax.js",
"/libs/abp/jquery/abp.resource-loader.js",
"/libs/abp/aspnetcore.mvc.ui.theme.shared/jquery/jquery-extensions.js",
"/libs/abp/aspnetcore.mvc.ui.theme.shared/jquery-form/jquery-form-extensions.js",
"/libs/abp/aspnetcore.mvc.ui.theme.shared/bootstrap/dom-event-handlers.js",
"/libs/abp/aspnetcore.mvc.ui.theme.shared/bootstrap/modal-manager.js",
"/libs/abp/aspnetcore.mvc.ui.theme.shared/datatables/datatables-extensions.js",
"/libs/abp/aspnetcore.mvc.ui.theme.shared/sweetalert/abp-sweetalert.js",
"/libs/abp/aspnetcore.mvc.ui.theme.shared/toastr/abp-toastr.js"
);
.Add(StandardBundles.Scripts.Global)
.AddContributors(typeof(SharedThemeGlobalScriptContributor));
});
services.AddAssemblyOf<AbpAspNetCoreMvcUiThemeSharedModule>();

@ -0,0 +1,37 @@
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling.Libraries.Bootstrap;
using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling
{
[DependsOn(
typeof(BootstrapScriptBundleContributor)
)]
public class SharedThemeGlobalScriptContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.AddRange(new[]
{ //TODO: Create seperated contributors!
"/libs/jquery-validation/jquery.validate.js",
"/libs/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
"/libs/jquery-form/jquery.form.min.js",
"/libs/datatables.net/js/jquery.dataTables.js",
"/libs/datatables.net-bs4/js/dataTables.bootstrap4.js",
"/libs/sweetalert/sweetalert.min.js",
"/libs/toastr/toastr.min.js",
"/libs/abp/core/abp.js",
"/libs/abp/jquery/abp.dom.js",
"/libs/abp/jquery/abp.ajax.js",
"/libs/abp/jquery/abp.resource-loader.js",
"/libs/abp/aspnetcore.mvc.ui.theme.shared/jquery/jquery-extensions.js",
"/libs/abp/aspnetcore.mvc.ui.theme.shared/jquery-form/jquery-form-extensions.js",
"/libs/abp/aspnetcore.mvc.ui.theme.shared/bootstrap/dom-event-handlers.js",
"/libs/abp/aspnetcore.mvc.ui.theme.shared/bootstrap/modal-manager.js",
"/libs/abp/aspnetcore.mvc.ui.theme.shared/datatables/datatables-extensions.js",
"/libs/abp/aspnetcore.mvc.ui.theme.shared/sweetalert/abp-sweetalert.js",
"/libs/abp/aspnetcore.mvc.ui.theme.shared/toastr/abp-toastr.js"
});
}
}
}

@ -0,0 +1,23 @@
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling.Libraries.Bootstrap;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling.Libraries.DatatablesNetBs4;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling.Libraries.FontAwesome;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling.Libraries.Toastr;
using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling
{
[DependsOn(
typeof(BootstrapStyleBundleContributor),
typeof(FontAwesomeStyleBundleContributor),
typeof(ToastrStyleBundleContributor),
typeof(DatatablesNetBs4StyleBundleContributor)
)]
public class SharedThemeGlobalStyleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.Add("/libs/abp/aspnetcore.mvc.ui.theme.shared/datatables/datatables.css");
}
}
}

@ -0,0 +1,15 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling
{
public class StandardBundles
{
public static class Styles
{
public static string Global = "Global";
}
public static class Scripts
{
public static string Global = "Global";
}
}
}

@ -1,12 +1,40 @@
using Volo.Abp.AspNetCore.Mvc.UI.Bundling.Contributors;
using System;
using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{
public static class BundleConfigurationExtensions
{
public static void AddFiles(this BundleConfiguration bundleConfiguration, params string[] files)
public static BundleConfiguration AddFiles(this BundleConfiguration bundleConfiguration, params string[] files)
{
bundleConfiguration.Contributors.Add(new SimpleBundleContributor(files));
bundleConfiguration.Contributors.AddFiles(files);
return bundleConfiguration;
}
public static BundleConfiguration AddContributors(this BundleConfiguration bundleConfiguration, params IBundleContributor[] contributors)
{
if (!contributors.IsNullOrEmpty())
{
foreach (var contributor in contributors)
{
bundleConfiguration.Contributors.Add(contributor);
}
}
return bundleConfiguration;
}
public static BundleConfiguration AddContributors(this BundleConfiguration bundleConfiguration, params Type[] contributorTypes)
{
if (!contributorTypes.IsNullOrEmpty())
{
foreach (var contributorType in contributorTypes)
{
bundleConfiguration.Contributors.Add(contributorType);
}
}
return bundleConfiguration;
}
}
}

@ -4,12 +4,12 @@
{
public string Name { get; }
public BundleContributorList Contributors { get; }
public BundleContributorCollection Contributors { get; }
public BundleConfiguration(string name)
{
Name = name;
Contributors = new BundleContributorList();
Contributors = new BundleContributorCollection();
}
}
}

@ -4,11 +4,11 @@ using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{
public class BundleCollection
public class BundleConfigurationCollection
{
private readonly ConcurrentDictionary<string, BundleConfiguration> _bundleContributors;
public BundleCollection()
public BundleConfigurationCollection()
{
_bundleContributors = new ConcurrentDictionary<string, BundleConfiguration>();
}
@ -30,6 +30,12 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
return _bundleContributors[bundleName];
}
public BundleConfiguration GetOrNull(string bundleName)
{
_bundleContributors.TryGetValue(bundleName, out var bundleConfiguration);
return bundleConfiguration;
}
public BundleConfiguration GetOrAdd(string bundleName)
{
return GetOrAdd(bundleName, c => { });
@ -47,21 +53,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
});
}
public List<string> GetFiles(string bundleName)
{
CheckBundle(bundleName);
var files = new List<string>();
var bundleConfiguration = _bundleContributors[bundleName];
foreach (var contributor in bundleConfiguration.Contributors)
{
contributor.Contribute(files);
}
return files;
}
private void CheckBundle(string bundleName)
{
if (!_bundleContributors.ContainsKey(bundleName))

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using Volo.Abp.AspNetCore.Mvc.UI.Theming;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{
public class BundleConfigurationContext : IBundleConfigurationContext
{
public List<string> Files { get; }
public ITheme Theme { get; }
public IServiceProvider ServiceProvider { get; }
public BundleConfigurationContext(List<string> files, ITheme theme, IServiceProvider serviceProvider)
{
Files = files;
Theme = theme;
ServiceProvider = serviceProvider;
}
}
}

@ -0,0 +1,7 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{
public abstract class BundleContributor : IBundleContributor
{
public abstract void ConfigureBundle(BundleConfigurationContext context);
}
}

@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using JetBrains.Annotations;
using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{
public class BundleContributorCollection
{
private readonly List<IBundleContributor> _contributors;
public BundleContributorCollection()
{
_contributors = new List<IBundleContributor>();
}
public void Add(IBundleContributor contributor)
{
_contributors.Add(contributor);
}
public void Add<TContributor>()
where TContributor : IBundleContributor, new()
{
Add(typeof(TContributor));
}
public void Add([NotNull] Type contributorType)
{
Check.NotNull(contributorType, nameof(contributorType));
if (!typeof(IBundleContributor).IsAssignableFrom(contributorType))
{
throw new AbpException($"Given {nameof(contributorType)} ({contributorType.AssemblyQualifiedName}) should implement the {typeof(IBundleContributor).AssemblyQualifiedName} interface!");
}
if (IsAlreadyAdded(contributorType))
{
throw new AbpException($"Given {nameof(contributorType)} ({contributorType.AssemblyQualifiedName}) is already added before! If you want to ensure that a contributor is added, create your own contributor and depend on the contributor you want to ensure that it's added.");
}
AddWithDependencies(contributorType);
}
public IReadOnlyList<IBundleContributor> GetAll()
{
return _contributors.ToImmutableList();
}
private bool IsAlreadyAdded(Type contributorType)
{
return _contributors.Any(c => c.GetType() == contributorType);
}
private void AddWithDependencies(Type contributorType)
{
var dependsOnAttributes = contributorType
.GetCustomAttributes(true)
.OfType<IDependedTypesProvider>()
.ToList();
foreach (var dependsOnAttribute in dependsOnAttributes)
{
foreach (var dependedType in dependsOnAttribute.GetDependedTypes())
{
AddWithDependencies(dependedType); //Recursive call
if (!IsAlreadyAdded(dependedType))
{
AddInstanceToContributors(dependedType);
}
}
}
AddInstanceToContributors(contributorType);
}
private void AddInstanceToContributors(Type contributorType)
{
try
{
_contributors.Add((IBundleContributor)Activator.CreateInstance(contributorType));
}
catch (Exception ex)
{
throw new AbpException($"Can not instantiate {contributorType.AssemblyQualifiedName}", ex);
}
}
}
}

@ -1,9 +0,0 @@
using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{
public class BundleContributorList : List<IBundleContributor>
{
}
}

@ -0,0 +1,10 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{
public static class BundleContributorListExtensions
{
public static void AddFiles(this BundleContributorCollection contributors, params string[] files)
{
contributors.Add(new SimpleBundleContributor(files));
}
}
}

@ -2,26 +2,35 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Mvc.UI.Theming;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{
//TODO: Do not make this singleton (since it's using scoped services), instead separate a singleton bundlecache!
public class BundleManager : IBundleManager, ISingletonDependency
{
private readonly BundlingOptions _options;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly IBundler _bundler;
private readonly IThemeManager _themeManager;
private readonly IServiceProvider _serviceProvider;
private readonly ConcurrentDictionary<string, string> _cache;
public BundleManager(
IOptions<BundlingOptions> options,
IHostingEnvironment hostingEnvironment,
IBundler bundler)
IBundler bundler,
IThemeManager themeManager,
IServiceProvider serviceProvider)
{
_hostingEnvironment = hostingEnvironment;
_bundler = bundler;
_themeManager = themeManager;
_serviceProvider = serviceProvider;
_options = options.Value;
_cache = new ConcurrentDictionary<string, string>();
@ -29,12 +38,12 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
public List<string> GetStyleBundleFiles(string bundleName)
{
return _options.StyleBundles.GetFiles(bundleName);
return GetFiles(_options.StyleBundles.Get(bundleName));
}
public List<string> GetScriptBundleFiles(string bundleName)
{
return _options.ScriptBundles.GetFiles(bundleName);
return GetFiles(_options.ScriptBundles.Get(bundleName));
}
public void CreateStyleBundle(string bundleName, Action<BundleConfiguration> configureAction)
@ -46,5 +55,27 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{
_options.ScriptBundles.GetOrAdd(bundleName, configureAction);
}
protected virtual List<string> GetFiles(BundleConfiguration bundleConfiguration)
{
//TODO: Caching, Bundling & Minifying!
using (var scope = _serviceProvider.CreateScope())
{
var context = new BundleConfigurationContext(
new List<string>(),
_themeManager.CurrentTheme,
scope.ServiceProvider
);
foreach (var contributor in bundleConfiguration.Contributors.GetAll())
{
contributor.ConfigureBundle(context);
}
return context.Files;
}
}
}
}

@ -2,14 +2,14 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{
public class BundlingOptions
{
public BundleCollection StyleBundles { get; set; }
public BundleConfigurationCollection StyleBundles { get; set; }
public BundleCollection ScriptBundles { get; set; }
public BundleConfigurationCollection ScriptBundles { get; set; }
public BundlingOptions()
{
StyleBundles = new BundleCollection();
ScriptBundles = new BundleCollection();
StyleBundles = new BundleConfigurationCollection();
ScriptBundles = new BundleConfigurationCollection();
}
}
}

@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.Contributors
{
public class SimpleBundleContributor : IBundleContributor
{
public string[] Files { get; }
public SimpleBundleContributor(params string[] files)
{
Files = files ?? Array.Empty<string>();
}
public void Contribute(List<string> files)
{
files.AddRange(Files);
}
}
}

@ -0,0 +1,13 @@
using System.Collections.Generic;
using Volo.Abp.AspNetCore.Mvc.UI.Theming;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{
public interface IBundleConfigurationContext : IServiceProviderAccessor
{
List<string> Files { get; }
ITheme Theme { get; }
}
}

@ -1,9 +1,7 @@
using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{
public interface IBundleContributor
{
void Contribute(List<string> files);
void ConfigureBundle(BundleConfigurationContext context);
}
}

@ -0,0 +1,14 @@
using Volo.Abp.AspNetCore.Mvc.UI.Bundling.Libraries.JQuery;
using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.Libraries.Bootstrap
{
[DependsOn(typeof(JQueryScriptBundleContributor))]
public class BootstrapScriptBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.Add("/libs/bootstrap/js/bootstrap.bundle.js");
}
}
}

@ -0,0 +1,10 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.Libraries.Bootstrap
{
public class BootstrapStyleBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.Add("/libs/bootstrap/css/bootstrap.css");
}
}
}

@ -0,0 +1,14 @@
using Volo.Abp.AspNetCore.Mvc.UI.Bundling.Libraries.Bootstrap;
using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.Libraries.DatatablesNetBs4
{
[DependsOn(typeof(BootstrapStyleBundleContributor))]
public class DatatablesNetBs4StyleBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.Add("/libs/datatables.net-bs4/css/dataTables.bootstrap4.css");
}
}
}

@ -0,0 +1,10 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.Libraries.FontAwesome
{
public class FontAwesomeStyleBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.Add("/libs/font-awesome/css/font-awesome.css");
}
}
}

@ -0,0 +1,10 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.Libraries.JQuery
{
public class JQueryScriptBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.Add("/libs/jquery/jquery.js");
}
}
}

@ -0,0 +1,10 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.Libraries.Toastr
{
public class ToastrStyleBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.Add("/libs/toastr/toastr.min.css");
}
}
}

@ -0,0 +1,19 @@
using System;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{
public class SimpleBundleContributor : BundleContributor
{
public string[] Files { get; }
public SimpleBundleContributor(params string[] files)
{
Files = files ?? Array.Empty<string>();
}
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.AddRange(Files);
}
}
}

@ -1,21 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
namespace Volo.Abp.AspNetCore.Mvc.Views.Shared.Components.AbpScriptBundle
{
public class AbpScriptBundleViewComponent : AbpViewComponent
{
private readonly IBundleManager _bundleManager;
public AbpScriptBundleViewComponent(IBundleManager bundleManager)
{
_bundleManager = bundleManager;
}
public IViewComponentResult Invoke(string name)
{
var files = _bundleManager.GetScriptBundleFiles(name);
return View(files);
}
}
}

@ -1,5 +0,0 @@
@model List<string>
@foreach (var scriptFile in Model)
{
<script src="@scriptFile" type="text/javascript"></script>
}

@ -1,21 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
namespace Volo.Abp.AspNetCore.Mvc.Views.Shared.Components.AbpStyleBundle
{
public class AbpStyleBundleViewComponent : AbpViewComponent
{
private readonly IBundleManager _bundleManager;
public AbpStyleBundleViewComponent(IBundleManager bundleManager)
{
_bundleManager = bundleManager;
}
public IViewComponentResult Invoke(string name)
{
var files = _bundleManager.GetStyleBundleFiles(name);
return View(files);
}
}
}

@ -1,5 +0,0 @@
@model List<string>
@foreach (var styleFile in Model)
{
<link rel="stylesheet" type="text/css" href="@styleFile" />
}

@ -10,10 +10,6 @@
<RootNamespace>Volo.Abp.AspNetCore.Mvc</RootNamespace>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Views\**\*.cshtml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NUglify" Version="1.5.11" />
</ItemGroup>

@ -50,8 +50,7 @@ namespace System.Collections.Generic
/// <returns>Value if found, default if can not found.</returns>
public static TValue GetOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
{
TValue obj;
return dictionary.TryGetValue(key, out obj) ? obj : default;
return dictionary.TryGetValue(key, out var obj) ? obj : default;
}
/// <summary>
@ -64,8 +63,7 @@ namespace System.Collections.Generic
/// <returns>Value if found, default if can not found.</returns>
public static TValue GetOrDefault<TKey, TValue>(this IReadOnlyDictionary<TKey, TValue> dictionary, TKey key)
{
TValue obj;
return dictionary.TryGetValue(key, out obj) ? obj : default;
return dictionary.TryGetValue(key, out var obj) ? obj : default;
}
/// <summary>

@ -22,11 +22,11 @@ namespace Volo.Abp.Modularity
var dependencyDescriptors = moduleType
.GetCustomAttributes()
.OfType<IDependedModuleTypesProvider>();
.OfType<IDependedTypesProvider>();
foreach (var descriptor in dependencyDescriptors)
{
foreach (var dependedModuleType in descriptor.GetDependedModuleTypes())
foreach (var dependedModuleType in descriptor.GetDependedTypes())
{
dependencies.AddIfNotContains(dependedModuleType);
}

@ -4,30 +4,22 @@ using JetBrains.Annotations;
namespace Volo.Abp.Modularity
{
/// <summary>
/// Used to define dependencies of an ABP module to other modules.
/// It should be used for a class implements <see cref="IAbpModule"/>.
/// Used to define dependencies of a type.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class DependsOnAttribute : Attribute, IDependedModuleTypesProvider
public class DependsOnAttribute : Attribute, IDependedTypesProvider
{
/// <summary>
/// Types of depended modules.
/// </summary>
[NotNull]
public Type[] DependedModuleTypes { get; }
public Type[] DependedTypes { get; }
/// <summary>
/// Used to define dependencies of an ABP module to other modules.
/// </summary>
/// <param name="dependedModuleTypes">Types of depended modules</param>
public DependsOnAttribute(params Type[] dependedModuleTypes)
public DependsOnAttribute(params Type[] dependedTypes)
{
DependedModuleTypes = dependedModuleTypes ?? new Type[0];
DependedTypes = dependedTypes ?? new Type[0];
}
public virtual Type[] GetDependedModuleTypes()
public virtual Type[] GetDependedTypes()
{
return DependedModuleTypes;
return DependedTypes;
}
}
}

@ -3,9 +3,9 @@ using JetBrains.Annotations;
namespace Volo.Abp.Modularity
{
public interface IDependedModuleTypesProvider
public interface IDependedTypesProvider
{
[NotNull]
Type[] GetDependedModuleTypes();
Type[] GetDependedTypes();
}
}

@ -1,4 +1,5 @@
@{
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling
@{
Layout = null;
var title = "ABP Bootstrap Demo";
if (ViewData["Title"] != null)
@ -16,8 +17,8 @@
<title>@title</title>
<vc:abp-style-bundle name="GlobalStyles"></vc:abp-style-bundle>
<link href="~/css/demo.min.css" rel="stylesheet" /> @* TODO: Add to the GlobalStyles bundle! *@
<abp-style-bundle name="@StandardBundles.Styles.Global" />
<link href="~/css/demo.min.css" rel="stylesheet" />
@RenderSection("styles", false)
</head>
@ -27,7 +28,7 @@
@RenderBody()
</div>
<vc:abp-script-bundle name="GlobalScripts"></vc:abp-script-bundle>
<abp-script-bundle name="@StandardBundles.Scripts.Global" />
@RenderSection("scripts", false)

Loading…
Cancel
Save