usar - importar una clase en c#
Pasar la cadena de conexión de la aplicación a una biblioteca de clases de repositorio en ASP.NET 5 usando el IConfigurationRoot (7)
ASP.NET proporciona su propia forma de pasar por los ajustes de configuración.
Supongamos que tienes esto en tu appSettings.json:
{
"Config": {
"Setting1": 1,
"Setting2": "SO"
}
}
Entonces necesitas una clase como esta:
public class MyConfiguration
{
public int Setting1 { get; set; }
public string Setting2 { get; set; }
}
Esto le permite configurar su servicio con esta configuración agregando la siguiente línea
services.Configure<MyConfigurationDto>(Configuration.GetSection("Config"));
para ConfigureServices
.
A continuación, puede inyectar la configuración en los constructores haciendo lo siguiente:
public class SomeController : Controller
{
private readonly IOptions<MyConfiguration> config;
public ServiceLocatorController(IOptions<MyConfiguration> config)
{
this.config = config;
}
[HttpGet]
public IActionResult Get()
{
return new HttpOkObjectResult(config.Value);
}
}
Este ejemplo es para controladores. Pero puedes hacer lo mismo con otras capas de tu aplicación.
Tengo una aplicación web ASP.NET 5 MVC y en Startup.cs veo que la propiedad pública
IConfigurationRoot Configuration
se está configurando como builder.Build();
A lo largo de la aplicación web MVC simplemente puedo hacer
Startup.Configuration["Data:DefaultConnection:ConnectionString"]
para obtener la cadena de appsettings.json
archivo appsettings.json
.
¿Cómo puedo obtener la cadena de conexión especificada en ASP.NET 5 MVC appsettings.json
transmite a mi biblioteca de clases de repositorio mediante la inyección del constructor?
ACTUALIZAR:
Aquí está el repositorio base del que heredan todos los demás repositorios (como se puede ver, tengo una cadena de conexión codificada aquí por ahora):
public class BaseRepo
{
public static string ConnectionString = "Server=MYSERVER;Database=MYDATABASE;Trusted_Connection=True;";
public static SqlConnection GetOpenConnection()
{
var cs = ConnectionString;
var connection = new SqlConnection(cs);
connection.Open();
return connection;
}
}
En mi aplicación web asp.net 5 en mi archivo appsettings.json tengo lo siguiente, que es equivalente a agregar una cadena de conexión a un web.config en una aplicación web .net 4.5:
"Data": {
"DefaultConnection": {
"ConnectionString": "Server=MYSERVER;Database=MYDATABASE;Trusted_Connection=True;"
}
}
Además, en mi aplicación web asp.net 5 tengo el siguiente código predeterminado en mi Startup.cs que carga la configuración de los sitios en una propiedad pública de tipo IConfigurationRoot:
public IConfigurationRoot Configuration { get; set; }
// Class Constructor
public Startup(IHostingEnvironment env)
{
// Set up configuration sources.
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
if (env.IsDevelopment())
{
// For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
builder.AddUserSecrets();
}
builder.AddEnvironmentVariables();
Configuration = builder.Build();
}
Ahora, en mi aplicación web asp.net, si quisiera acceder a cualquiera de los ajustes, puedo simplemente hacer lo siguiente: Configuración de inicio Startup.Configuration["Data:DefaultConnection:ConnectionString"]
Pero desafortunadamente no puedo hacer esto desde la biblioteca de mi clase ...
Si alguien quiere probar y resolver esto, aquí están los pasos para reproducir:
- Cree una nueva aplicación web ASP.NET 5 MVC.
- Agregue otro proyecto de tipo Class Library (Package) al proyecto.
- Descubra una manera de pasar las aplicaciones de la aplicación MVC de ASP.NET 5 a la biblioteca de clases
Después de la actualización todavía no puedo entenderlo. Aquí está mi código:
public class BaseRepo
{
private readonly IConfigurationRoot config;
public BaseRepo(IConfigurationRoot config)
{
this.config = config;
}
}
Esta declaración de clase no funciona ya que BaseRepo requiere un parámetro de constructor ahora.
public class CustomerRepo : BaseRepository, ICustomerRepo
{
public Customer Find(int id)
{
using (var connection = GetOpenConnection())
{
...
}
}
}
Lo que necesita es crear una clase en el proyecto de la biblioteca de clases para acceder a appsettings.json en el proyecto del sitio web y devolver la cadena de conexión.
{
private static string _connectionString;
public static string GetConnectionString()
{
if (string.IsNullOrEmpty(_connectionString))
{
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json");
Configuration = builder.Build();
_connectionString = Configuration.Get<string>("Data:MyDb:ConnectionString");
}
return _connectionString;
}
public static IConfigurationRoot Configuration { get; set; }
}
Si ConfigureServices
en el proyecto startUp.cs
contiene
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<YourDbContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
y su archivo cs del repositorio está teniendo la inyección del constructor como se muestra a continuación
public class MyRepo : IRepo
{
private readonly YourDbContext dbContext;
public MyRepo(YourDbContext ctx)
{
dbContext = ctx;
}
}
YourDbContext
se resolverá automáticamente.
Tengo un constructor en mi clase de repositorio que acepta la cadena de conexión db como parámetro. Esto me funciona cuando agrego mi repositorio para inyección. En ConfigureServies () del archivo startup.cs agregue esto:
services.AddScoped<IRepos>(c => new Repos(Configuration["DbConnections:ConnStr1"]));
IRepos.cs
es la interfaz, Repos.cs
es la clase que lo implementa. Y, por supuesto, la configuración es solo una referencia al objeto IConfigurationRoot
creado.
Un enfoque ligeramente diferente sería crear una clase estática en su biblioteca de clases en la que llame a un método desde el método Configure(..)
en Startup.cs
:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
ConnectionManager.SetConfig(Configuration);
}
En este caso, he agregado la configuración como Singleton en ConfigureServices
:
services.AddSingleton(_ => Configuration);
Mi ConnectionManager
ve así:
public class ConnectionManager
{
private static IConfiguration currentConfig;
public static void SetConfig(IConfiguration configuration)
{
currentConfig = configuration;
}
/// <summary>
/// Get a connection to the database.
/// </summary>
public static SqlConnection GetConnection
{
get
{
string connectionString = currentConfig.GetConnectionString("MyConnection");
// Create a new connection for each query.
SqlConnection connection = new SqlConnection(connectionString);
return connection;
}
}
}
Esto puede o no tener algunos problemas con respecto a la vida útil de los objetos, y ciertamente no soy un fanático de las clases static
pero, por lo que puedo decir, es un enfoque viable. En lugar de pasar la Configuration
, incluso podría extraer ConnectionString
del archivo de configuración y enviar solo eso.
Ya existe un método de extensión que puede utilizar para obtener cadenas de conexión específicamente de aspsettings.json.
Defina sus cadenas de conexión en appsettings.json así:
{ "ConnectionStrings": { "Local": "Data source=.//SQLExpress;Initial Catalog=.......", "Test:": "Data source=your-server;......" }, "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Debug", "System": "Information", "Microsoft": "Information" } } }
En su método
public void ConfigureServices(IServiceCollection services)
dentro de suStartup.cs
, puede obtener la cadena de conexión así:var connectionString = this.Configuration.GetConnectionString("Local");
- La extensión
GetConnectionString
es deMicrosoft.Extensions.Configuration
. - Disfrutar :)
ACTUALIZAR
No quería entrar en detalles al principio porque la pregunta aquí ya había sido marcada como contestada. Pero supongo que puedo mostrar mis 2 centavos aquí.
Si necesita inyectar todo el objeto IConfigurationRoot
en los Controladores, @Chrono mostró el camino correcto.
Si no necesita el objeto completo, solo debe obtener la cadena de conexión, pasarla a DbContext dentro de la llamada a ConfigureServices()
e inyectar DbContext
en los controladores. @Prashant Lakhlani lo mostró correctamente.
Solo digo que, en la publicación @Prashant Lakhlani, puedes usar la extensión GetConnectionString
lugar para limpiar el código un poco.
en su archivo Startup.cs agregue el siguiente método
public void ConfigureServices(IServiceCollection services) {
services.AddSingleton(_ => Configuration);
}
luego actualiza tu clase BaseRepo como esta
public class BaseRepo {
private readonly IConfiguration config;
public BaseRepo(IConfiguration config) {
this.config = config;
}
public SqlConnection GetOpenConnection() {
string cs = config["Data:DefaultConnection:ConnectionString"];
SqlConnection connection = new SqlConnection(cs);
connection.Open();
return connection;
}
}