Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to Reduce magic in the interaction of EF Core and DI #4750

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@
<value>Root namespace of the project is required to generate code.</value>
</data>
<data name="MigrationsAssemblyMismatch" xml:space="preserve">
<value>Your target project '{assembly}' doesn't match your migrations assembly '{migrationsAssembly}'. Change your target project to the migrations project by using the Package Manager Console's Default project drop-down list or by using the '--targetProject' option for DNX commands. Change your migrations assembly by using DbContextOptionsBuilder. E.g. options.UseSqlServer().MigrationsAssembly("{assembly}")</value>
<value>Your target project '{assembly}' doesn't match your migrations assembly '{migrationsAssembly}'. Change your target project to the migrations project by using the Package Manager Console's Default project drop-down list or by using the '--targetProject' option for DNX commands. Change your migrations assembly by using DbContextOptionsBuilder. E.g. options.UseSqlServer(connection, b =&gt; b.MigrationsAssembly("{assembly}"))</value>
</data>
<data name="SensitiveInformationWarning" xml:space="preserve">
<value>To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.</value>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Infrastructure.Internal;
Expand All @@ -12,13 +13,24 @@ namespace Microsoft.EntityFrameworkCore
{
public static class InMemoryDbContextOptionsExtensions
{
public static InMemoryDbContextOptionsBuilder UseInMemoryDatabase([NotNull] this DbContextOptionsBuilder optionsBuilder)
public static DbContextOptionsBuilder UseInMemoryDatabase(
[NotNull] this DbContextOptionsBuilder optionsBuilder,
[CanBeNull] Action<InMemoryDbContextOptionsBuilder> inMemoryOptionsAction = null)
{
Check.NotNull(optionsBuilder, nameof(optionsBuilder));

((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(new InMemoryOptionsExtension());

return new InMemoryDbContextOptionsBuilder(optionsBuilder);
inMemoryOptionsAction?.Invoke(new InMemoryDbContextOptionsBuilder(optionsBuilder));

return optionsBuilder;
}

public static DbContextOptionsBuilder<TContext> UseInMemoryDatabase<TContext>(
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder,
[CanBeNull] Action<InMemoryDbContextOptionsBuilder> inMemoryOptionsAction = null)
where TContext : DbContext
=> (DbContextOptionsBuilder<TContext>)UseInMemoryDatabase(
(DbContextOptionsBuilder)optionsBuilder, inMemoryOptionsAction);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Data.Common;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Infrastructure;
Expand All @@ -16,11 +17,14 @@ public static class SqlServerDbContextOptionsExtensions
/// <summary>
/// Configures the context to connect to a Microsoft SQL Server database.
/// </summary>
/// <param name="optionsBuilder"> The options for the context. </param>
/// <param name="optionsBuilder"> A builder for setting options on the context. </param>
/// <param name="connectionString"> The connection string of the database to connect to. </param>
/// <returns> An options builder to allow additional SQL Server specific configuration. </returns>
public static SqlServerDbContextOptionsBuilder UseSqlServer(
[NotNull] this DbContextOptionsBuilder optionsBuilder, [NotNull] string connectionString)
/// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server specific configuration.</param>
/// <returns> The options builder so that further configuration can be chained. </returns>
public static DbContextOptionsBuilder UseSqlServer(
[NotNull] this DbContextOptionsBuilder optionsBuilder,
[NotNull] string connectionString,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this just happen in the action now? Or, is this the pattern for required config?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. This is the pattern for required config.

[CanBeNull] Action<SqlServerDbContextOptionsBuilder> sqlServerOptionsAction = null)
{
Check.NotNull(optionsBuilder, nameof(optionsBuilder));
Check.NotEmpty(connectionString, nameof(connectionString));
Expand All @@ -29,22 +33,27 @@ public static SqlServerDbContextOptionsBuilder UseSqlServer(
extension.ConnectionString = connectionString;
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);

return new SqlServerDbContextOptionsBuilder(optionsBuilder);
sqlServerOptionsAction?.Invoke(new SqlServerDbContextOptionsBuilder(optionsBuilder));

return optionsBuilder;
}

// Note: Decision made to use DbConnection not SqlConnection: Issue #772
/// <summary>
/// Configures the context to connect to a Microsoft SQL Server database.
/// </summary>
/// <param name="optionsBuilder"> The options for the context. </param>
/// <param name="optionsBuilder"> A builder for setting options on the context. </param>
/// <param name="connection">
/// An existing <see cref="DbConnection" /> to be used to connect to the database. If the connection is
/// in the open state then EF will not open or close the connection. If the connection is in the closed
/// state then EF will open and close the connection as needed.
/// </param>
/// <returns> An options builder to allow additional SQL Server specific configuration. </returns>
public static SqlServerDbContextOptionsBuilder UseSqlServer(
[NotNull] this DbContextOptionsBuilder optionsBuilder, [NotNull] DbConnection connection)
/// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server specific configuration.</param>
/// <returns> The options builder so that further configuration can be chained. </returns>
public static DbContextOptionsBuilder UseSqlServer(
[NotNull] this DbContextOptionsBuilder optionsBuilder,
[NotNull] DbConnection connection,
[CanBeNull] Action<SqlServerDbContextOptionsBuilder> sqlServerOptionsAction = null)
{
Check.NotNull(optionsBuilder, nameof(optionsBuilder));
Check.NotNull(connection, nameof(connection));
Expand All @@ -53,9 +62,46 @@ public static SqlServerDbContextOptionsBuilder UseSqlServer(
extension.Connection = connection;
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);

return new SqlServerDbContextOptionsBuilder(optionsBuilder);
sqlServerOptionsAction?.Invoke(new SqlServerDbContextOptionsBuilder(optionsBuilder));

return optionsBuilder;
}

/// <summary>
/// Configures the context to connect to a Microsoft SQL Server database.
/// </summary>
/// <param name="optionsBuilder"> A builder for setting options on the context. </param>
/// <param name="connectionString"> The connection string of the database to connect to. </param>
/// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server specific configuration.</param>
/// <returns> The options builder so that further configuration can be chained. </returns>
public static DbContextOptionsBuilder<TContext> UseSqlServer<TContext>(
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder,
[NotNull] string connectionString,
[CanBeNull] Action<SqlServerDbContextOptionsBuilder> sqlServerOptionsAction = null)
where TContext : DbContext
=> (DbContextOptionsBuilder<TContext>)UseSqlServer(
(DbContextOptionsBuilder)optionsBuilder, connectionString, sqlServerOptionsAction);

// Note: Decision made to use DbConnection not SqlConnection: Issue #772
/// <summary>
/// Configures the context to connect to a Microsoft SQL Server database.
/// </summary>
/// <param name="optionsBuilder"> A builder for setting options on the context. </param>
/// <param name="connection">
/// An existing <see cref="DbConnection" /> to be used to connect to the database. If the connection is
/// in the open state then EF will not open or close the connection. If the connection is in the closed
/// state then EF will open and close the connection as needed.
/// </param>
/// <param name="sqlServerOptionsAction">An optional action to allow additional SQL Server specific configuration.</param>
/// <returns> The options builder so that further configuration can be chained. </returns>
public static DbContextOptionsBuilder<TContext> UseSqlServer<TContext>(
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder,
[NotNull] DbConnection connection,
[CanBeNull] Action<SqlServerDbContextOptionsBuilder> sqlServerOptionsAction = null)
where TContext : DbContext
=> (DbContextOptionsBuilder<TContext>)UseSqlServer(
(DbContextOptionsBuilder)optionsBuilder, connection, sqlServerOptionsAction);

private static SqlServerOptionsExtension GetOrCreateExtension(DbContextOptionsBuilder optionsBuilder)
{
var existing = optionsBuilder.Options.FindExtension<SqlServerOptionsExtension>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,12 @@ private SqlServerConnection(

protected override DbConnection CreateDbConnection() => new SqlConnection(ConnectionString);

// TODO use clone connection method once implemented see #1406
public virtual ISqlServerConnection CreateMasterConnection()
{
var builder = new SqlConnectionStringBuilder { ConnectionString = ConnectionString, InitialCatalog = "master" };

// TODO use clone connection method once implemented see #1406
var optionsBuilder = new DbContextOptionsBuilder();
optionsBuilder.UseSqlServer(builder.ConnectionString).CommandTimeout(CommandTimeout ?? DefaultMasterConnectionCommandTimeout);

return new SqlServerConnection(optionsBuilder.Options, Logger);
}
=> new SqlServerConnection(new DbContextOptionsBuilder()
.UseSqlServer(
new SqlConnectionStringBuilder { ConnectionString = ConnectionString, InitialCatalog = "master" }.ConnectionString,
b => b.CommandTimeout(CommandTimeout ?? DefaultMasterConnectionCommandTimeout)).Options, Logger);

public override bool IsMultipleActiveResultSetsEnabled
=> (bool)(_multipleActiveResultSetsEnabled
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Data.Common;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Infrastructure;
Expand All @@ -11,30 +12,56 @@ namespace Microsoft.EntityFrameworkCore
{
public static class SqliteDbContextOptionsBuilderExtensions
{
public static SqliteDbContextOptionsBuilder UseSqlite([NotNull] this DbContextOptionsBuilder options, [NotNull] string connectionString)
public static DbContextOptionsBuilder UseSqlite(
[NotNull] this DbContextOptionsBuilder optionsBuilder,
[NotNull] string connectionString,
[CanBeNull] Action<SqliteDbContextOptionsBuilder> sqliteOptionsAction = null)
{
Check.NotNull(options, nameof(options));
Check.NotNull(optionsBuilder, nameof(optionsBuilder));
Check.NotEmpty(connectionString, nameof(connectionString));

var extension = GetOrCreateExtension(options);
var extension = GetOrCreateExtension(optionsBuilder);
extension.ConnectionString = connectionString;
((IDbContextOptionsBuilderInfrastructure)options).AddOrUpdateExtension(extension);
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);

return new SqliteDbContextOptionsBuilder(options);
sqliteOptionsAction?.Invoke(new SqliteDbContextOptionsBuilder(optionsBuilder));

return optionsBuilder;
}

public static SqliteDbContextOptionsBuilder UseSqlite([NotNull] this DbContextOptionsBuilder options, [NotNull] DbConnection connection)
public static DbContextOptionsBuilder UseSqlite(
[NotNull] this DbContextOptionsBuilder optionsBuilder,
[NotNull] DbConnection connection,
[CanBeNull] Action<SqliteDbContextOptionsBuilder> sqliteOptionsAction = null)
{
Check.NotNull(options, nameof(options));
Check.NotNull(optionsBuilder, nameof(optionsBuilder));
Check.NotNull(connection, nameof(connection));

var extension = GetOrCreateExtension(options);
var extension = GetOrCreateExtension(optionsBuilder);
extension.Connection = connection;
((IDbContextOptionsBuilderInfrastructure)options).AddOrUpdateExtension(extension);
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);

sqliteOptionsAction?.Invoke(new SqliteDbContextOptionsBuilder(optionsBuilder));

return new SqliteDbContextOptionsBuilder(options);
return optionsBuilder;
}

public static DbContextOptionsBuilder<TContext> UseSqlite<TContext>(
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder,
[NotNull] string connectionString,
[CanBeNull] Action<SqliteDbContextOptionsBuilder> sqliteOptionsAction = null)
where TContext : DbContext
=> (DbContextOptionsBuilder<TContext>)UseSqlite(
(DbContextOptionsBuilder)optionsBuilder, connectionString, sqliteOptionsAction);

public static DbContextOptionsBuilder<TContext> UseSqlite<TContext>(
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder,
[NotNull] DbConnection connection,
[CanBeNull] Action<SqliteDbContextOptionsBuilder> sqliteOptionsAction = null)
where TContext : DbContext
=> (DbContextOptionsBuilder<TContext>)UseSqlite(
(DbContextOptionsBuilder)optionsBuilder, connection, sqliteOptionsAction);

private static SqliteOptionsExtension GetOrCreateExtension(DbContextOptionsBuilder options)
{
var existingExtension = options.Options.FindExtension<SqliteOptionsExtension>();
Expand Down
Loading