WindsorContainerで非常に奇妙な動作をします。
コンテナをこのように構成しました。
Container = new WindsorContainer();
Container.Kernel.ComponentModelCreated += KernelComponentModelCreated;
Container.Install(FromAssembly.This());
private static void KernelComponentModelCreated(ComponentModel model)
{
if (model.LifestyleType == LifestyleType.Undefined)
model.LifestyleType = LifestyleType.Transient;
}
ですから、ライフスタイルを指定していないコンポーネントはすべて一過性のライフスタイルになると思っていたので、今まで問題はなかったようです。
いくつかのコンポーネントをすべて解決する複数の非同期タスクを開始します。(したがって、すべてのタスクがコンポーネントの新しいインスタンスを取得することを期待します)
ただし、コンポーネントのクロススレッドの問題が原因でタスクが失敗するため、タスクが新しいインスタンスを取得しないことがわかりました。(したがって、複数のタスクで使用されています)
Container.Resolve(somecomponent);を交換すると 新しいコンポーネントを適切に作成するだけで、すべてが正常に機能します。
var contextProvider = MvcApplication.Container.Resolve<IDbContextProvider>();
交換された
var contextProvider = new DbContextProvider();
だから私の質問は、私がここで何が欠けているのかということです。
明示的に設定されているため、タスクは一時的に設定されたMVC3コントローラで開始されます。
上記のコードにより、DbContextProviderは、一時的に構成されたすべてのリポジトリーで解決されます。
私がドキュメントで見つけたもう1つのことはです。一時的なコンポーネントを解放する必要があります。IDisposableを使用してすべてのコンポーネントを実装しました。しかし、コントローラーに自動コンストラクターインジェクションがあるため、手動でリリースする必要があるかどうかは完全にはわかりません。リリースする必要がある場合は、どうすればこれを実行できますか。(はい、コンテナーでReleaseメソッドを呼び出す必要があることはわかっています)
アップデート
以下のコードは、コントローラーのリリースと解決を担当します。
public class WindsorControllerFactory : DefaultControllerFactory
{
private readonly IKernel _kernel;
public WindsorControllerFactory(IKernel kernel)
{
_kernel = kernel;
}
public override void ReleaseController(IController controller)
{
_kernel.ReleaseComponent(controller);
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
}
return (IController)_kernel.Resolve(controllerType);
}
}
すべての依存関係が解決され、本来あるべき方法でリリースされているかどうかをテストするために利用できる例はありますか?(ライフスタイルテスト)