Net CoreによるAutoFacの利用
この記事ではIoCやDIの概念は紹介していませんので、Iocの予備知識がない場合は、まず関連情報を検索することをお勧めします
この記事では、AutoFacの基本的な使い方と、asp .net coreでの応用を簡単に紹介します。
オートファックの紹介
コンポーネントを登録する3つの方法
1. リフレクション
2. レディメイド・インスタンス(新規)
3. ラムダ式(オブジェクトのインスタンス化を実行する無名メソッド)。
また、quot;component" や "service" といった用語の意味については、コメントで説明します。
// Create the builder for the registered component
var builder = new ContainerBuilder();
// Register components by type ConsoleLogger Storming Service: ILogger
builder.RegisterType<ConsoleLogger>().As<ILogger>();
//Register the component ConsoleLogger by type, exposing all the services (interfaces) it implements
builder.RegisterType<ConsoleLogger>().AsImplementedInterfaces();
// register the component output according to the instance Storm service: TextWriter
var output = new StringWriter();
builder.RegisterInstance(output).As<TextWriter>();
//expression register component, here we are in the constructor when passing the reference - >"musection" storm service: IConfigReader
builder.Register(c =new ConfigReader("mysection")).As<IConfigReader>();
//expression to register the component, pass the reference when parsing
var service = scope.Resolve<IConfigReader>(
new NamedParameter("section", "mysection"));
//reflective registration of components, directly registered ConsoleLogger class (must be a specific class), if the ConsoleLogger has more than one constructor, will take the constructor with the most parameters to instantiate
builder.RegisterType<ConsoleLogger>();
//reflective registration of components, manually specify the constructor, here specify the constructor to call MyComponent (ILogger log, IConfigReader config) to register
builder.RegisterType<MyComponent>()
.UsingConstructor(typeof(ILogger), typeof(IConfigReader));
// Register the static variable "Instance" in the MySingleton class, the ExternallyOwned() function specifies that it controls the life cycle of the instance, rather than automatically released by autofac
builder.RegisterInstance(MySingleton.Instance).ExternallyOwned();
//One component exposes two services
builder.RegisterType<CallLogger>().As<ILogger>().As<ICallInterceptor>();
//Register the class ending with "Service" in the current assembly
Builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Service")) .AsImplementedInterfaces();
//Register all classes in "MyApp.Repository" assembly
builder.RegisterAssemblyTypes(GetAssembly("MyApp.Repository")).AsImplementedInterfaces();
// Build a container to complete the registration
var rootcontainer = builder.Build();
//You can get the IConfigReader implementation class manually in the following way
//This manual parsing method needs to get the component from the lifecycle scope to ensure that the component is eventually released
//Do not parse the component directly from the root container rootcontainer, it will probably lead to a memory leak
BeginLifetimeScope())
{
var reader = scope.Resolve<IConfigReader>();
}
複数のコンポーネントが同じサービスを公開している場合、オートファックは最後に登録されたコンポーネントをサービスの提供元として使用します。この動作をオーバーライドするには
PreserveExistingDefaults()
メソッドを使用して
ライフサイクル
using(var scope = rootcontainer.BeginLifetimeScope())
上記のコードは、ライフサイクルスコープを作成します。
ライフサイクルスコープは解放可能で、スコープ内で解決されたコンポーネントは、using 内で使用するか、コンポーネントの Dispose() 関数を最後に手動で呼び出さなければなりません。
ライフサイクルが参照するクラスのライフサイクルよりも大きいクラスを参照することは避けてください。例えば、サービスのライフサイクルがsingletonで、リポジトリのライフサイクルがperrequestの場合、サービスがリポジトリを参照します。サービスはリリースされないので、結局関連するリポジトリもリリースされないでしょう ( キャプティブ依存性 )
ルートコンテナから直接コンポーネントをパースすることはできるだけ避ける必要がありますが、常に例外は存在します。実際、非シングルトン コンポーネントの場合、理論的にはプロジェクト アーキテクチャは手動で解析するのではなく、コンストラクタから注入する必要があります。手動で解析する必要があるのは、いくつかの設定ヘルパークラスなどです。
特定のコンポーネント(クラス)のライフサイクルは、以下のように分類される(この後に続く機能は、autofacに対応するものである)。
- 依存関係ごとに1インスタンス(デフォルト) ---InstancePerDependency()
- シングルインスタンス シングルインスタンス ----SingleInstance()
- ライフタイム・スコープごとに1つのインスタンス ---InstancePerLifetimeScope()
- 一致するライフサイクルスコープごとに1つのインスタンス (Instance Per Matching Lifetime Scope) ---InstancePerMatchingLifetimeScope()
- 1 リクエストにつき 1 インスタンス (Instance Per Request) asp.net Web リクエスト ---InstancePerRequest()
- 所有するごとに1つのインスタンス (Instance Per Owned) ---InstancePerOwned()
従来のASP.NET MVCプロジェクトでautofacを使用したことがある場合、注意すべきいくつかの相違点があります。
<ブロッククオート-
Net Coreでは
InstancePerLifetimeScope
従来の(レガシーな)Asp.netではなくInstancePerRequest
を使用して、HTTP リクエストごとに依存関係の一意なインスタンスのみが作成されるようにします。InstancePerRequest
要求レベルはもはや存在しない - .net CoreのWeb ApiはMvcと同じように登録される {コントローラは.NETで作成されます。 net コアによって作成され、コントローラは autofac によって管理されません (コントローラのコンストラクタは例外です)。 {インスタンスペアリクエスト インスタンスペアリクエスト のライフサイクルを使用することができます。
AddControllersAsServices()
関数は、より深く知りたい人のために、チェックアウトしてください。
https://www.strathweb.com/2016/03/the-subtle-perils-of-controller-dependency-injection-in-asp-net-core-mvc
asp .net coreでのAutoFacの使用について
.net coreでautofacを使用することは比較的簡単で、従来のasp.netのWebプロジェクトと比較して多くのステップを節約することができます。
nugetパッケージの紹介です。
- オートファック
- Autofac.Extensions.DependencyInjectionについて
起動時のコード
public static IContainer AutofacContainer;
// This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services)
public IServiceProvider ConfigureServices(IServiceCollection services) {
// Register the services into the IServiceCollection
services.AddMvc();
ContainerBuilder builder = new ContainerBuilder();
//Populate Autofac with the services in services.
builder.Populate(services);
//register the new module component
builder.RegisterModule<DefaultModuleRegister>();
//create container.
AutofacContainer = builder.Build();
//use container to create AutofacServiceProvider
return new AutofacServiceProvider(AutofacContainer);
}
上記のコードでは、ビルダーの
RegisterModule
関数に渡す必要があります。TModule
モジュールで、autofacと呼ばれるこのモジュールの機能は、以下のように、関連するすべての登録設定を1つのクラスにまとめ、コードの保守と設定を容易にすることです。
DefaultModuleRegister
のコードは
DefaultModuleRegisterです。
public class DefaultModuleRegister : Module
{
protected override void Load(ContainerBuilder builder)
{
//register the classes ending with "Ser" in the current assembly, and leak all the interfaces implemented by the class, the life cycle of PerLifetimeScope
builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Ser")). AsImplementedInterfaces().InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Repository" ;)).AsImplementedInterfaces().InstancePerLifetimeScope();
//register all the classes in the "MyApp.
//builder.RegisterAssemblyTypes(GetAssembly("MyApp.Repository")).AsImplementedInterfaces();
}
public static Assembly GetAssembly(string assemblyName)
{
AssemblyLoadContext.Default.LoadFromAssemblyPath(AppContext.BaseDirectory + $"{assemblyName}.dll");
return assembly;
}
}
Configure機能では、オプションでプログラム停止時のオートファック解除機能を追加することができます。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime appLifetime)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
//The program stops calling the function
appLifetime.ApplicationStopped.Register(() => { AutofacContainer.Dispose(); });
}
Controller内のコード。
private IUserSer _user;
private IUserSer _user2;
public HomeController(IUserSer user, IUserSer user2)
{
_user = user;
_user2 = user2;
}
public IActionResult Index()
{
using (var scope = Startup.AutofacContainer.BeginLifetimeScope())
{
IConfiguration config = scope.Resolve<IConfiguration>();
IHostingEnvironment env = scope.Resolve<IHostingEnvironment>();
}
string name = _user.GetName();
string name2 = _user2.GetName();
return View();
}
ご覧の通り、IServiceCollection のサービスに autofac を投入したので、.net core のデフォルトの注入サービス(IConfiguration、IHostingEnvironment など)を AutoFac でどこからでも解析できるようになりました。
通常のプロジェクトの使い方では
AutofacContainer
を共通クラスライブラリで呼び出せるようにします。
Net Core AutoFacについては、Scripting Houseの過去記事を検索していただくか、引き続き以下の関連記事をご覧ください。
関連
-
pythonでpillowをインストールする3つの方法
-
.NET 6:.NETのロギングコンポーネントlog4netを使用する。
-
.NET Coreでオブジェクトプールを使用する
-
NET6新機能 新構造体の最適化
-
net core downlink tracking skywalking インストールと使いやすいチュートリアル
-
Net Core HttpClient処理 レスポンス圧縮の詳細
-
ASP.NET学習でよくあるエラーのまとめ
-
.NET 6における暗黙の名前空間参照
-
Application_End イベントをブロックする解決策
-
ASP.NETでのRadioButton(ラジオボタン)の使用について
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
ASP.NET CoreでURLを設定する5つの方法
-
.NET開発サーバー アプリケーション管理ツール
-
ASP.NET CoreでCAPの取引詳細を自動で有効にする
-
ASP.NETでWeb.configからログインする際の正しいアカウントパスワードを確認する
-
ASP.NET Core MVC Dependency Injection ビューとコントローラ
-
再起動を伴わないNET5の設定変更は自動的に反映される
-
asp.net core3.1 cookieとjwtのハイブリッド認証による多様な認証ソリューションの実現
-
非同期タスクキャンセルと監視のネット実装
-
ajaxでポップアップアラートボックス
-
CS0234 名前空間 'Microsoft.AspNet' に型または名前空間名 'Mvc' が存在しない (あなたは