net getconnectionstring connectionstrings asp asp.net-core connection-string appsettings

asp.net-core - getconnectionstring - core 2 connection string



Obtenga ConnectionString de appsettings.json en lugar de estar codificado en la aplicaciĆ³n.NET Core 2.0 (4)

Tengo la siguiente clase en la aplicación NET Core2.0.

// required when local database does not exist or was deleted public class ToDoContextFactory : IDesignTimeDbContextFactory<AppContext> { public AppContext CreateDbContext(string[] args) { var builder = new DbContextOptionsBuilder<AppContext>(); builder.UseSqlServer("Server=localhost;Database=DbName;Trusted_Connection=True;MultipleActiveResultSets=true"); return new AppContext(builder.Options); } }

Esto se requiere en Core 2.0 con migración cuando la base de datos no existe y debe crearse cuando ejecuta la base de datos de actualización .
No se pueden crear migraciones después de actualizar a ASP.NET Core 2.0

Me gustaría no tener ConnectionString en 2 lugares (aquí y en appsettings.json) pero solo en .json, así que he tratado de reemplazar

"Server=localhost;Database=DbName;Trusted_Connection=True;MultipleActiveResultSets=true"

con

ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString

Pero no está funcionando, estoy obteniendo un valor nulo.

ACTUALIZACIÓN 1:
Solo para tener en cuenta que agregar explícitamente .json no es necesario en el Core 2, por lo que el problema no está en el archivo.
https://andrewlock.net/exploring-program-and-startup-in-asp-net-core-2-preview1-2/

ACTUALIZACIÓN 2:
También ya estoy usando la Configuración para enviar ConnectionString de .json a Context:

public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddDbContext<AppContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); } }

Pero no puedo usar esto para ToDoContextFactory porque no tiene Configuración, y ToDoContextFactory es utilizado por las migraciones, por lo que la aplicación no se ejecuta en absoluto.

SOLUCIÓN: Basado en la respuesta de @JRB, hice que funcionara así:

public AppContext CreateDbContext(string[] args) { string projectPath = AppDomain.CurrentDomain.BaseDirectory.Split(new String[] { @"bin/" }, StringSplitOptions.None)[0]; IConfigurationRoot configuration = new ConfigurationBuilder() .SetBasePath(projectPath) .AddJsonFile("appsettings.json") .Build(); string connectionString = configuration.GetConnectionString("DefaultConnection"); var builder = new DbContextOptionsBuilder<AppContext>(); builder.UseSqlServer(connectionString); return new AppContext(builder.Options); }


¿Qué hay de pasarlo como inyección dp en esa clase? en ConfigureServices:

services.Configure<MyOptions>(Configuration);

crear clase para mantener cadenas json:

public class MyOptions { public MyOptions() { } public string Option1 { get; set; } public string Option2 { get; set; } }

Agregue cadenas al archivo json:

"option1": "somestring", "option2": "someothersecretstring"

En las clases que necesitan estas cadenas, pase como constructor:

public class SomeClass { private readonly MyOptions _options; public SomeClass(IOptions<MyOptions> options) { _options = options.Value; } public void UseStrings() { var option1 = _options.Option1; var option2 = _options.Option2; //code } }


En ASPNET Core lo haces en Startup.cs

public void ConfigureServices(IServiceCollection services) { services.AddDbContext<BloggingContext>(options => options.UseSqlServer(Configuration.GetConnectionString("BloggingDatabase"))); }

donde su conexión se define en appsettings.json

{ "ConnectionStrings": { "BloggingDatabase": "..." }, }

Ejemplo de MS docs


En realidad, hay un patrón predeterminado que puede emplear para lograr este resultado sin tener que implementar IDesignTimeDbContextFactory y hacer cualquier copia de archivo de configuración.

Se detalla en este documento , que también analiza las otras formas en que el marco intentará crear una instancia de DbContext en el momento del diseño.

Específicamente, aprovecha un nuevo gancho, en este caso un método estático de la forma public static IWebHost BuildWebHost(string[] args) . La documentación implica lo contrario, pero este método puede vivir en cualquier clase que contenga su punto de entrada ( ver src ). Implementar esto es parte de la guía en el documento de migración 1.x a 2.x y lo que no es completamente obvio al observar el código es que la llamada a WebHost.CreateDefaultBuilder(args) está, entre otras cosas, conectando su configuración por defecto Patrón con el que comienzan los nuevos proyectos. Eso es todo lo que necesita para obtener la configuración que utilizarán los servicios de tiempo de diseño, como las migraciones.

Aquí hay más detalles sobre lo que está pasando en el fondo:

Al agregar una migración, cuando el marco intenta crear su DbContext , first agrega cualquier implementación de IDesignTimeDbContextFactory que encuentra a una colección de métodos de fábrica que se pueden usar para crear su contexto, luego obtiene sus servicios configurados a través del enganche estático discutido anteriormente y looks cualquier tipo de contexto registrado con un DbContextOptions (que ocurre en su Startup.ConfigureServices cuando usa AddDbContext o AddDbContextPool ) y agrega esas fábricas. Finalmente, looks en el ensamblaje las clases derivadas de DbContext y crea un método de fábrica que simplemente llama a Activator.CreateInstance como último saludo.

El orden de precedencia que utiliza el marco es el mismo que el anterior. Por lo tanto, si tiene implementado IDesignTimeDbContextFactory , se anulará el IDesignTimeDbContextFactory mencionado anteriormente. Sin embargo, para los escenarios más comunes, no necesitará IDesignTimeDbContextFactory .


PASO 1: incluya lo siguiente en OnConfiguring ()

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { IConfigurationRoot configuration = new ConfigurationBuilder() .SetBasePath(AppDomain.CurrentDomain.BaseDirectory) .AddJsonFile("appsettings.json") .Build(); optionsBuilder.UseSqlServer(configuration.GetConnectionString("DefaultConnection")); }

PASO 2: Crear appsettings.json:

{ "ConnectionStrings": { "DefaultConnection": "Server=YOURSERVERNAME; Database=YOURDATABASENAME; Trusted_Connection=True; MultipleActiveResultSets=true" } }

PASO 3: Copia impresa de appsettings.json al directorio correcto

Hard copy appsettings.json.config to the directory specified in the AppDomain.CurrentDomain.BaseDirectory directory. Use your debugger to find out which directory that is.

Supuesto: ya ha incluido el paquete Microsoft.Extensions.Configuration.Json (obténgalo de Nuget) en su proyecto.