ASP.NET Web APIでは、HttpControllerContext インスタンスは、現在の要求の URI など、現在の環境に関する多くの情報を提供します。
サービスがそのような情報 (リクエスト URI など) に依存している場合、その情報をサービスに挿入できる必要があります。
これは、Poor Man の DI を使用して行うのは非常に簡単です。カスタムの IHttpControllerActivator を実装するだけです。
しかし、Castle Windsor では、これが突然非常に難しくなります。以前、この問題を解決する非常に複雑な方法について説明しましたが、それは PerWebRequest のライフスタイルに依存しており、HttpContext.Current が空であるため、このライフスタイルはセルフホスティング シナリオでは機能しないことが判明しました。
これまでのところ、必要な情報をインライン引数としてカスタム IHttpControllerActivator から Resolve メソッドに渡すことで、これを機能させることができました。
public IHttpController Create(
HttpControllerContext controllerContext,
Type controllerType)
{
var baseUri = new Uri(
controllerContext
.Request
.RequestUri
.GetLeftPart(UriPartial.Authority));
return (IHttpController)this.container.Resolve(
controllerType,
new { baseUri = baseUri });
}
ただし、デフォルトでは、これはすぐに要求された型が引数に依存している場合 (つまり、要求された Controller 自体が に依存している場合baseUri
) にのみ機能します。依存関係baseUri
が依存関係階層の奥深くに埋もれている場合、インライン引数がより深い層に伝播されないため、デフォルトでは機能しません。
この動作は、カスタム IDependencyResolver (ASP.NET Web API IDependencyResolver ではなく、Castle Windsor IDependencyResolver) で変更できます。
public class InlineDependenciesPropagatingDependencyResolver :
DefaultDependencyResolver
{
protected override CreationContext RebuildContextForParameter(
CreationContext current, Type parameterType)
{
if (parameterType.ContainsGenericParameters)
{
return current;
}
return new CreationContext(parameterType, current, true);
}
}
デフォルトの実装であるではなく、 がコンストラクタ引数true
として渡されていることに注意してください。propagateInlineDependencies
false
コンテナー インスタンスを InlineDependenciesPropagatingDependencyResolver クラスと結び付けるには、次のように構築する必要があります。
this.container =
new WindsorContainer(
new DefaultKernel(
new InlineDependenciesPropagatingDependencyResolver(),
new DefaultProxyFactory()),
new DefaultComponentInstaller());
これがこの問題に対する最善の解決策なのか、それとももっと簡単な方法があるのか 疑問に思っていますか?