FileContextCore/Extensions/FileContextDbContextOptionsExtensions.cs
// Copyright (c) morrisjdev. All rights reserved.
// Original copyright (c) .NET Foundation. All rights reserved.
// Modified version by morrisjdev
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using FileContextCore.Diagnostics;
using FileContextCore.FileManager;
using FileContextCore.Infrastructure;
using FileContextCore.Infrastructure.Internal;
using FileContextCore.Serializer;
using FileContextCore.Storage;
using FileContextCore.StoreManager;
using FileContextCore.Utilities;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
// ReSharper disable once CheckNamespace
namespace FileContextCore
{
/// <summary>
/// FileContextCore specific extension methods for <see cref="DbContextOptionsBuilder" />.
/// </summary>
public static class FileContextDbContextOptionsExtensions
{
#region NothingConfiguredUseJsonAndDefaultFileManager
/// <summary>
/// Configures the context to connect to an in-memory database.
/// The in-memory database is shared anywhere the same name is used, but only for a given
/// service provider.
/// </summary>
/// <typeparam name="TContext"> The type of context being configured. </typeparam>
/// <param name="optionsBuilder"> The builder being used to configure the context. </param>
/// <param name="databaseName">
/// The name of the in-memory database. This allows the scope of the in-memory database to be controlled
/// independently of the context. The in-memory database is shared anywhere the same name is used.
/// </param>
/// <param name="location">An optional parameter to define the location where the files are stored</param>
/// <param name="password">An optional parameter to define a password if needed by store manager, serializer or file manager</param>
/// <param name="databaseRoot">
/// All in-memory databases will be rooted in this object, allowing the application
/// to control their lifetime. This is useful when sometimes the context instance
/// is created explicitly with <c>new</c> while at other times it is resolved using dependency injection.
/// </param>
/// <param name="inMemoryOptionsAction">An optional action to allow additional in-memory specific configuration.</param>
/// <returns> The options builder so that further configuration can be chained. </returns>
public static DbContextOptionsBuilder<TContext> UseFileContextDatabase<TContext>(
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder,
string databaseName = "",
string location = null,
string password = null,
[CanBeNull] FileContextDatabaseRoot databaseRoot = null,
[CanBeNull] Action<FileContextDbContextOptionsBuilder> inMemoryOptionsAction = null)
where TContext : DbContext
=> (DbContextOptionsBuilder<TContext>) UseFileContextDatabase(
(DbContextOptionsBuilder) optionsBuilder, databaseName, location, password, databaseRoot,
inMemoryOptionsAction);
/// <summary>
/// Configures the context to connect to a named in-memory database.
/// The in-memory database is shared anywhere the same name is used, but only for a given
/// service provider.
/// </summary>
/// <param name="optionsBuilder"> The builder being used to configure the context. </param>
/// <param name="databaseName">
/// The name of the in-memory database. This allows the scope of the in-memory database to be controlled
/// independently of the context. The in-memory database is shared anywhere the same name is used.
/// </param>
/// <param name="location">An optional parameter to define the location where the files are stored</param>
/// <param name="password">An optional parameter to define a password if needed by store manager, serializer or file manager</param>
/// <param name="databaseRoot">
/// All in-memory databases will be rooted in this object, allowing the application
/// to control their lifetime. This is useful when sometimes the context instance
/// is created explicitly with <c>new</c> while at other times it is resolved using dependency injection.
/// </param>
/// <param name="inMemoryOptionsAction">An optional action to allow additional in-memory specific configuration.</param>
/// <returns> The options builder so that further configuration can be chained. </returns>
public static DbContextOptionsBuilder UseFileContextDatabase(
[NotNull] this DbContextOptionsBuilder optionsBuilder,
string databaseName = "",
string location = null,
string password = null,
[CanBeNull] FileContextDatabaseRoot databaseRoot = null,
[CanBeNull] Action<FileContextDbContextOptionsBuilder> inMemoryOptionsAction = null)
{
Check.NotNull(optionsBuilder, nameof(optionsBuilder));
var extension = optionsBuilder.Options.FindExtension<FileContextOptionsExtension>()
?? new FileContextOptionsExtension();
extension = extension.WithCustomOptions(databaseName, location, password,
typeof(DefaultStoreManager), typeof(JSONSerializer), typeof(DefaultFileManager));
if (databaseRoot != null)
{
extension = extension.WithDatabaseRoot(databaseRoot);
}
ConfigureWarnings(optionsBuilder);
((IDbContextOptionsBuilderInfrastructure) optionsBuilder).AddOrUpdateExtension(extension);
inMemoryOptionsAction?.Invoke(new FileContextDbContextOptionsBuilder(optionsBuilder));
return optionsBuilder;
}
#endregion
#region UseDefaultStoreManagerWithSerializerAndFileManager
/// <summary>
/// Configures the context to connect to an in-memory database.
/// The in-memory database is shared anywhere the same name is used, but only for a given
/// service provider.
/// </summary>
/// <typeparam name="TContext"> The type of context being configured. </typeparam>
/// <typeparam name="TSerializer"> The type of the serializer to be used. </typeparam>
/// <typeparam name="TFileManager"> The type of the file manager to be used. </typeparam>
/// <param name="optionsBuilder"> The builder being used to configure the context. </param>
/// <param name="databaseName">
/// The name of the in-memory database. This allows the scope of the in-memory database to be controlled
/// independently of the context. The in-memory database is shared anywhere the same name is used.
/// </param>
/// <param name="location">An optional parameter to define the location where the files are stored</param>
/// <param name="password">An optional parameter to define a password if needed by store manager, serializer or file manager</param>
/// <param name="databaseRoot">
/// All in-memory databases will be rooted in this object, allowing the application
/// to control their lifetime. This is useful when sometimes the context instance
/// is created explicitly with <c>new</c> while at other times it is resolved using dependency injection.
/// </param>
/// <param name="inMemoryOptionsAction">An optional action to allow additional in-memory specific configuration.</param>
/// <returns> The options builder so that further configuration can be chained. </returns>
public static DbContextOptionsBuilder<TContext> UseFileContextDatabase<TContext, TSerializer, TFileManager>(
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder,
string databaseName = "",
string location = null,
string password = null,
[CanBeNull] FileContextDatabaseRoot databaseRoot = null,
[CanBeNull] Action<FileContextDbContextOptionsBuilder> inMemoryOptionsAction = null)
where TContext : DbContext
where TSerializer : ISerializer
where TFileManager : IFileManager
=> (DbContextOptionsBuilder<TContext>) UseFileContextDatabase<TSerializer, TFileManager>(
optionsBuilder, databaseName, location, password, databaseRoot, inMemoryOptionsAction);
/// <summary>
/// Configures the context to connect to a named in-memory database.
/// The in-memory database is shared anywhere the same name is used, but only for a given
/// service provider.
/// </summary>
/// <typeparam name="TSerializer"> The type of the serializer to be used. </typeparam>
/// <typeparam name="TFileManager"> The type of the file manager to be used. </typeparam>
/// <param name="optionsBuilder"> The builder being used to configure the context. </param>
/// <param name="databaseName">
/// The name of the in-memory database. This allows the scope of the in-memory database to be controlled
/// independently of the context. The in-memory database is shared anywhere the same name is used.
/// </param>
/// <param name="location">An optional parameter to define the location where the files are stored</param>
/// <param name="password">An optional parameter to define a password if needed by store manager, serializer or file manager</param>
/// <param name="databaseRoot">
/// All in-memory databases will be rooted in this object, allowing the application
/// to control their lifetime. This is useful when sometimes the context instance
/// is created explicitly with <c>new</c> while at other times it is resolved using dependency injection.
/// </param>
/// <param name="inMemoryOptionsAction">An optional action to allow additional in-memory specific configuration.</param>
/// <returns> The options builder so that further configuration can be chained. </returns>
public static DbContextOptionsBuilder UseFileContextDatabase<TSerializer, TFileManager>(
[NotNull] this DbContextOptionsBuilder optionsBuilder,
string databaseName = "",
string location = null,
string password = null,
[CanBeNull] FileContextDatabaseRoot databaseRoot = null,
[CanBeNull] Action<FileContextDbContextOptionsBuilder> inMemoryOptionsAction = null)
where TSerializer : ISerializer
where TFileManager : IFileManager
{
Check.NotNull(optionsBuilder, nameof(optionsBuilder));
var extension = optionsBuilder.Options.FindExtension<FileContextOptionsExtension>()
?? new FileContextOptionsExtension();
extension = extension.WithCustomOptions(databaseName, location, password,
typeof(DefaultStoreManager), typeof(TSerializer), typeof(TFileManager));
if (databaseRoot != null)
{
extension = extension.WithDatabaseRoot(databaseRoot);
}
ConfigureWarnings(optionsBuilder);
((IDbContextOptionsBuilderInfrastructure) optionsBuilder).AddOrUpdateExtension(extension);
inMemoryOptionsAction?.Invoke(new FileContextDbContextOptionsBuilder(optionsBuilder));
return optionsBuilder;
}
#endregion
#region UseCustomStoreManager
/// <summary>
/// Configures the context to connect to an in-memory database.
/// The in-memory database is shared anywhere the same name is used, but only for a given
/// service provider.
/// </summary>
/// <typeparam name="TContext"> The type of context being configured. </typeparam>
/// <typeparam name="TStoreManager"> The type of the store manager to be used. </typeparam>
/// <param name="optionsBuilder"> The builder being used to configure the context. </param>
/// <param name="databaseName">
/// The name of the in-memory database. This allows the scope of the in-memory database to be controlled
/// independently of the context. The in-memory database is shared anywhere the same name is used.
/// </param>
/// <param name="location">An optional parameter to define the location where the files are stored</param>
/// <param name="password">An optional parameter to define a password if needed by store manager, serializer or file manager</param>
/// <param name="databaseRoot">
/// All in-memory databases will be rooted in this object, allowing the application
/// to control their lifetime. This is useful when sometimes the context instance
/// is created explicitly with <c>new</c> while at other times it is resolved using dependency injection.
/// </param>
/// <param name="inMemoryOptionsAction">An optional action to allow additional in-memory specific configuration.</param>
/// <returns> The options builder so that further configuration can be chained. </returns>
public static DbContextOptionsBuilder<TContext> UseFileContextDatabase<TContext, TStoreManager>(
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder,
string databaseName = "",
string location = null,
string password = null,
[CanBeNull] FileContextDatabaseRoot databaseRoot = null,
[CanBeNull] Action<FileContextDbContextOptionsBuilder> inMemoryOptionsAction = null)
where TContext : DbContext
where TStoreManager : IStoreManager
=> (DbContextOptionsBuilder<TContext>) UseFileContextDatabase<TStoreManager>(
optionsBuilder, databaseName, location, password, databaseRoot, inMemoryOptionsAction);
/// <summary>
/// Configures the context to connect to a named in-memory database.
/// The in-memory database is shared anywhere the same name is used, but only for a given
/// service provider.
/// </summary>
/// <typeparam name="TStoreManager"> The type of the store manager to be used. </typeparam>
/// <param name="optionsBuilder"> The builder being used to configure the context. </param>
/// <param name="databaseName">
/// The name of the in-memory database. This allows the scope of the in-memory database to be controlled
/// independently of the context. The in-memory database is shared anywhere the same name is used.
/// </param>
/// <param name="location">An optional parameter to define the location where the files are stored</param>
/// <param name="password">An optional parameter to define a password if needed by store manager, serializer or file manager</param>
/// <param name="databaseRoot">
/// All in-memory databases will be rooted in this object, allowing the application
/// to control their lifetime. This is useful when sometimes the context instance
/// is created explicitly with <c>new</c> while at other times it is resolved using dependency injection.
/// </param>
/// <param name="inMemoryOptionsAction">An optional action to allow additional in-memory specific configuration.</param>
/// <returns> The options builder so that further configuration can be chained. </returns>
public static DbContextOptionsBuilder UseFileContextDatabase<TStoreManager>(
[NotNull] this DbContextOptionsBuilder optionsBuilder,
string databaseName = "",
string location = null,
string password = null,
[CanBeNull] FileContextDatabaseRoot databaseRoot = null,
[CanBeNull] Action<FileContextDbContextOptionsBuilder> inMemoryOptionsAction = null)
where TStoreManager : IStoreManager
{
Check.NotNull(optionsBuilder, nameof(optionsBuilder));
var extension = optionsBuilder.Options.FindExtension<FileContextOptionsExtension>()
?? new FileContextOptionsExtension();
extension = extension.WithCustomOptions(databaseName, location, password, typeof(TStoreManager), null, null);
if (databaseRoot != null)
{
extension = extension.WithDatabaseRoot(databaseRoot);
}
ConfigureWarnings(optionsBuilder);
((IDbContextOptionsBuilderInfrastructure) optionsBuilder).AddOrUpdateExtension(extension);
inMemoryOptionsAction?.Invoke(new FileContextDbContextOptionsBuilder(optionsBuilder));
return optionsBuilder;
}
#endregion
private static void ConfigureWarnings(DbContextOptionsBuilder optionsBuilder)
{
// Set warnings defaults
var coreOptionsExtension
= optionsBuilder.Options.FindExtension<CoreOptionsExtension>()
?? new CoreOptionsExtension();
coreOptionsExtension = coreOptionsExtension.WithWarningsConfiguration(
coreOptionsExtension.WarningsConfiguration.TryWithExplicit(
FileContextEventId.TransactionIgnoredWarning, WarningBehavior.Throw));
((IDbContextOptionsBuilderInfrastructure) optionsBuilder).AddOrUpdateExtension(coreOptionsExtension);
}
}
}