Page クラスもプレゼンターも、その依存関係の構築またはライフサイクルの管理を直接処理する必要はありません。これらはすべて、コンテナーによって処理される必要があります。コンストラクター インジェクションは WebForms では機能しないため、必要な依存関係をクラスのプロパティとして公開する必要があります。たとえば、クラスを次のように変更できます。
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
public _DefaultPresenter Presenter { get; set; }
}
ページはプレゼンターに挿入されるため、リポジトリへの参照は必要ありません。
この回答の残りの部分は StructureMap に固有のものです。詳細は他のコンテナーでは異なる場合があります。
セッター インジェクションを有効にするには、データを入力するプロパティを StructureMap に指示する必要があります。1 つの方法は、[SetterProperty] 属性をプロパティ自体に適用することです。ただし、クラス内に StructureMap の詳細を含めると、少し侵略的に感じる可能性があります。もう 1 つの方法は、注入するプロパティ タイプを認識できるように StructureMap を構成することです。例えば:
protected void Application_Start(object sender, EventArgs e)
{
ObjectFactory.Initialize(x =>
{
x.Scan(scan =>
{
scan.TheCallingAssembly();
scan.WithDefaultConventions();
});
x.ForRequestedType<IRepository>().TheDefaultIsConcreteType<Repository>().CacheBy(InstanceScope.Hybrid);
x.SetAllProperties(set => set.WithAnyTypeFromNamespaceContainingType<IRepository>());
});
}
SetAllProperties メソッドを使用すると、StructureMap に入力する必要があるプロパティを認識する方法を伝えることができます。この場合、StructureMap にすべてのプレゼンターを注入するように指示しています (プレゼンターがすべて同じ名前空間にあると仮定します)。
リクエストごとに setter インジェクションを実行する必要があります。StructureMap では、BuildUp() メソッドを使用して依存関係を既存のインスタンスに注入します。各ページまたはページの基本クラスの Init イベントまたは Load イベントで実行できますが、これも侵略的です。コンテナーをページ クラスから完全に除外するには、アプリケーションの PreRequestHandlerExecute イベントを (global.asax または IHttpModule で) 使用できます。
protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
var application = (HttpApplication)sender;
var page = application.Context.CurrentHandler as Page;
if (page == null) return;
ObjectFactory.BuildUp(page);
}
最後に、IRepository を明示的に Dispose したい場合は、EndRequest イベントでそれを処理できます。
protected void Application_EndRequest(object sender, EventArgs e)
{
var disposable = ObjectFactory.GetInstance<IRepository>() as IDisposable;
if (disposable != null) disposable.Dispose();
}
これは正しく機能することに注意してください。これは、初期化で StructureMap に Hybrid によって IRepository をキャッシュするように指示したためです。これは、「各 HTTP リクエスト (または Web サイト内で実行されていない場合はスレッド) ごとに同じインスタンスを提供する」ことを意味します。EndRequest で IRepository を取得すると、リクエスト全体で使用されたものと同じものを受け取り、それを破棄できます。