it-swarm.com.de

Übergeben der Verbindungszeichenfolge der Anwendung an eine Repository-Klassenbibliothek in ASP.NET 5 mithilfe von IConfigurationRoot

Ich habe eine ASP.NET 5-MVC-Webanwendung und in Startup.cs sehe ich die öffentliche Eigenschaft 

IConfigurationRoot Configuration 

wird eingestellt auf builder.Build();

In der MVC-Webanwendung kann ich das einfach tun

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

um die Verbindungszeichenfolge aus der appsettings.json-Datei zu erhalten.

Wie kann ich die in der ASP.NET 5-MVC appsettings.json angegebene Verbindungszeichenfolge mit Konstruktorinjektion an meine Repository-Klassenbibliothek übergeben übergeben?

UPDATE:
Hier ist das Basis-Repository, von dem alle anderen Repositorys erben (wie Sie sehen, habe ich hier eine fest codierte Verbindungszeichenfolge):

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

In meiner asp.net 5-Webanwendung in meiner appsettings.json-Datei habe ich Folgendes, was dem Hinzufügen einer Verbindungszeichenfolge zu einer web.config in einer .net 4.5-Webanwendung entspricht:

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

Zusätzlich habe ich in meiner asp.net 5-Webanwendung den folgenden Standardcode in meiner Startup.cs, der die Site-Konfiguration in eine öffentliche Eigenschaft des Typs IConfigurationRoot lädt:

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

Wenn ich nun in meiner asp.net-Webanwendung auf eine der Einstellungen zugreifen möchte, kann ich einfach Folgendes tun: Startup.Configuration["Data:DefaultConnection:ConnectionString"]

Leider kann ich das nicht aus meiner Klassenbibliothek machen.

Wenn jemand dies herausfinden möchte, sind hier die Schritte zur Reproduktion:

  1. Erstellen Sie eine neue ASP.NET 5-MVC-Webanwendung. 
  2. Fügen Sie dem Projekt ein anderes Projekt des Typs Class Library (Package) hinzu. 
  3. Finden Sie einen Weg, Apps-Einstellungen von der ASP.NET 5-MVC-App an die Klassenbibliothek zu übergeben

Nach dem Update kann ich es immer noch nicht ganz verstehen. Hier ist mein Code:

public class BaseRepo
{
    private readonly IConfigurationRoot config;

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

Diese Klassendeklaration funktioniert nicht, da BaseRepo jetzt einen Konstruktor param benötigt.

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

fügen Sie in Ihrer Datei "Startup.cs" die folgende Methode hinzu

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

aktualisieren Sie dann Ihre BaseRepo-Klasse wie folgt

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

ASP.NET bietet eine eigene Möglichkeit, Konfigurationseinstellungen zu umgehen.

Angenommen, Sie haben Folgendes in Ihrer appSettings.json:

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

Dann brauchst du eine Klasse wie diese:

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

    public string Setting2 { get; set; }
}

Auf diese Weise können Sie Ihren Dienst mit dieser Konfiguration konfigurieren, indem Sie die folgende Zeile hinzufügen

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

zu ConfigureServices.

Sie können die Konfiguration dann in Konstruktoren einfügen, indem Sie folgendermaßen vorgehen:

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

Dieses Beispiel ist für Controller. Sie können dies jedoch auch mit anderen Schichten Ihrer Anwendung tun.

10
Chrono

Ich habe einen Konstruktor in meiner Repository-Klasse, der die DB-Verbindungszeichenfolge als Parameter akzeptiert. Dies funktioniert für mich, wenn ich mein Repository für die Injektion hinzufüge. Fügen Sie in ConfigureServies () der Datei startup.cs Folgendes hinzu:

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

IRepos.cs ist das Interface, Repos.cs ist die Klasse, die es implementiert. Und natürlich ist Konfiguration nur ein Verweis auf das erstellte IConfigurationRoot-Objekt.

2
Matthew Allen

Es gibt bereits eine Erweiterungsmethode, mit der Sie Verbindungszeichenfolgen speziell von aspsettings.json abrufen können.

  1. Definieren Sie Ihre Verbindungszeichenfolgen in appsettings.json wie folgt:

     {
         "ConnectionStrings": {
             "Local": "Data source=.\\SQLExpress;Initial Catalog=.......",
             "Test:": "Data source=your-server;......"
         },
         "Logging": {
             "IncludeScopes": false,
             "LogLevel": {
                 "Default": "Debug",
                 "System": "Information",
                 "Microsoft": "Information"
             }
         }
    }
    
  2. In Ihrer public void ConfigureServices(IServiceCollection services)-Methode in Ihrem Startup.cs können Sie die Verbindungszeichenfolge folgendermaßen erhalten:

    var connectionString = this.Configuration.GetConnectionString("Local");
    
  3. Die Erweiterung GetConnectionString stammt von Microsoft.Extensions.Configuration.
  4. Genießen :)

UPDATE

Ich wollte zunächst nicht ins Detail gehen, weil die Frage hier bereits als beantwortet markiert war. Aber ich denke ich kann hier meine 2 Cent zeigen.

Wenn Sie das gesamte IConfigurationRoot-Objekt in die Controller injizieren müssen, hat @Chrono den richtigen Weg gezeigt.

Wenn Sie das gesamte Objekt nicht benötigen, sollten Sie nur die Verbindungszeichenfolge abrufen, sie in den DbContext im Aufruf von ConfigureServices() übergeben und die Variable DbContext in Controller einfügen. @Prashant Lakhlani hat es richtig gezeigt.

Ich sage nur, in @Prashant Lakhlani post können Sie stattdessen die Erweiterung GetConnectionString verwenden, um den Code ein wenig aufzuräumen.

1
David Liang

Wenn ConfigureServices in Ihrem Projekt startUp.cs enthalten ist

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

und Ihre Repository-CS-Datei enthält die Konstruktorinjektion wie unten gezeigt

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

YourDbContext wird automatisch aufgelöst.

1

Ein etwas anderer Ansatz wäre, eine statische Klasse in Ihrer Klassenbibliothek zu erstellen, in der Sie eine Methode aus der Configure(..)- -Methode in Startup.cs aufrufen:

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

In diesem Fall habe ich Configuration als Singleton in ConfigureServices hinzugefügt:

services.AddSingleton(_ => Configuration);

Mein ConnectionManager sieht so aus:

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

Es kann sein, dass dies einige Probleme in Bezug auf die Lebensdauer von Objekten und dergleichen hat oder nicht, und ich bin sicherlich kein Fan von static-Klassen, aber soweit ich das beurteilen kann, ist dies ein gangbarer Ansatz. Anstatt Configuration zu übergeben, können Sie sogar die ConnectionString-Datei aus der Konfigurationsdatei extrahieren und nur diese senden.

1
Ruben Steins

Sie müssen eine Klasse im Klassenbibliothekprojekt erstellen, um auf die Datei appsettings.json im Websiteprojekt zuzugreifen und die Verbindungszeichenfolge zurückzugeben.

{
    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