web-dev-qa-db-ja.com

IConfigurationRootを使用して、アプリケーションの接続文字列をASP.NET 5のリポジトリクラスライブラリに渡す

ASP.NET 5 MVC Webアプリケーションがあり、Startup.csにパブリックプロパティがあることがわかります

_IConfigurationRoot Configuration 
_

builder.Build();に設定されています

MVC Webアプリケーション全体で、私は簡単にできる

_Startup.Configuration["Data:DefaultConnection:ConnectionString"]
_

_appsettings.json_ファイルからconn文字列を取得します。

コンストラクターインジェクションを使用して、ASP.NET 5 MVC _appsettings.json_で指定された接続文字列をリポジトリクラスライブラリに渡すにはどうすればよいですか?

更新:
他のすべてのリポジトリが継承するベースリポジトリを以下に示します(現在のところ、ここにハードコードされた接続文字列があります)。

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

Appsettings.jsonファイルのasp.net 5 Webアプリケーションには、.net 4.5 webappのweb.configに接続文字列を追加するのと同等の次のものがあります。

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

さらに、asp.net 5 Webアプリケーションでは、Startup.csに次のデフォルトコードがあり、サイト構成を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();
        }
_

今、私のasp.net Webアプリケーションで、appsettingsのいずれかにアクセスしたい場合、次のことを簡単に行うことができます。_Startup.Configuration["Data:DefaultConnection:ConnectionString"]_

しかし、残念ながら、クラスライブラリからこれを行うことはできません。

誰かがこれを試して、理解したい場合は、再現する手順を以下に示します。

  1. 新しいASP.NET 5 MVC Webアプリを作成します。
  2. クラスライブラリ(パッケージ)タイプの別のプロジェクトをプロジェクトに追加します。
  3. ASP.NET 5 MVCアプリからクラスライブラリにアプリ設定を渡す方法を考え出す

更新後もまだ取得できません。ここに私のコードがあります:

_public class BaseRepo
{
    private readonly IConfigurationRoot config;

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

BaseRepoにはコンストラクターパラメーターが必要になったため、このクラス宣言は機能しません。

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

startup.csファイルに次のメソッドを追加します

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

次に、このようにBaseRepoクラスを更新します

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

ASP.NETには、構成設定を渡す独自の方法が用意されています。

AppSettings.jsonにthisがあるとします:

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

次に、このようなクラスが必要です:

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

    public string Setting2 { get; set; }
}

これにより、次の行を追加して、この構成でサービスを構成できます。

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

ConfigureServicesに。

次に、以下を実行して、構成をコンストラクターに注入できます。

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

この例はコントローラー用です。ただし、アプリケーションの他のレイヤーでも同じことができます。

13
Chrono

リポジトリクラスに、db接続文字列をパラメーターとして受け入れるコンストラクターがあります。これは、注入用のリポジトリを追加するときに機能します。 startup.csファイルのConfigureServies()でこれを追加します。

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

IRepos.csはインターフェース、Repos.csはそれを実装するクラスです。そしてもちろん、ConfigurationはビルドされたIConfigurationRootオブジェクトへの単なる参照です。

3
Matthew Allen

特にaspsettings.jsonから接続文字列を取得するために使用できる拡張メソッドが既にあります。

  1. Appsettings.jsonで接続文字列を次のように定義します。

    _ {
         "ConnectionStrings": {
             "Local": "Data source=.\\SQLExpress;Initial Catalog=.......",
             "Test:": "Data source=your-server;......"
         },
         "Logging": {
             "IncludeScopes": false,
             "LogLevel": {
                 "Default": "Debug",
                 "System": "Information",
                 "Microsoft": "Information"
             }
         }
    }
    _
  2. _Startup.cs_内のpublic void ConfigureServices(IServiceCollection services)メソッドで、次のような接続文字列を取得できます。

    _var connectionString = this.Configuration.GetConnectionString("Local");
    _
  3. GetConnectionString拡張子は_Microsoft.Extensions.Configuration_からのものです。
  4. 楽しい :)

[〜#〜] update [〜#〜]

ここでの質問には既に回答済みのマークが付けられていたため、最初は詳細に入りませんでした。しかし、ここで2セントを表示できると思います。

ControllerにIConfigurationRootオブジェクト全体を挿入する必要がある場合、@ Chronoは正しい方法を示しました。

オブジェクト全体が必要ない場合は、接続文字列を取得し、ConfigureServices()呼び出し内のDbContextに渡し、DbContextをControllersに挿入するだけです。 @Prashant Lakhlaniはそれを正しく示しました。

@Prashant Lakhlaniの投稿では、代わりにGetConnectionString拡張を使用してコードを少しクリーンアップできると言っています。

2
David Liang

少し異なる方法は、_Startup.cs_のConfigure(..)- methodからメソッドを呼び出すクラスライブラリに静的クラスを作成することです。

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

この場合、構成をConfigureServicesにシングルトンとして追加しました。

_services.AddSingleton(_ => Configuration);
_

私のConnectionManagerは次のようになります。

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

これには、オブジェクトの寿命などに関する問題がある場合とない場合があり、staticクラスのファンではありませんが、実行可能なアプローチであると言えます。 Configurationを渡す代わりに、構成ファイルからConnectionStringを抽出して、それだけを送信することもできます。

2
Ruben Steins

ConfigureServicesがプロジェクトのstartUp.csを含む

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

リポジトリのcsファイルには、以下に示すようにコンストラクタ注入があります

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

YourDbContextは自動的に解決されます。

1

必要なのは、クラスライブラリプロジェクトにクラスを作成して、Webサイトプロジェクトのappsettings.jsonにアクセスし、接続文字列を返すことです。

{
    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