web-dev-qa-db-fra.com

Transmission de la chaîne de connexion de l'application à une bibliothèque de classes de référentiel dans ASP.NET 5 à l'aide de IConfigurationRoot

J'ai une application Web ASP.NET 5 MVC et dans Startup.cs, je vois que la propriété publique 

IConfigurationRoot Configuration 

est réglé sur builder.Build();

Tout au long de l'application Web MVC, je peux simplement faire

Startup.Configuration["Data:DefaultConnection:ConnectionString"]

pour obtenir la chaîne de connexion à partir du fichier appsettings.json.

Comment obtenir la chaîne de connexion spécifiée dans ASP.NET 5 MVC appsettings.json transmise à ma bibliothèque de classes de référentiel à l'aide de l'injection de constructeur?

METTRE À JOUR:
Voici le référentiel de base dont tous les autres référentiels héritent (comme vous pouvez le constater, j'ai une chaîne de connexion codée en dur ici pour l'instant):

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;
    }
}

Dans mon application web asp.net 5 dans mon fichier appsettings.json, les éléments suivants équivalent à l’ajout d’une chaîne de connexion à un fichier web.config dans une application Web .net 4.5:

  "Data": {
    "DefaultConnection": {
      "ConnectionString": "Server=MYSERVER;Database=MYDATABASE;Trusted_Connection=True;"
    }
  }

De plus, dans mon application Web asp.net 5, le code par défaut suivant figure dans mon fichier Startup.cs, qui charge la configuration des sites dans une propriété publique de type 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();
        }

Maintenant, dans mon application Web asp.net, si je souhaite accéder à l'un des paramètres d'application, je peux simplement effectuer les opérations suivantes: Startup.Configuration["Data:DefaultConnection:ConnectionString"]

Mais malheureusement, je ne peux pas le faire depuis ma bibliothèque de classe ..

Si quelqu'un veut essayer de comprendre ceci, voici les étapes à suivre pour reproduire:

  1. Créez une nouvelle application Web ASP.NET 5 MVC. 
  2. Ajoutez un autre projet de type bibliothèque de classes (package) au projet. 
  3. Trouvez un moyen de transmettre les paramètres d'application de l'application ASP.NET 5 MVC à la bibliothèque de classes.

Après la mise à jour, je ne peux toujours pas tout à fait l'obtenir. Voici mon code:

public class BaseRepo
{
    private readonly IConfigurationRoot config;

    public BaseRepo(IConfigurationRoot config)
    {
        this.config = config;
    }
}

Cette déclaration de classe ne fonctionne pas car BaseRepo nécessite maintenant un paramètre constructeur.

public class CustomerRepo : BaseRepository, ICustomerRepo
{
    public Customer Find(int id)
    {
        using (var connection = GetOpenConnection())
        {
            ...
        }
    }
}
21
Blake Rivell

sur votre fichier Startup.cs, ajoutez la méthode suivante

public void ConfigureServices(IServiceCollection services) {
    services.AddSingleton(_ => Configuration);
}

puis mettez à jour votre classe BaseRepo comme ceci

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;
    }
}
27
Manos Pasgiannis

ASP.NET fournit sa propre manière de transmettre les paramètres de configuration.

Supposons que vous ayez ceci dans votre appSettings.json:

{
  "Config": {
    "Setting1": 1,
    "Setting2": "SO"
  }
}

Ensuite, vous avez besoin d'un cours comme celui-ci:

public class MyConfiguration
{
    public int Setting1 { get; set; }

    public string Setting2 { get; set; }
}

Cela vous permet de configurer votre service avec cette configuration en ajoutant la ligne suivante

services.Configure<MyConfigurationDto>(Configuration.GetSection("Config"));

à ConfigureServices.

Vous pouvez ensuite injecter la configuration dans les constructeurs en procédant comme suit:

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);
    }
}

Cet exemple est pour les contrôleurs. Mais vous pouvez faire la même chose avec d'autres couches de votre application.

