-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added possibility to define default interceptors for Linq2Db. (#259)
* Added possibility to define default interceptors for Linq2Db. * CR fixes * changed the way of Linq2Db Interceptors registration. Made it possible to use interceptors registered for EF core also. * improved existing interceptors checking logic. Naming changes inside interceptor tests. * cr fix: removed duplicated interceptors check * cr fixes * Update Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.ContextExtensions.cs Co-authored-by: Svyatoslav Danyliv <[email protected]> * Update Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.ContextExtensions.cs Co-authored-by: Svyatoslav Danyliv <[email protected]> * cosmetics * Make traversing EF core interceptors configurable and disabled by default. * Update Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.cs Co-authored-by: Svyatoslav Danyliv <[email protected]> * Update Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.ContextExtensions.cs Co-authored-by: Svyatoslav Danyliv <[email protected]> * changed the name of method for using ef core registered interceptors to UseEfCoreRegisteredInterceptorsIfPossible. * removed UseEfCoreRegisteredInterceptorsIfPossible support and added possibility to create extension having same functionality. Added sample implementation of such extension method in tests. * updated README.md * cosmetic naming change Co-authored-by: Svyatoslav Danyliv <[email protected]>
- Loading branch information
Showing
15 changed files
with
822 additions
and
2 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
112 changes: 112 additions & 0 deletions
112
Source/LinqToDB.EntityFrameworkCore/Internal/LinqToDBOptionsExtension.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,112 @@ | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
using Microsoft.EntityFrameworkCore.Infrastructure; | ||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
namespace LinqToDB.EntityFrameworkCore.Internal | ||
{ | ||
using Interceptors; | ||
|
||
/// <summary> | ||
/// Model containing LinqToDB related context options | ||
/// </summary> | ||
public class LinqToDBOptionsExtension : IDbContextOptionsExtension | ||
{ | ||
private DbContextOptionsExtensionInfo? _info; | ||
private IList<IInterceptor>? _interceptors; | ||
|
||
/// <summary> | ||
/// Context options extension info object | ||
/// </summary> | ||
public DbContextOptionsExtensionInfo Info | ||
=> _info ??= new LinqToDBExtensionInfo(this); | ||
|
||
/// <summary> | ||
/// List of registered LinqToDB interceptors | ||
/// </summary> | ||
public virtual IList<IInterceptor> Interceptors | ||
=> _interceptors ??= new List<IInterceptor>(); | ||
|
||
/// <summary> | ||
/// .ctor | ||
/// </summary> | ||
public LinqToDBOptionsExtension() | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// .ctor | ||
/// </summary> | ||
/// <param name="copyFrom"></param> | ||
protected LinqToDBOptionsExtension(LinqToDBOptionsExtension copyFrom) | ||
{ | ||
_interceptors = copyFrom._interceptors; | ||
} | ||
|
||
/// Adds the services required to make the selected options work. This is used when | ||
/// there is no external System.IServiceProvider and EF is maintaining its own service | ||
/// provider internally. This allows database providers (and other extensions) to | ||
/// register their required services when EF is creating an service provider. | ||
/// <param name="services">The collection to add services to</param> | ||
public void ApplyServices(IServiceCollection services) | ||
{ | ||
; | ||
} | ||
|
||
/// <summary> | ||
/// Gives the extension a chance to validate that all options in the extension are | ||
/// valid. Most extensions do not have invalid combinations and so this will be a | ||
/// no-op. If options are invalid, then an exception should be thrown. | ||
/// </summary> | ||
/// <param name="options"></param> | ||
public void Validate(IDbContextOptions options) | ||
{ | ||
; | ||
} | ||
|
||
private sealed class LinqToDBExtensionInfo : DbContextOptionsExtensionInfo | ||
{ | ||
private string? _logFragment; | ||
|
||
public LinqToDBExtensionInfo(IDbContextOptionsExtension extension) | ||
: base(extension) | ||
{ | ||
} | ||
|
||
private new LinqToDBOptionsExtension Extension | ||
=> (LinqToDBOptionsExtension)base.Extension; | ||
|
||
public override bool IsDatabaseProvider | ||
=> false; | ||
|
||
public override string LogFragment | ||
{ | ||
get | ||
{ | ||
if (_logFragment == null) | ||
{ | ||
string logFragment = string.Empty; | ||
|
||
if (Extension.Interceptors.Any()) | ||
{ | ||
logFragment += $"Interceptors count: {Extension.Interceptors.Count}"; | ||
} | ||
|
||
_logFragment = logFragment; | ||
} | ||
|
||
return _logFragment; | ||
} | ||
} | ||
|
||
public override long GetServiceProviderHashCode() | ||
{ | ||
return 0; | ||
} | ||
|
||
public override void PopulateDebugInfo(IDictionary<string, string> debugInfo) | ||
=> debugInfo["Linq2Db"] = "1"; | ||
} | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
Source/LinqToDB.EntityFrameworkCore/LinqToDBContextOptionsBuilder.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,41 @@ | ||
using Microsoft.EntityFrameworkCore; | ||
|
||
namespace LinqToDB.EntityFrameworkCore | ||
{ | ||
using Internal; | ||
using Interceptors; | ||
|
||
/// <summary> | ||
/// LinqToDB context options builder | ||
/// </summary> | ||
public class LinqToDBContextOptionsBuilder | ||
{ | ||
private readonly LinqToDBOptionsExtension _extension; | ||
|
||
/// <summary> | ||
/// Db context options | ||
/// </summary> | ||
public DbContextOptions DbContextOptions { get; private set; } | ||
|
||
/// <summary> | ||
/// .ctor | ||
/// </summary> | ||
/// <param name="optionsBuilder"></param> | ||
public LinqToDBContextOptionsBuilder(DbContextOptionsBuilder optionsBuilder) | ||
{ | ||
_extension = optionsBuilder.Options.FindExtension<LinqToDBOptionsExtension>(); | ||
DbContextOptions = optionsBuilder.Options; | ||
} | ||
|
||
/// <summary> | ||
/// Registers LinqToDb interceptor | ||
/// </summary> | ||
/// <param name="interceptor">The interceptor instance to register</param> | ||
/// <returns></returns> | ||
public LinqToDBContextOptionsBuilder AddInterceptor(IInterceptor interceptor) | ||
{ | ||
_extension.Interceptors.Add(interceptor); | ||
return this; | ||
} | ||
} | ||
} |
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
33 changes: 33 additions & 0 deletions
33
Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFTools.ContextOptionsBuilderExtensions.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,33 @@ | ||
using System; | ||
using Microsoft.EntityFrameworkCore; | ||
using Microsoft.EntityFrameworkCore.Infrastructure; | ||
|
||
namespace LinqToDB.EntityFrameworkCore | ||
{ | ||
using Internal; | ||
|
||
public static partial class LinqToDBForEFTools | ||
{ | ||
/// <summary> | ||
/// Registers custom options related to LinqToDB provider | ||
/// </summary> | ||
/// <param name="optionsBuilder"></param> | ||
/// <param name="linq2DbOptionsAction">Custom options action</param> | ||
/// <returns></returns> | ||
public static DbContextOptionsBuilder UseLinqToDb( | ||
this DbContextOptionsBuilder optionsBuilder, | ||
Action<LinqToDBContextOptionsBuilder>? linq2DbOptionsAction = null) | ||
{ | ||
((IDbContextOptionsBuilderInfrastructure)optionsBuilder) | ||
.AddOrUpdateExtension(GetOrCreateExtension(optionsBuilder)); | ||
|
||
linq2DbOptionsAction?.Invoke(new LinqToDBContextOptionsBuilder(optionsBuilder)); | ||
|
||
return optionsBuilder; | ||
} | ||
|
||
private static LinqToDBOptionsExtension GetOrCreateExtension(DbContextOptionsBuilder options) | ||
=> options.Options.FindExtension<LinqToDBOptionsExtension>() | ||
?? new LinqToDBOptionsExtension(); | ||
} | ||
} |
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
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
21 changes: 21 additions & 0 deletions
21
...rameworkCore.BaseTests/Interceptors/Extensions/LinqToDBContextOptionsBuilderExtensions.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,21 @@ | ||
using System.Linq; | ||
using LinqToDB.Interceptors; | ||
using Microsoft.EntityFrameworkCore.Infrastructure; | ||
|
||
namespace LinqToDB.EntityFrameworkCore.BaseTests.Interceptors.Extensions | ||
{ | ||
public static class LinqToDBContextOptionsBuilderExtensions | ||
{ | ||
public static void UseEfCoreRegisteredInterceptorsIfPossible(this LinqToDBContextOptionsBuilder builder) | ||
{ | ||
var coreEfExtension = builder.DbContextOptions.FindExtension<CoreOptionsExtension>(); | ||
if (coreEfExtension?.Interceptors != null) | ||
{ | ||
foreach (var comboInterceptor in coreEfExtension.Interceptors.OfType<IInterceptor>()) | ||
{ | ||
builder.AddInterceptor(comboInterceptor); | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.