私はDIとその使い方に関する多くのドキュメントを読んだことがあります(ASP.NETコアに関連しています)。私が理解しているように、フレームワークが私のためにいくつかのコントローラをインスタンス化するとき、コントローラのクラスがコンストラクタに渡す必要があることを何とか知っています。それは反射か何か?誰かが私にASP.NET Core GitHubのソースでそれを見ることができる場所を教えてもらえますか?コンテナに必要なもの(DIALコンテナ)はDIコンテナでどのように認識されていますか?
2
A
答えて
2
現在のRC1上のASP.NET Core DIのコンストラクタ選択動作は、かなり複雑です。これまでは、単一のコンストラクタを持つ型だけをサポートしていました。これはvery good defaultです。しかしRC1では、複数のコンストラクタを持つ型を受け入れます。それでも、その動作は非常に奇妙で、テスト中にDIコンテナに複数のコンストラクタを持つ私のコンポーネントを作成させることはできませんでした。
コンストラクタの選択とコンストラクタパラメータの分析はすべてリフレクションを使用して行われ、式ツリーが構築され、最終的にデリゲートにコンパイルされます。コードはthisと同じくらい簡単です:
public Expression Build(Expression provider)
{
var parameters = _constructorInfo.GetParameters();
return Expression.New(
_constructorInfo,
_parameterCallSites.Select((callSite, index) =>
Expression.Convert(
callSite.Build(provider),
parameters[index].ParameterType)));
}
7
あなたはGitHubの上hereを探し始めることができます。
ナットシェルでは、リフレクションを使用して、タイプのパブリックコンストラクタとそのパラメータを検査しています。
var constructors = _descriptor.ImplementationType.GetTypeInfo()
.DeclaredConstructors
.Where(constructor => constructor.IsPublic)
.ToArray();
パラメータの長さに基づいてコンストラクタをソートし、最適なものを選択します。
このスニペットは、インスタンス化される型を呼び出すための最適なコンストラクタを探します。
public IServiceCallSite CreateCallSite(ServiceProvider provider, ISet<Type> callSiteChain)
{
var constructors = _descriptor.ImplementationType.GetTypeInfo()
.DeclaredConstructors
.Where(constructor => constructor.IsPublic)
.ToArray();
IServiceCallSite[] parameterCallSites = null;
if (constructors.Length == 0)
{
throw new InvalidOperationException(Resources.FormatNoConstructorMatch(_descriptor.ImplementationType));
}
else if (constructors.Length == 1)
{
var constructor = constructors[0];
var parameters = constructor.GetParameters();
if (parameters.Length == 0)
{
return new CreateInstanceCallSite(_descriptor);
}
parameterCallSites = PopulateCallSites(
provider,
callSiteChain,
parameters,
throwIfCallSiteNotFound: true);
return new ConstructorCallSite(constructor, parameterCallSites);
}
Array.Sort(constructors,
(a, b) => b.GetParameters().Length.CompareTo(a.GetParameters().Length));
ConstructorInfo bestConstructor = null;
HashSet<Type> bestConstructorParameterTypes = null;
for (var i = 0; i < constructors.Length; i++)
{
var parameters = constructors[i].GetParameters();
var currentParameterCallSites = PopulateCallSites(
provider,
callSiteChain,
parameters,
throwIfCallSiteNotFound: false);
if (currentParameterCallSites != null)
{
if (bestConstructor == null)
{
bestConstructor = constructors[i];
parameterCallSites = currentParameterCallSites;
}
else
{
// Since we're visiting constructors in decreasing order of number of parameters,
// we'll only see ambiguities or supersets once we've seen a 'bestConstructor'.
if (bestConstructorParameterTypes == null)
{
bestConstructorParameterTypes = new HashSet<Type>(
bestConstructor.GetParameters().Select(p => p.ParameterType));
}
if (!bestConstructorParameterTypes.IsSupersetOf(parameters.Select(p => p.ParameterType)))
{
// Ambigious match exception
var message = string.Join(
Environment.NewLine,
Resources.FormatAmbigiousConstructorException(_descriptor.ImplementationType),
bestConstructor,
constructors[i]);
throw new InvalidOperationException(message);
}
}
}
}
if (bestConstructor == null)
{
throw new InvalidOperationException(
Resources.FormatUnableToActivateTypeException(_descriptor.ImplementationType));
}
else
{
Debug.Assert(parameterCallSites != null);
return parameterCallSites.Length == 0 ?
(IServiceCallSite)new CreateInstanceCallSite(_descriptor) :
new ConstructorCallSite(bestConstructor, parameterCallSites);
}
}
+1
ありがとう、私が探していたもの –
関連する問題
- 1. DIコンテナは工場にどのようなメリットをもたらしますか?
- 2. DIコンテナはこの
- 3. IoC/DIコンテナが「コンテナ」と呼ばれるのはなぜですか?
- 4. DDDのドメインインフラストラクチャサービス用にDIコンテナを設定する必要はありますか?
- 5. Windows MobileアプリケーションのIoC/DIコンテナ
- 6. RESTクライアントのPHP - DIコンテナ
- 7. 単体テストでのDIコンテナの使用
- 8. コンテナがC++に必要です
- 9. コンテナにはどのようなタイプがありますか?
- 10. ビットマップにはどのようなコンテナを使用しますか?
- 11. コンテナ要素内に含まれていない要素
- 12. Castle Windsorコンテナはどのように入手できますか?
- 13. 私はなぜiocコンテナが必要なのですか
- 14. Dockerコンテナ内のディレクトリを別のコンテナからアクセスできるようにする
- 15. dom/css:コンテナに複数の100%コンテナをコンテナに入れてビューポート(100%)より大きくする
- 16. ASP.NET 5とビルトインされたDIコンテナのリクエストごとのスコープ
- 17. JSFのバージョンはどのようなものですか?コンテナかfaces-config?
- 18. コンテナの要素によってコンテナ(タプル、リスト、辞書)のリストをインデックスする方法はありますか?
- 19. DIコンテナを(ほぼ)各クラスに注入するアンチパターンですか?
- 20. コンテナグループとコンテナをどのようにリンクできますか?
- 21. コンテナを変更せずにコンテナの高さを100%にする
- 22. YarnException:許可されていないコンテナの開始要求
- 23. 小さいコンテナ内で大きなコンテナをオーバーフローさせてセンタリングする
- 24. Webコンテナ、Webコンテナ、埋め込みWebコンテナに展開する
- 25. EJBコンテナとWebコンテナのJPA
- 26. CSS:最初のdivをコンテナの外に出すのではなく、コンテナの外に出す(最初のコンテナの後に2番目のコンテナを表示する)
- 27. PHPでDIコンテナを手動で作成/使用しますか?
- 28. STLコンテナから要素を移動すると、そのコンテナから要素が削除されますか?
- 29. STLはどのようにコンテナの終わりを知っていますか?
- 30. コンテナへのアクセスが必要なときに、コンテナ自体の代わりにイテレータを返す
複数のコンストラクタを持つタイプをサポートしています。 – Nkosi
@Nkosi:現在のrc1は、複数のコンストラクタを持つ型を受け入れません。 – Steven
間違ったコードを見ていますか?私が読んでいるコードを誤解している可能性があります。 https://github.com/aspnet/DependencyInjection/blob/4f2e6f035662b73936a2ed4fc249c163c9978c91/src/Microsoft.Extensions.DependencyInjection/ServiceLookup/Service.cs – Nkosi