10
Chrono

J'ai un constructeur dans ma classe de référentiel qui accepte la chaîne de connexion à la base de données en tant que paramètre. Cela fonctionne pour moi lorsque j'ajoute mon référentiel pour l'injection. Dans ConfigureServies () du fichier startup.cs, ajoutez ceci:

services.AddScoped<IRepos>(c => new Repos(Configuration["DbConnections:ConnStr1"]));

IRepos.cs est l'interface, Repos.cs est la classe qui l'implémente. Et bien sûr, Configuration n'est qu'une référence à l'objet IConfigurationRoot construit.

2
Matthew Allen

Il existe déjà une méthode d'extension que vous pouvez utiliser pour obtenir des chaînes de connexion spécifiquement à partir d'aspsettings.json.

  1. Définissez vos chaînes de connexion dans appsettings.json comme ceci:

     {
         "ConnectionStrings": {
             "Local": "Data source=.\\SQLExpress;Initial Catalog=.......",
             "Test:": "Data source=your-server;......"
         },
         "Logging": {
             "IncludeScopes": false,
             "LogLevel": {
                 "Default": "Debug",
                 "System": "Information",
                 "Microsoft": "Information"
             }
         }
    }
    
  2. Dans votre méthode public void ConfigureServices(IServiceCollection services) dans votre Startup.cs, vous pouvez obtenir la chaîne de connexion comme ceci:

    var connectionString = this.Configuration.GetConnectionString("Local");
    
  3. L'extension GetConnectionString provient de Microsoft.Extensions.Configuration.
  4. Prendre plaisir :)

METTRE &AGRAVE; JOUR

Je ne voulais pas entrer dans les détails au début parce que la question ici avait déjà été marquée comme réponse. Mais je suppose que je peux montrer mes 2 cents ici.

Si vous avez besoin de l’intégralité de l’objet IConfigurationRoot injecté dans les contrôleurs, @Chrono a montré la bonne manière.

Si vous n'avez pas besoin de tout l'objet, vous devez simplement obtenir la chaîne de connexion, la transmettre au DbContext dans l'appel ConfigureServices() et injecter la DbContext dans les contrôleurs. @Pashant Lakhlani l'a montré correctement.

Je dis simplement que, dans le post de @Prashant Lakhlani, vous pouvez utiliser l'extension GetConnectionString à la place pour nettoyer un peu le code.

1
David Liang

Si ConfigureServices dans le startUp.cs de votre projet contient

services.AddEntityFramework()
             .AddSqlServer()
             .AddDbContext<YourDbContext>(options =>
                 options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

et votre fichier cs de référentiel est en train d'avoir l'injection de constructeur comme indiqué ci-dessous

public class MyRepo : IRepo
{
    private readonly YourDbContext dbContext;
    public MyRepo(YourDbContext ctx)
    {
        dbContext = ctx;
    }
}

YourDbContext sera résolu automatiquement.

1
Prashant Lakhlani

Une approche légèrement différente consisterait à créer une classe statique dans votre bibliothèque de classes sur laquelle vous appelez une méthode à partir de la méthode Configure(..)- dans Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ...
    ConnectionManager.SetConfig(Configuration);
}

Dans ce cas, j'ai ajouté Configuration en tant que Singleton dans ConfigureServices:

services.AddSingleton(_ => Configuration);

Ma ConnectionManager ressemble à ceci:

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;
        }
    }
}

Cela peut ou peut ne pas avoir quelques problèmes concernant la durée de vie des objets et autres, et je ne suis certainement pas fan des classes static, mais pour autant que je sache, cette approche est viable. Au lieu de passer Configuration, vous pouvez même extraire la ConnectionString du fichier de configuration et n'envoyer que.

1
Ruben Steins

Ce dont vous avez besoin est de créer un projet de classe dans la bibliothèque de classes pour accéder au fichier appsettings.json dans le projet de site Web et renvoyer une chaîne de connexion.

{
    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; }

}
0
samvietnam