Implemented feature management domain module and efcore integration

pull/877/head
Halil ibrahim Kalkan 6 years ago
parent fb656134d8
commit 287f71d805

@ -14,9 +14,9 @@ namespace Volo.Abp.FeatureManagement.EntityFrameworkCore
{
context.Services.AddAbpDbContext<FeatureManagementDbContext>(options =>
{
/* Add custom repositories here. Example:
* options.AddRepository<Question, EfCoreQuestionRepository>();
*/
options.AddDefaultRepositories<IFeatureManagementDbContext>();
options.AddRepository<FeatureValue, EfCoreFeatureValueRepository>();
});
}
}

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace Volo.Abp.FeatureManagement.EntityFrameworkCore
{
public class EfCoreFeatureValueRepository : EfCoreRepository<IFeatureManagementDbContext, FeatureValue, Guid>, IFeatureValueRepository
{
public EfCoreFeatureValueRepository(IDbContextProvider<IFeatureManagementDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public async Task<FeatureValue> FindAsync(string name, string providerName, string providerKey)
{
return await DbSet
.FirstOrDefaultAsync(
s => s.Name == name && s.ProviderName == providerName && s.ProviderKey == providerKey
);
}
public async Task<List<FeatureValue>> GetListAsync(string providerName, string providerKey)
{
return await DbSet
.Where(
s => s.ProviderName == providerName && s.ProviderKey == providerKey
).ToListAsync();
}
}
}

@ -11,6 +11,8 @@ namespace Volo.Abp.FeatureManagement.EntityFrameworkCore
public static string Schema { get; set; } = FeatureManagementConsts.DefaultDbSchema;
public DbSet<FeatureValue> FeatureValues { get; set; }
public FeatureManagementDbContext(DbContextOptions<FeatureManagementDbContext> options)
: base(options)
{

@ -15,23 +15,17 @@ namespace Volo.Abp.FeatureManagement.EntityFrameworkCore
optionsAction?.Invoke(options);
/* Configure all entities here. Example:
builder.Entity<Question>(b =>
builder.Entity<FeatureValue>(b =>
{
//Configure table & schema name
//b.ToTable(options.TablePrefix + "Questions", options.Schema);
//Properties
//b.Property(q => q.Title).IsRequired().HasMaxLength(QuestionConsts.MaxTitleLength);
//Configure relations
//b.HasMany(question => question.Tags).WithOne().HasForeignKey(qt => qt.QuestionId);
b.ToTable(options.TablePrefix + "FeatureValues", options.Schema);
b.Property(x => x.Name).HasMaxLength(FeatureValueConsts.MaxNameLength).IsRequired();
b.Property(x => x.Value).HasMaxLength(FeatureValueConsts.MaxValueLength).IsRequired();
b.Property(x => x.ProviderName).HasMaxLength(FeatureValueConsts.MaxProviderNameLength);
b.Property(x => x.ProviderKey).HasMaxLength(FeatureValueConsts.MaxProviderKeyLength);
//Configure indexes
//b.HasIndex(q => q.CreationTime);
b.HasIndex(x => new { x.Name, x.ProviderName, x.ProviderKey });
});
*/
}
}
}

@ -1,4 +1,5 @@
using Volo.Abp.Data;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
namespace Volo.Abp.FeatureManagement.EntityFrameworkCore
@ -6,8 +7,6 @@ namespace Volo.Abp.FeatureManagement.EntityFrameworkCore
[ConnectionStringName("AbpFeatureManagement")]
public interface IFeatureManagementDbContext : IEfCoreDbContext
{
/* Add DbSet for each Aggregate Root here. Example:
* DbSet<Question> Questions { get; }
*/
DbSet<FeatureValue> FeatureValues { get; set; }
}
}

