mirror of https://github.com/abpframework/abp.git
15 changed files with 369 additions and 48 deletions
@ -1,38 +1,51 @@ |
|||
using System.Collections.Generic; |
|||
using System.Collections.Immutable; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace Volo.Abp.Features |
|||
{ |
|||
public class FeatureDefinitionContext : IFeatureDefinitionContext |
|||
{ |
|||
protected Dictionary<string, FeatureDefinition> Features { get; } |
|||
internal Dictionary<string, FeatureGroupDefinition> Groups { get; } |
|||
|
|||
public FeatureDefinitionContext(Dictionary<string, FeatureDefinition> features) |
|||
public FeatureDefinitionContext() |
|||
{ |
|||
Features = features; |
|||
Groups = new Dictionary<string, FeatureGroupDefinition>(); |
|||
} |
|||
|
|||
public virtual FeatureDefinition GetOrNull(string name) |
|||
public FeatureGroupDefinition AddGroup(string name, ILocalizableString displayName = null) |
|||
{ |
|||
return Features.GetOrDefault(name); |
|||
} |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
public virtual IReadOnlyList<FeatureDefinition> GetAll() |
|||
{ |
|||
return Features.Values.ToImmutableList(); |
|||
if (Groups.ContainsKey(name)) |
|||
{ |
|||
throw new AbpException($"There is already an existing permission group with name: {name}"); |
|||
} |
|||
|
|||
return Groups[name] = new FeatureGroupDefinition(name, displayName); |
|||
} |
|||
|
|||
public virtual void Add(params FeatureDefinition[] definitions) |
|||
public FeatureGroupDefinition GetGroupOrNull(string name) |
|||
{ |
|||
if (definitions.IsNullOrEmpty()) |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
if (!Groups.ContainsKey(name)) |
|||
{ |
|||
return; |
|||
return null; |
|||
} |
|||
|
|||
foreach (var definition in definitions) |
|||
return Groups[name]; |
|||
} |
|||
|
|||
public void RemoveGroup(string name) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
if (!Groups.ContainsKey(name)) |
|||
{ |
|||
Features[definition.Name] = definition; |
|||
throw new AbpException($"Undefined feature group: '{name}'."); |
|||
} |
|||
|
|||
Groups.Remove(name); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,108 @@ |
|||
using System.Collections.Generic; |
|||
using System.Collections.Immutable; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace Volo.Abp.Features |
|||
{ |
|||
public class FeatureGroupDefinition |
|||
{ |
|||
/// <summary>
|
|||
/// Unique name of the group.
|
|||
/// </summary>
|
|||
public string Name { get; } |
|||
|
|||
public Dictionary<string, object> Properties { get; } |
|||
|
|||
public ILocalizableString DisplayName |
|||
{ |
|||
get => _displayName; |
|||
set => _displayName = Check.NotNull(value, nameof(value)); |
|||
} |
|||
private ILocalizableString _displayName; |
|||
|
|||
public IReadOnlyList<FeatureDefinition> Features => _features.ToImmutableList(); |
|||
private readonly List<FeatureDefinition> _features; |
|||
|
|||
/// <summary>
|
|||
/// Gets/sets a key-value on the <see cref="Properties"/>.
|
|||
/// </summary>
|
|||
/// <param name="name">Name of the property</param>
|
|||
/// <returns>
|
|||
/// Returns the value in the <see cref="Properties"/> dictionary by given <see cref="name"/>.
|
|||
/// Returns null if given <see cref="name"/> is not present in the <see cref="Properties"/> dictionary.
|
|||
/// </returns>
|
|||
public object this[string name] |
|||
{ |
|||
get => Properties.GetOrDefault(name); |
|||
set => Properties[name] = value; |
|||
} |
|||
|
|||
protected internal FeatureGroupDefinition( |
|||
string name, |
|||
ILocalizableString displayName = null) |
|||
{ |
|||
Name = name; |
|||
DisplayName = displayName ?? new FixedLocalizableString(Name); |
|||
|
|||
Properties = new Dictionary<string, object>(); |
|||
_features = new List<FeatureDefinition>(); |
|||
} |
|||
|
|||
public virtual FeatureDefinition AddFeature( |
|||
string name, |
|||
string defaultValue = null, |
|||
ILocalizableString displayName = null, |
|||
ILocalizableString description = null, |
|||
bool isVisibleToClients = true) |
|||
{ |
|||
var feature = new FeatureDefinition( |
|||
name, |
|||
defaultValue, |
|||
displayName, |
|||
description, |
|||
isVisibleToClients |
|||
); |
|||
|
|||
_features.Add(feature); |
|||
|
|||
return feature; |
|||
} |
|||
|
|||
public virtual List<FeatureDefinition> GetFeaturesWithChildren() |
|||
{ |
|||
var features = new List<FeatureDefinition>(); |
|||
|
|||
foreach (var feature in _features) |
|||
{ |
|||
AddFeatureToListRecursively(features, feature); |
|||
} |
|||
|
|||
return features; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Sets a property in the <see cref="Properties"/> dictionary.
|
|||
/// This is a shortcut for nested calls on this object.
|
|||
/// </summary>
|
|||
public virtual FeatureGroupDefinition WithProperty(string key, object value) |
|||
{ |
|||
Properties[key] = value; |
|||
return this; |
|||
} |
|||
|
|||
private void AddFeatureToListRecursively(List<FeatureDefinition> features, FeatureDefinition feature) |
|||
{ |
|||
features.Add(feature); |
|||
|
|||
foreach (var child in feature.Children) |
|||
{ |
|||
AddFeatureToListRecursively(features, child); |
|||
} |
|||
} |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return $"[{nameof(FeatureGroupDefinition)} {Name}]"; |
|||
} |
|||
} |
|||
} |
|||
@ -1,9 +1,14 @@ |
|||
namespace Volo.Abp.Features |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace Volo.Abp.Features |
|||
{ |
|||
public interface IFeatureDefinitionContext |
|||
{ |
|||
FeatureDefinition GetOrNull(string name); |
|||
FeatureGroupDefinition AddGroup([NotNull] string name, ILocalizableString displayName = null); |
|||
|
|||
void Add(params FeatureDefinition[] definitions); |
|||
FeatureGroupDefinition GetGroupOrNull(string name); |
|||
|
|||
void RemoveGroup(string name); |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netcoreapp2.2</TargetFramework> |
|||
<LangVersion>latest</LangVersion> |
|||
<AssemblyName>Volo.Abp.Features.Tests</AssemblyName> |
|||
<PackageId>Volo.Abp.Features.Tests</PackageId> |
|||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" /> |
|||
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" /> |
|||
<ProjectReference Include="..\..\src\Volo.Abp.Features\Volo.Abp.Features.csproj" /> |
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,10 @@ |
|||
namespace Volo.Abp.Features |
|||
{ |
|||
public class AbpFeaturesTestBase : AbpIntegratedTest<AbpFeaturesTestModule> |
|||
{ |
|||
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) |
|||
{ |
|||
options.UseAutofac(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using Volo.Abp.Autofac; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.Features |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpFeaturesModule), |
|||
typeof(AbpTestBaseModule), |
|||
typeof(AbpAutofacModule) |
|||
)] |
|||
public class AbpFeaturesTestModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
using Shouldly; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.Features |
|||
{ |
|||
public class FeatureDefinitionManager_Tests : AbpFeaturesTestBase |
|||
{ |
|||
private readonly IFeatureDefinitionManager _featureDefinitionManager; |
|||
|
|||
public FeatureDefinitionManager_Tests() |
|||
{ |
|||
_featureDefinitionManager = GetRequiredService<IFeatureDefinitionManager>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Get_Defined_Features() |
|||
{ |
|||
_featureDefinitionManager.GetOrNull("BooleanTestFeature1").ShouldNotBeNull(); |
|||
_featureDefinitionManager.Get("BooleanTestFeature1").Name.ShouldBe("BooleanTestFeature1"); |
|||
|
|||
_featureDefinitionManager.GetOrNull("IntegerTestFeature1").ShouldNotBeNull(); |
|||
_featureDefinitionManager.Get("IntegerTestFeature1").Name.ShouldBe("IntegerTestFeature1"); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Not_Get_Undefined_Features() |
|||
{ |
|||
_featureDefinitionManager.GetOrNull("UndefinedFeature").ShouldBeNull(); |
|||
Assert.Throws<AbpException>(() => |
|||
{ |
|||
_featureDefinitionManager.Get("UndefinedFeature"); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
namespace Volo.Abp.Features |
|||
{ |
|||
public class TestFeatureDefinitionProvider : FeatureDefinitionProvider |
|||
{ |
|||
public override void Define(IFeatureDefinitionContext context) |
|||
{ |
|||
var group = context.AddGroup("Test Group"); |
|||
group.AddFeature("BooleanTestFeature1"); |
|||
group.AddFeature("IntegerTestFeature1", defaultValue: "1"); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue