ASP.NETWebAPIを使用してCastleWindsorをセットアップしようとしています。
Hyprlinkrパッケージ(https://github.com/ploeh/Hyprlinkr)も使用しているため、コントローラーの依存関係の1つにHttpRequestMessageのインスタンスを挿入する必要があります。
Mark Seemannによるこの記事をフォローしています-http ://blog.ploeh.dk/2012/04/19/WiringHttpControllerContextWithCastleWindsor.aspxですが、APIは実行されていますが、APIを呼び出すと、リクエストはハングします。エラーメッセージはありません。まるで無限ループに入っているかのようです。カスタムControllerActivatorでResolveの呼び出しがハングしています
Castleの登録の一部が間違っていると思います。上記の記事に記載されているものを削除すると、APIを正常に呼び出すことができます(解決する必要のある依存関係はありませんが)
何か案は?
コードは以下です
//Global.asax
public class WebApiApplication : HttpApplication
{
private readonly IWindsorContainer container;
public WebApiApplication()
{
container =
new WindsorContainer(
new DefaultKernel(
new InlineDependenciesPropagatingDependencyResolver(),
new DefaultProxyFactory()),
new DefaultComponentInstaller());
container.Install(new DependencyInstaller());
}
protected void Application_Start()
{
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new WindsorCompositionRoot(this.container));
}
// installer
public class DependencyInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.AddFacility<TypedFactoryFacility>();
container.Register(
Component.For<ValuesController>()
.Named("ValuesController")
.LifeStyle.PerWebRequest,
Component.For<IResourceLinker>()
.ImplementedBy<RouteLinker>()
.LifeStyle.PerWebRequest,
Component.For<IResourceModelBuilder>()
.ImplementedBy<ResourceModelBuilder>()
.LifeStyle.PerWebRequest,
Component.For<HttpRequestMessage>()
.Named("HttpRequestMessage")
.LifeStyle.PerWebRequest
);
}
}
//Activator
public class WindsorCompositionRoot : IHttpControllerActivator
{
private readonly IWindsorContainer container;
public WindsorCompositionRoot(IWindsorContainer container)
{
this.container = container;
}
public IHttpController Create(
HttpRequestMessage request,
HttpControllerDescriptor controllerDescriptor,
Type controllerType)
{
var controller = (IHttpController)this.container.Resolve(controllerType, new { request = request });
request.RegisterForDispose(
new Release(
() => this.container.Release(controller)));
return controller;
}
// DependencyResolver
public class InlineDependenciesPropagatingDependencyResolver : DefaultDependencyResolver
{
protected override CreationContext RebuildContextForParameter(CreationContext current, Type parameterType)
{
if (parameterType.ContainsGenericParameters)
{
return current;
}
return new CreationContext(parameterType, current, true);
}
}
編集***********追加情報****************
そこで、コントローラーがHttpRequestMessageをctor引数として受け取るシナリオを設定し、次のことを見つけました。
これは機能します:
//controller
public class ValuesController : ApiController
{
private readonly HttpRequestMessage _httpReq;
public ValuesController(HttpRequestMessage httpReq)
{
_httpReq = httpReq;
}
//IHttpControllerActivator
public IHttpController Create(
HttpRequestMessage httpRequest,
HttpControllerDescriptor controllerDescriptor,
Type controllerType)
{
var controller = (IHttpController)this.container.Resolve(
controllerType, new { httpReq = httpRequest });
return controller;
ただし、これはそうではありません。
//controller
public class ValuesController : ApiController
{
private readonly HttpRequestMessage _httpReq;
public ValuesController(HttpRequestMessage request)
{
_httpReq = request;
}
//IHttpControllerActivator
public IHttpController Create(
HttpRequestMessage request,
HttpControllerDescriptor controllerDescriptor,
Type controllerType)
{
var controller = (IHttpController)this.container.Resolve(
controllerType, new { request = request });
return controller;
つまり、anonオブジェクトに「request」というプロパティがあり、コントローラーのctorargが「request」と呼ばれる場合です。どういうわけか、コントローラーに要求プロパティがnullであると思わせています。これが私が見るエラーの原因です:
'ApiController'インスタンスを再利用できません。「ApiController」は、着信メッセージごとに作成する必要があります。カスタムの「IHttpControllerActivator」をチェックして、同じインスタンスを作成しないことを確認してください。
System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext、CancellationToken cancelToken)at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal(HttpRequestMessage request、CancellationToken cancelToken)at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(HttpRequestMessageリクエスト、CancellationToken cancelToken)
これを読んでください セッターインジェクションを呼び出さずにStructureMapでオブジェクトコンポジションを強化するにはどうすればよいですか?
同様のシナリオを説明しています。
もちろん、hyprlinkrには「request」と呼ばれるHttpRequestMessageのctor argがあるので、そのプロパティ名でanonオブジェクトを指定する必要があります。
何か案は?