2017-11-23 7 views
-1

クラスライブラリでクラスを設定し、Startup.csのサービスでそれらを注入可能に設定して問題なく動作させました。期待される。私が働いていたテストアプリでAsp.Net Core 2.0のConfigurationオブジェクトは、クラスライブラリプロジェクトに注入可能

。私はStartup.cs

// *If* you need access to generic IConfiguration this is **required** 
     services.AddSingleton<IConfiguration>(Configuration); 

     services.AddOptions(); 
     // Add our class objects so they can be injected 

services.Configure<TestAppServices.ConfigurationClasses.ApplicationSettings>(Configuration.GetSection("ApplicationSettings")); 
     services.Configure<TestAppServices.ConfigurationClasses.LoggingSettings>(Configuration.GetSection("Logging")); 
     services.Configure<TestAppServices.ConfigurationClasses.ApplicationIconUrlSettings>(Configuration.GetSection("ApplicationIconUrls")); 
     services.Configure<TestAppServices.ConfigurationClasses.DatabaseConfigurationSettings>(Configuration.GetSection("ConnectionStrings")); 
     services.Configure<TestAppServices.ConfigurationClasses.SmsSettings>(Configuration.GetSection("SmsSettings")); 
でデータクラスライブラリプロジェクトに加えて、私のMVCアプリのプロジェクト(コア2.0.1およびEF 2.0.1とMVC6)

を持っています

設定されている個々のクラスのすべての設定にアクセスできますが、次の設定は機能しません。

private static IConfiguration _configuration { get; set; } 
    private const string AppSettingsConnectionsHeader = "ConnectionStrings"; 

    public DatabaseHelpers(IConfiguration configuration) 
    { 
     _configuration = configuration; 
    } 

    public static ConnectionStrings GetConnections() 
    { 
     var cs = new ConnectionStrings(); 
     _configuration.GetSection(AppSettingsConnectionsHeader).Bind(cs); 
     return cs; 
    } 

私は通常のエラーに取得しています

System.NullReferenceException:オブジェクト参照がオブジェクトインスタンスに設定されていません。 TestAppServices.DatabaseHelpers.GetConnections()で

_configurationはnullです。したがって、注入されません。

GetConnections方法

は、クラスライブラリプロジェクト内注射用であるので、実際の構成オブジェクトを設定するための特別な方法がありますので、

var cs = DatabaseHelpers.GetConnections(); 

のように、コントローラから呼び出されていますか?

アップデート:私は、次の

public static class ConnectionStrings 
{ 
    public static string DefaultConnection => "DefaultConnection"; 
    public static string TestingConnection => "TestingConnection"; 
    public static string StagingConnection => "StagingConnection"; 
    public static string ProductionConnection => "ProductionConnection"; 
    public static string DevelopmentConnection => "DevelopmentConnection";  
} 

public class ConfigurationSettings 
{ 
    private readonly IConfiguration _configuration; 

    public ConfigurationSettings(IConfiguration config) 
    { 
     _configuration = config; 
    } 

    public DatabaseConfigurationSettings GetConnectionStringFor(DatabaseIsFor dbfor) 
    { 
     var dbcs = new DatabaseConfigurationSettings(); 
     switch (dbfor) 
     { 
      case DatabaseIsFor.Development: 
       if (!string.IsNullOrEmpty(_configuration.GetConnectionString(ConnectionStrings.DevelopmentConnection))) 
       { 
        dbcs.CompleteConnectionString = _configuration.GetConnectionString(ConnectionStrings.DevelopmentConnection); 
        dbcs.ConnectionName = ConnectionStrings.DevelopmentConnection; //== _connections.Value.DevelopmentConnection.ToString(); 
        return dbcs; 
       } 
       break; 

      case DatabaseIsFor.Testing: 
       if (!string.IsNullOrEmpty(_configuration.GetConnectionString(ConnectionStrings.TestingConnection))) 
       { 
        dbcs.CompleteConnectionString = _configuration.GetConnectionString(ConnectionStrings.TestingConnection); 
        dbcs.ConnectionName = ConnectionStrings.TestingConnection; //== _connections.Value.TestingConnection.ToString(); 
        return dbcs; 
       } 
       break; 

      case DatabaseIsFor.Staging: 
       if (!string.IsNullOrEmpty(_configuration.GetConnectionString(ConnectionStrings.StagingConnection))) 
       { 
        dbcs.CompleteConnectionString = _configuration.GetConnectionString(ConnectionStrings.StagingConnection); 
        dbcs.ConnectionName = ConnectionStrings.StagingConnection; //== _connections.Value.TestingConnection.ToString(); 
        return dbcs; 
       } 
       break; 

      case DatabaseIsFor.Production: 
       if (!string.IsNullOrEmpty(_configuration.GetConnectionString(ConnectionStrings.ProductionConnection))) 
       { 
        dbcs.CompleteConnectionString = _configuration.GetConnectionString(ConnectionStrings.ProductionConnection); 
        dbcs.ConnectionName = ConnectionStrings.ProductionConnection; //== _connections.Value.TestingConnection.ToString(); 
        return dbcs; 
       } 
       break; 

     } 
     dbcs.CompleteConnectionString = _configuration.GetConnectionString(ConnectionStrings.DefaultConnection); 
     dbcs.ConnectionName = ConnectionStrings.DefaultConnection; //== _connections.Value.DefaultConnection.ToString(); 
     return dbcs; 
    } 
} 

