2017-02-05 16 views
5

ASP.NET MVCの内部の詳細を知っているシニアレベルのASP.NETアーキテクトからの回答を探しています。Startup.csオブジェクトの参照を取得する

ここに標準ASP.NETコアアプリケーションのスケルトンがあります。 ASP.NET装置はStartup.csクラスのインスタンスをインスタンス化し、この作品では

var config = new ConfigurationBuilder() 
    .AddCommandLine(args) 
    .AddEnvironmentVariables(prefix: "ASPNETCORE_") 
    .Build(); 

var host = new WebHostBuilder() 
    .UseConfiguration(config) 
    .UseKestrel() 
    .UseContentRoot(Directory.GetCurrentDirectory()) 
    .UseIISIntegration() 
    .UseStartup<Startup>() 
    .Build(); 

host.Run(); 

.UseStartup<Startup>() 

私のクエリは、私はスタートアップオブジェクトのこの既にインスタンスインスタンスのホールド(参照)を得ることができる方法である私ができますライブラリ/フレームワークにプラグインします。

コンテキストは、いくつかのUberレベルのフレームワークをセットアップし、すべての要求が開始されているこのジャンクション(Startup.cs)の参照を取得することです。

答えて

10

あなたStartupIStartupインターフェース、それへの参照を取得することは簡単で実装している場合:

var host = new WebHostBuilder() 
.UseConfiguration(config) 
.UseKestrel() 
.UseContentRoot(Directory.GetCurrentDirectory()) 
.UseIISIntegration() 
.UseStartup<Startup>() 
.Build(); 

var startup = host.Services.GetService(typeof(IStartup)); // or from any other part of code using IServiceProvider. 

しかし、asp.netコアははこのインタフェースを実装するスタートアップクラスを必要としませんが。そうでなければ、アダプタパターンを使用し、StartupクラスをIStartupインターフェイスに適合させます。あなたはまだIStartupのインスタンスを持ちますが、あなたのStartupクラスではありません。代わりにConventionBasedStartupのインスタンスになります。 Asp.netコアは、スタートアップクラスのメソッドを探索し、ConfigureConfigureServicesのメソッドを見つけ、それらをConventionBasedStartupに渡し、IStartupインターフェイスに適合させます。この場合、起動クラスのインスタンスは、実際にはフィールドに格納されていないため、重複して取得することはできません。プライベートでもConventionBasedStartupであり、委譲参照のみで到達可能です。

短いストーリー - Startupクラスのインスタンスを取得する場合は、IStartupインターフェイスを実装するようにします。 IStartupインターフェイスを実装する方法について

更新:

public class Startup : IStartup 
{ 
    public Startup(IHostingEnvironment env) 
    { 
     // constructor as usual 
     var builder = new ConfigurationBuilder() 
      .SetBasePath(env.ContentRootPath) 
      .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 
      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) 
      .AddEnvironmentVariables(); 
     Configuration = builder.Build(); 
    } 

    public IConfigurationRoot Configuration { get; } 

    public void Configure(IApplicationBuilder app) {    
     app.UseMvc(); 
     // resolve services from container 
     var env = (IHostingEnvironment) app.ApplicationServices.GetService(typeof(IHostingEnvironment)); 
     var logger = (ILoggerFactory)app.ApplicationServices.GetService(typeof(ILoggerFactory)); 
     logger.AddConsole(Configuration.GetSection("Logging")); 
     logger.AddDebug(); 
     // etc 
    }   

    public IServiceProvider ConfigureServices(IServiceCollection services) { 
     services.AddMvc(); 
     // etc 
     // return provider 
     return services.BuildServiceProvider(); 
    } 
} 
+0

おかげで、これは有望と思われる、私は、 '' Startup'クラスへのインタフェースとしてIStartup'が、それは 'ConfigureServices'の戻り値の型のために文句を言っています追加しました質問は 'ConfigureServices'の中で' IStartup'インターフェースの要件に合うように返すべきものです、私は.netに慣れています。 – user2727195

+0

@ user2727195例を使って答えを更新しました。 – Evk

+0

おかげさまで、ビジュアルスタジオコードは、例えば、 'ConfigurationBuilder'や' IConfigurationRoot'のように、依存性が少ないと不平を言っています。私はジェネレータ 'yo aspnet'を使って基本的な素裸の骨を作りました。私のフレームワークでは重い持ち上げが行われるので、 'Startup.cs'レベルで最も単純な実装をしたいと思っています。また、独自のカスタム実装があるので、 'asp.net mvc'の' mvc'にプラグインしたくありません。非常に単純なレベルでは、Startupオブジェクトが着信要求を自分のフレームワークに委譲するだけです。 – user2727195

関連する問題