forked from masastack/MASA.Utils
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ebb9df8
commit af78655
Showing
13 changed files
with
388 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
[*.cs] | ||
|
||
# top-most EditorConfig file | ||
root = true | ||
|
||
# Don't use tabs for indentation. | ||
[*] | ||
indent_style = space | ||
trim_trailing_whitespace = true | ||
guidelines = 140 | ||
max_line_length = 140 | ||
|
||
# Code files | ||
[*.{cs,csx,vb,vbx}] | ||
indent_size = 4 | ||
insert_final_newline = true | ||
charset = utf-8 | ||
|
||
# Xml project files | ||
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] | ||
indent_size = 2 | ||
|
||
# Xml config files | ||
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct,xml,stylecop}] | ||
indent_size = 2 | ||
|
||
# JSON files | ||
[*.json] | ||
indent_size = 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
src/Data/MASA.Utils.Data.EntityFrameworkCore/IQueryFilterProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace MASA.Utils.Data.EntityFrameworkCore; | ||
|
||
public interface IQueryFilterProvider | ||
{ | ||
LambdaExpression OnExecuting(IMutableEntityType entityType); | ||
} |
6 changes: 6 additions & 0 deletions
6
src/Data/MASA.Utils.Data.EntityFrameworkCore/ISaveChangesFilter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace MASA.Utils.Data.EntityFrameworkCore; | ||
|
||
public interface ISaveChangesFilter | ||
{ | ||
void OnExecuting(ChangeTracker changeTracker); | ||
} |
13 changes: 13 additions & 0 deletions
13
src/Data/MASA.Utils.Data.EntityFrameworkCore/MASA.Utils.Data.EntityFrameworkCore.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0-preview.7.21378.4" /> | ||
</ItemGroup> | ||
|
||
</Project> |
118 changes: 118 additions & 0 deletions
118
src/Data/MASA.Utils.Data.EntityFrameworkCore/MasaDbContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
namespace MASA.Utils.Data.EntityFrameworkCore; | ||
|
||
public class MasaDbContext : DbContext | ||
{ | ||
private readonly MasaDbContextOptions _options; | ||
|
||
public MasaDbContext() : base() { } | ||
|
||
public MasaDbContext(MasaDbContextOptions options) | ||
: base(options) | ||
{ | ||
_options = options; | ||
} | ||
|
||
/// <summary> | ||
/// Automatic filter soft delete data. | ||
/// When you override this method,you should call base.<see cref="OnModelCreating(ModelBuilder)"/>. | ||
/// <inheritdoc/> | ||
/// </summary> | ||
/// <param name="modelBuilder"></param> | ||
protected sealed override void OnModelCreating(ModelBuilder modelBuilder) | ||
{ | ||
OnModelCreatingExecuting(modelBuilder); | ||
|
||
// null when run dotnet ef cli | ||
if (_options == null) | ||
{ | ||
base.OnModelCreating(modelBuilder); | ||
return; | ||
} | ||
|
||
foreach (var entityType in modelBuilder.Model.GetEntityTypes()) | ||
{ | ||
foreach (var provider in _options.QueryFilterProviders) | ||
{ | ||
try | ||
{ | ||
var lambda = provider.OnExecuting(entityType); | ||
modelBuilder.Entity(entityType.ClrType).HasQueryFilter(lambda); | ||
} | ||
catch (Exception ex) | ||
{ | ||
throw new Exception("An error occured when QueryFilterProvider executing", ex); | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Use this method instead of OnModelCreating | ||
/// </summary> | ||
/// <param name="modelBuilder"></param> | ||
protected virtual void OnModelCreatingExecuting(ModelBuilder modelBuilder) | ||
{ | ||
|
||
} | ||
|
||
/// <summary> | ||
/// Automatic soft delete. | ||
/// <inheritdoc/> | ||
/// </summary> | ||
/// <returns></returns> | ||
public override int SaveChanges() | ||
{ | ||
return SaveChanges(true); | ||
} | ||
|
||
/// <summary> | ||
/// Automatic soft delete. | ||
/// <inheritdoc/> | ||
/// </summary> | ||
/// <param name="acceptAllChangesOnSuccess"></param> | ||
/// <returns></returns> | ||
public sealed override int SaveChanges(bool acceptAllChangesOnSuccess) | ||
{ | ||
OnFilterExecuting(); | ||
return base.SaveChanges(acceptAllChangesOnSuccess); | ||
} | ||
|
||
private void OnFilterExecuting() | ||
{ | ||
foreach (var filter in _options.SaveChangesFilters) | ||
{ | ||
try | ||
{ | ||
filter.OnExecuting(ChangeTracker); | ||
} | ||
catch (Exception ex) | ||
{ | ||
throw new Exception("An error occured when intercept SaveChanges(Async)", ex); | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Automatic soft delete. | ||
/// <inheritdoc/> | ||
/// </summary> | ||
/// <param name="cancellationToken"></param> | ||
/// <returns></returns> | ||
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default) | ||
{ | ||
return SaveChangesAsync(true, cancellationToken); | ||
} | ||
|
||
/// <summary> | ||
/// Automatic soft delete. | ||
/// <inheritdoc/> | ||
/// </summary> | ||
/// <param name="acceptAllChangesOnSuccess"></param> | ||
/// <param name="cancellationToken"></param> | ||
/// <returns></returns> | ||
public sealed override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default) | ||
{ | ||
OnFilterExecuting(); | ||
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/Data/MASA.Utils.Data.EntityFrameworkCore/MasaDbContextOptions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
namespace MASA.Utils.Data.EntityFrameworkCore; | ||
|
||
public abstract class MasaDbContextOptions : DbContextOptions | ||
{ | ||
public MasaDbContextOptions() | ||
: base(new Dictionary<Type, IDbContextOptionsExtension>()) | ||
{ | ||
|
||
} | ||
|
||
public MasaDbContextOptions([NotNull] IReadOnlyDictionary<Type, IDbContextOptionsExtension> extensions) | ||
: base(extensions) | ||
{ | ||
|
||
} | ||
|
||
/// <summary> | ||
/// Can be used to filter data | ||
/// </summary> | ||
public abstract IEnumerable<IQueryFilterProvider> QueryFilterProviders { get; } | ||
|
||
/// <summary> | ||
/// Can be used to intercept SaveChanges(Async) method | ||
/// </summary> | ||
public abstract IEnumerable<ISaveChangesFilter> SaveChangesFilters { get; } | ||
} |
16 changes: 16 additions & 0 deletions
16
src/Data/MASA.Utils.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
namespace MASA.Utils.Data.EntityFrameworkCore; | ||
|
||
public abstract class MasaDbContextOptionsBuilder : DbContextOptionsBuilder | ||
{ | ||
public MasaDbContextOptionsBuilder(DbContextOptions options) | ||
: base(options) | ||
{ | ||
|
||
} | ||
|
||
public abstract MasaDbContextOptionsBuilder UseQueryFilterProvider<TProvider>() | ||
where TProvider : class, IQueryFilterProvider; | ||
|
||
public abstract MasaDbContextOptionsBuilder UseSaveChangesFilter<TFilter>() | ||
where TFilter : class, ISaveChangesFilter; | ||
} |
25 changes: 25 additions & 0 deletions
25
src/Data/MASA.Utils.Data.EntityFrameworkCore/MasaDbContextOptionsBuilder`.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
namespace MASA.Utils.Data.EntityFrameworkCore; | ||
|
||
public class MasaDbContextOptionsBuilder<TContext> : MasaDbContextOptionsBuilder | ||
where TContext : MasaDbContext | ||
{ | ||
private readonly IServiceCollection _services; | ||
|
||
public MasaDbContextOptionsBuilder(IServiceCollection services) | ||
: base(new DbContextOptions<TContext>()) | ||
{ | ||
_services = services; | ||
} | ||
|
||
public override MasaDbContextOptionsBuilder UseQueryFilterProvider<TProvider>() | ||
{ | ||
_services.AddScoped<IQueryFilterProvider, TProvider>(); | ||
return this; | ||
} | ||
|
||
public override MasaDbContextOptionsBuilder UseSaveChangesFilter<TFilter>() | ||
{ | ||
_services.AddScoped<ISaveChangesFilter, TFilter>(); | ||
return this; | ||
} | ||
} |
82 changes: 82 additions & 0 deletions
82
src/Data/MASA.Utils.Data.EntityFrameworkCore/MasaDbContextOptions`.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
namespace MASA.Utils.Data.EntityFrameworkCore; | ||
|
||
public class MasaDbContextOptions<TContext> : MasaDbContextOptions | ||
where TContext : MasaDbContext | ||
{ | ||
private readonly DbContextOptions _originOptions; | ||
|
||
public MasaDbContextOptions( | ||
DbContextOptions originOptions, | ||
IEnumerable<IQueryFilterProvider> queryFilterProviders, | ||
IEnumerable<ISaveChangesFilter> saveChangesFilters) | ||
{ | ||
_originOptions = originOptions; | ||
QueryFilterProviders = queryFilterProviders; | ||
SaveChangesFilters = saveChangesFilters; | ||
} | ||
|
||
/// <summary> | ||
/// Can be used to filter data | ||
/// </summary> | ||
public override IEnumerable<IQueryFilterProvider> QueryFilterProviders { get; } | ||
|
||
/// <summary> | ||
/// Can be used to intercept SaveChanges(Async) method | ||
/// </summary> | ||
public override IEnumerable<ISaveChangesFilter> SaveChangesFilters { get; } | ||
|
||
/// <summary> | ||
/// <inheritdoc/> | ||
/// </summary> | ||
public override Type ContextType => _originOptions.ContextType; | ||
|
||
/// <summary> | ||
/// <inheritdoc/> | ||
/// </summary> | ||
public override bool IsFrozen => _originOptions.IsFrozen; | ||
|
||
/// <summary> | ||
/// <inheritdoc/> | ||
/// </summary> | ||
public override IEnumerable<IDbContextOptionsExtension> Extensions => _originOptions.Extensions; | ||
|
||
/// <summary> | ||
/// <inheritdoc/> | ||
/// </summary> | ||
/// <typeparam name="TExtension"></typeparam> | ||
/// <param name="extension"></param> | ||
/// <returns></returns> | ||
public override DbContextOptions WithExtension<TExtension>(TExtension extension) | ||
{ | ||
return _originOptions.WithExtension(extension); | ||
} | ||
|
||
/// <summary> | ||
/// <inheritdoc/> | ||
/// </summary> | ||
/// <typeparam name="TExtension"></typeparam> | ||
/// <returns></returns> | ||
public override TExtension FindExtension<TExtension>() | ||
{ | ||
return _originOptions.GetExtension<TExtension>(); | ||
} | ||
|
||
/// <summary> | ||
/// <inheritdoc/> | ||
/// </summary> | ||
public override void Freeze() | ||
{ | ||
_originOptions.Freeze(); | ||
} | ||
|
||
/// <summary> | ||
/// <inheritdoc/> | ||
/// </summary> | ||
/// <typeparam name="TExtension"></typeparam> | ||
/// <returns></returns> | ||
public override TExtension GetExtension<TExtension>() | ||
{ | ||
return _originOptions.GetExtension<TExtension>(); | ||
} | ||
} | ||
|
30 changes: 30 additions & 0 deletions
30
src/Data/MASA.Utils.Data.EntityFrameworkCore/ServiceCollectionExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
namespace MASA.Utils.Data.EntityFrameworkCore; | ||
|
||
public static class ServiceCollectionExtensions | ||
{ | ||
public static IServiceCollection AddMasaDbContext<TDbContext>( | ||
this IServiceCollection services, | ||
Action<MasaDbContextOptionsBuilder>? options = null) | ||
where TDbContext : MasaDbContext | ||
{ | ||
var builder = new MasaDbContextOptionsBuilder<TDbContext>(services); | ||
options?.Invoke(builder); | ||
|
||
services.AddDbContext<TDbContext>(); | ||
|
||
services.TryAddScoped(typeof(MasaDbContextOptions<TDbContext>), serviceProvider => CreateMasaDbContextOptions<TDbContext>(serviceProvider, builder.Options)); | ||
services.TryAddScoped<MasaDbContextOptions>(serviceProvider => serviceProvider.GetRequiredService<MasaDbContextOptions<TDbContext>>()); | ||
|
||
return services; | ||
} | ||
|
||
private static MasaDbContextOptions<TDbContext> CreateMasaDbContextOptions<TDbContext>( | ||
IServiceProvider serviceProvider, | ||
DbContextOptions options) | ||
where TDbContext : MasaDbContext | ||
{ | ||
var queryFilterProviders = serviceProvider.GetServices<IQueryFilterProvider>(); | ||
var saveChangesFilters = serviceProvider.GetServices<ISaveChangesFilter>(); | ||
return new MasaDbContextOptions<TDbContext>(options, queryFilterProviders, saveChangesFilters); | ||
} | ||
} |
Oops, something went wrong.