そして

public class HomeController : Controller 
{ 
    private IConfiguration Configuration { get; set; } 

    public HomeController(IConfiguration configuration) 
    { 
     Configuration = configuration; 
    } 

    public IActionResult Index() 
    { 
     // test view to check that this works 
     var cs = new ConfigurationSettings(Configuration);    
     var dbcs = cs.GetConnectionStringFor(DatabaseIsFor.Production); 

     var svm = SettingsViewModel(dbcs); 
     return View(svm); 
    } 
} 

そして、それが動作を次のように私は、コントローラにそれを使用する私のクラスライブラリプロジェクトを再構成serpent5の答えパー

を除いて私はなぜpaにする必要があるのか​​分からないss ConfigurationSettingsを新規作成するときの設定。私はそれをStartup.cs ConfigureServicesに追加して以来、すでにそこで利用できるはずはありませんか?

// Access to generic IConfiguration 
services.AddSingleton(Configuration); 
+0

コンストラクタにブレークポイントを設定します。ヒットしますか? –

+0

@ serpent5 ...素晴らしい呼び出し、コンストラクタ内のブレークポイントがヒットしていない、なぜですか? – dinotom

+0

@ serpent5 ...注射の構文が間違っていますか?あなたは何とかコンフィグレーションルートにIOptionsを使用するか、コンフィグレーションで設定されたクラスのIOptionsのみを使用しますか? – dinotom

答えて

2

クラスのインスタンスをインスタンス化しない場合は、Constructor Injectionは使用できません。あなたが提供したコードでは、コンストラクタ経由でIConfigurationのインスタンスを注入するようにDatabaseHelpersを設定しましたが、クラス自体はDependency Injectionには参加しないので、そのコンストラクタを呼び出す必要はありません。

特定の例の回避策は、何らかの方法で静的クラスを明示的に初期化することです。おそらくConfigureServicesに - あなたはその後、単にアプリの起動時にどこかにこれを設定したい

public static Initialize(IConfiguration configuration) 
{ 
    _configuration = configuration; 
} 

:あなたは、DatabaseHelpersにこのような何かを新しいメソッドを追加することができます。例えば:

services.AddSingleton<IConfiguration>(Configuration); 
DatabaseHelpers.Initialize(Configuration); 

これは技術的な問題の回避方法ですが、これには静的ヘルパーを使用するのが最適かどうかを検討することをおすすめします。私は実際にDatabaseHelpersの実装がここに示したよりも複雑であると仮定し、ConnectionStringsのインスタンスをあなたのDependency Injectionサービスコレクションに追加し、その代わりに使うことはできません。

更新:依存性注入は実際にはの魔法ではなく、ちょうどpatternです。これは、クラスを作成する責任を他のエンティティ(通常はMVC世界ではコントローラのアクティベーションプロセスです)に委任するとうまく動作しますが、作成を自分でコントロールしても機能しません。更新された例では、ConfigurationSettingsの作成に全責任を負います。したがって、そのコンストラクタ引数を指定する必要があります。

これを自分で処理したくない場合は、サービスのコレクションにConfigurationSettingsを追加して、DIコンテナに依存するConfigurationを解決させることができます。

+0

@ serpent5 ... upvoted ...これに関するもう1つの質問については、私のポストアップデートをご覧ください – dinotom

関連する問題