@ -1,6 +1,4 @@
using Abp.FeatureManagement;
namespace Volo.Abp.FeatureManagement
namespace Volo.Abp.FeatureManagement
{
public abstract class FeatureManagementDomainTestBase : FeatureManagementTestBase<AbpFeatureManagementDomainTestModule>
{

@ -1,5 +1,4 @@
using Abp.FeatureManagement;
using Microsoft.Data.Sqlite;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;

@ -0,0 +1,7 @@
namespace Volo.Abp.FeatureManagement.EntityFrameworkCore
{
public class FeatureValueRepositoryTests : FeatureValueRepository_Tests<AbpFeatureManagementEntityFrameworkCoreTestModule>
{
}
}

@ -1,9 +0,0 @@
using Abp.FeatureManagement;
namespace Volo.Abp.FeatureManagement.EntityFrameworkCore
{
public class MyEntityRepository_Tests : MyEntityRepository_Tests<AbpFeatureManagementEntityFrameworkCoreTestModule>
{
}
}

@ -1,7 +0,0 @@
namespace Abp.FeatureManagement.MongoDB
{
public class MyEntityRepository_Tests : MyEntityRepository_Tests<AbpFeatureManagementMongoDbTestModule>
{
}
}

@ -1,10 +1,8 @@
using Mongo2Go;
using Volo.Abp;
using Volo.Abp.Data;
using Volo.Abp.FeatureManagement.MongoDB;
using Volo.Abp.Modularity;
namespace Abp.FeatureManagement.MongoDB
namespace Volo.Abp.FeatureManagement.MongoDB
{
[DependsOn(
typeof(AbpFeatureManagementTestBaseModule),

@ -0,0 +1,7 @@
namespace Volo.Abp.FeatureManagement.MongoDB
{
public class FeatureValueRepositoryTests : FeatureValueRepository_Tests<AbpFeatureManagementMongoDbTestModule>
{
}
}

@ -1,24 +0,0 @@
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
namespace Abp.FeatureManagement
{
public class FeatureManagementTestDataBuilder : ITransientDependency
{
private readonly IGuidGenerator _guidGenerator;
private FeatureManagementTestData _testData;
public FeatureManagementTestDataBuilder(
IGuidGenerator guidGenerator,
FeatureManagementTestData testData)
{
_guidGenerator = guidGenerator;
_testData = testData;
}
public void Build()
{
}
}
}

@ -1,16 +0,0 @@
using System.Threading.Tasks;
using Volo.Abp.Modularity;
using Xunit;
namespace Abp.FeatureManagement
{
public abstract class MyEntityRepository_Tests<TStartupModule> : FeatureManagementTestBase<TStartupModule>
where TStartupModule : IAbpModule
{
[Fact]
public async Task Test1()
{
}
}
}

@ -1,11 +1,10 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization;
using Volo.Abp.Autofac;
using Volo.Abp.FeatureManagement;
using Volo.Abp.Modularity;
namespace Abp.FeatureManagement
namespace Volo.Abp.FeatureManagement
{
[DependsOn(
typeof(AbpAutofacModule),
@ -18,6 +17,14 @@ namespace Abp.FeatureManagement
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAlwaysAllowAuthorization();
Configure<FeatureManagementOptions>(options =>
{
options.Providers.InsertBefore(
typeof(TenantFeatureManagementProvider),
typeof(EditionFeatureManagementProvider)
);
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)

@ -0,0 +1,14 @@
namespace Volo.Abp.FeatureManagement
{
public class EditionFeatureManagementProvider : FeatureManagementProvider
{
public const string ProviderName = "Edition";
public override string Name => ProviderName;
public EditionFeatureManagementProvider(IFeatureManagementStore store)
: base(store)
{
}
}
}

@ -1,7 +1,6 @@
using Volo.Abp;
using Volo.Abp.Modularity;
using Volo.Abp.Modularity;
namespace Abp.FeatureManagement
namespace Volo.Abp.FeatureManagement
{
public abstract class FeatureManagementTestBase<TStartupModule> : AbpIntegratedTest<TStartupModule>
where TStartupModule : IAbpModule

@ -1,6 +1,6 @@
using Volo.Abp.DependencyInjection;
namespace Abp.FeatureManagement
namespace Volo.Abp.FeatureManagement
{
public class FeatureManagementTestData : ISingletonDependency
{

@ -0,0 +1,186 @@
using Volo.Abp.DependencyInjection;
using Volo.Abp.Features;
using Volo.Abp.Guids;
namespace Volo.Abp.FeatureManagement
{
public class FeatureManagementTestDataBuilder : ITransientDependency
{
private readonly IFeatureValueRepository _featureValueRepository;
private readonly IGuidGenerator _guidGenerator;
private readonly FeatureManagementTestData _testData;
public FeatureManagementTestDataBuilder(
IGuidGenerator guidGenerator,
FeatureManagementTestData testData,
IFeatureValueRepository featureValueRepository)
{
_guidGenerator = guidGenerator;
_testData = testData;
_featureValueRepository = featureValueRepository;
}
public void Build()
{
// "Regular" edition features /////////////////////////////////////
//SocialLogins
_featureValueRepository.Insert(
new FeatureValue(
_guidGenerator.Create(),
TestFeatureDefinitionProvider.SocialLogins,
true.ToString().ToLowerInvariant(),
EditionFeatureManagementProvider.ProviderName,
TestEditionNames.Regular
)
);
//UserCount
_featureValueRepository.Insert(
new FeatureValue(
_guidGenerator.Create(),
TestFeatureDefinitionProvider.UserCount,
"10",
EditionFeatureManagementProvider.ProviderName,
TestEditionNames.Regular
)
);
//ProjectCount
_featureValueRepository.Insert(
new FeatureValue(
_guidGenerator.Create(),
TestFeatureDefinitionProvider.ProjectCount,
"1",
EditionFeatureManagementProvider.ProviderName,
TestEditionNames.Regular
)
);
// "Enterprise" edition features //////////////////////////////////
//SocialLogins
_featureValueRepository.Insert(
new FeatureValue(
_guidGenerator.Create(),
TestFeatureDefinitionProvider.SocialLogins,
true.ToString().ToLowerInvariant(),
EditionFeatureManagementProvider.ProviderName,
TestEditionNames.Enterprise
)
);
//EmailSupport
_featureValueRepository.Insert(
new FeatureValue(
_guidGenerator.Create(),
TestFeatureDefinitionProvider.EmailSupport,
true.ToString().ToLowerInvariant(),
EditionFeatureManagementProvider.ProviderName,
TestEditionNames.Enterprise
)
);
//UserCount
_featureValueRepository.Insert(
new FeatureValue(
_guidGenerator.Create(),
TestFeatureDefinitionProvider.UserCount,
"20",
EditionFeatureManagementProvider.ProviderName,
TestEditionNames.Enterprise
)
);
//ProjectCount
_featureValueRepository.Insert(
new FeatureValue(
_guidGenerator.Create(),
TestFeatureDefinitionProvider.ProjectCount,
"3",
EditionFeatureManagementProvider.ProviderName,
TestEditionNames.Enterprise
)
);
//BackupCount
_featureValueRepository.Insert(
new FeatureValue(
_guidGenerator.Create(),
TestFeatureDefinitionProvider.BackupCount,
"5",
EditionFeatureManagementProvider.ProviderName,
TestEditionNames.Enterprise
)
);
// "Ultimate" edition features ////////////////////////////////////
//SocialLogins
_featureValueRepository.Insert(
new FeatureValue(
_guidGenerator.Create(),
TestFeatureDefinitionProvider.SocialLogins,
true.ToString().ToLowerInvariant(),
EditionFeatureManagementProvider.ProviderName,
TestEditionNames.Enterprise
)
);
//EmailSupport
_featureValueRepository.Insert(
new FeatureValue(
_guidGenerator.Create(),
TestFeatureDefinitionProvider.EmailSupport,
true.ToString().ToLowerInvariant(),
EditionFeatureManagementProvider.ProviderName,
TestEditionNames.Enterprise
)
);
//EmailSupport
_featureValueRepository.Insert(
new FeatureValue(
_guidGenerator.Create(),
TestFeatureDefinitionProvider.DailyAnalysis,
true.ToString().ToLowerInvariant(),
EditionFeatureManagementProvider.ProviderName,
TestEditionNames.Enterprise
)
);
//UserCount
_featureValueRepository.Insert(
new FeatureValue(
_guidGenerator.Create(),
TestFeatureDefinitionProvider.UserCount,
"100",
EditionFeatureManagementProvider.ProviderName,
TestEditionNames.Enterprise
)
);
//ProjectCount
_featureValueRepository.Insert(
new FeatureValue(
_guidGenerator.Create(),
TestFeatureDefinitionProvider.ProjectCount,
"10",
EditionFeatureManagementProvider.ProviderName,
TestEditionNames.Enterprise
)
);
//BackupCount
_featureValueRepository.Insert(
new FeatureValue(
_guidGenerator.Create(),
TestFeatureDefinitionProvider.BackupCount,
"10",
EditionFeatureManagementProvider.ProviderName,
TestEditionNames.Enterprise
)
);
}
}
}

@ -0,0 +1,60 @@
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Modularity;
using Xunit;
namespace Volo.Abp.FeatureManagement
{
public abstract class FeatureValueRepository_Tests<TStartupModule> : FeatureManagementTestBase<TStartupModule>
where TStartupModule : IAbpModule
{
protected IFeatureValueRepository Repository { get; set; }
protected FeatureValueRepository_Tests()
{
Repository = GetRequiredService<IFeatureValueRepository>();
}
[Fact]
public async Task FindAsync()
{
//feature value does exists
var featureValue = await Repository.FindAsync(
TestFeatureDefinitionProvider.ProjectCount,
EditionFeatureManagementProvider.ProviderName,
TestEditionNames.Enterprise
);
featureValue.ShouldNotBeNull();
featureValue.Value.ShouldBe("3");
//feature value does not exists
featureValue = await Repository.FindAsync(
TestFeatureDefinitionProvider.ProjectCount,
EditionFeatureManagementProvider.ProviderName,
"undefined-edition-name"
);
featureValue.ShouldBeNull();
}
[Fact]
public async Task GetListAsync()
{
var featureValues = await Repository.GetListAsync(EditionFeatureManagementProvider.ProviderName, TestEditionNames.Enterprise);
featureValues.Count.ShouldBeGreaterThan(0);
featureValues.ShouldContain(
fv => fv.Name == TestFeatureDefinitionProvider.SocialLogins &&
fv.Value == "true"
);
featureValues.ShouldContain(
fv => fv.Name == TestFeatureDefinitionProvider.ProjectCount &&
fv.Value == "3"
);
}
}
}

@ -0,0 +1,9 @@
namespace Volo.Abp.FeatureManagement
{
public static class TestEditionNames
{
public const string Regular = "Regular";
public const string Enterprise = "Enterprise";
public const string Ultimate = "Ultimate";
}
}

@ -0,0 +1,54 @@
using Volo.Abp.Features;
using Volo.Abp.Validation.StringValues;
namespace Volo.Abp.FeatureManagement
{
public class TestFeatureDefinitionProvider : FeatureDefinitionProvider
{
public const string SocialLogins = "SocialLogins";
public const string EmailSupport = "EmailSupport";
public const string DailyAnalysis = "DailyAnalysis";
public const string UserCount = "UserCount";
public const string ProjectCount = "ProjectCount";
public const string BackupCount = "BackupCount";
public override void Define(IFeatureDefinitionContext context)
{
var group = context.AddGroup("TestGroup");
group.AddFeature(
SocialLogins,
valueType: new ToggleStringValueType()
);
group.AddFeature(
EmailSupport,
valueType: new ToggleStringValueType()
);
group.AddFeature(
DailyAnalysis,
defaultValue: false.ToString().ToLowerInvariant(), //Optional, it is already false by default
valueType: new ToggleStringValueType()
);
group.AddFeature(
UserCount,
defaultValue: "1",
valueType: new FreeTextStringValueType(new NumericValueValidator(1, 1000))
);
group.AddFeature(
ProjectCount,
defaultValue: "1",
valueType: new FreeTextStringValueType(new NumericValueValidator(1, 10))
);
group.AddFeature(
BackupCount,
defaultValue: "0",
valueType: new FreeTextStringValueType(new NumericValueValidator(0, 10))
);
}
}
}

@ -1,29 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
namespace Volo.Abp.SettingManagement.EntityFrameworkCore
{
[ConnectionStringName("AbpSettingManagement")]
public class AbpSettingManagementDbContext : AbpDbContext<AbpSettingManagementDbContext>, ISettingManagementDbContext
{
public static string TablePrefix { get; set; } = AbpSettingManagementConsts.DefaultDbTablePrefix;
public static string Schema { get; set; } = AbpSettingManagementConsts.DefaultDbSchema;
public DbSet<Setting> Settings { get; set; }
public AbpSettingManagementDbContext(DbContextOptions<AbpSettingManagementDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ConfigureSettingManagement(TablePrefix, Schema);
}
}
}

@ -1,33 +0,0 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
namespace Volo.Abp.SettingManagement.EntityFrameworkCore
{
public static class AbpSettingManagementDbContextModelBuilderExtensions
{
public static void ConfigureSettingManagement(
[NotNull] this ModelBuilder builder,
[CanBeNull] string tablePrefix = AbpSettingManagementConsts.DefaultDbTablePrefix,
[CanBeNull] string schema = AbpSettingManagementConsts.DefaultDbSchema)
{
Check.NotNull(builder, nameof(builder));
if (tablePrefix == null)
{
tablePrefix = "";
}
builder.Entity<Setting>(b =>
{
b.ToTable(tablePrefix + "Settings", schema);
b.Property(x => x.Name).HasMaxLength(SettingConsts.MaxNameLength).IsRequired();
b.Property(x => x.Value).HasMaxLength(SettingConsts.MaxValueLength).IsRequired();
b.Property(x => x.ProviderName).HasMaxLength(SettingConsts.MaxProviderNameLength);
b.Property(x => x.ProviderKey).HasMaxLength(SettingConsts.MaxProviderKeyLength);
b.HasIndex(x => new {x.Name, x.ProviderName, x.ProviderKey});
});
}
}
}
Loading…
Cancel
Save