すべてのメソッドで「var thing = thingFactory.Get(id)」行を削除するためにコントローラーに Thing を挿入しようとしている場合は、ASP.NET MVC カスタム モデル バインダーを使用して、開始前に取得を実行できます。メソッドコード。
ルートが /{controller}/{action}/{id} のようになっている場合、id で値を検索します。
モデル バインディングにより、メソッド シグネチャは次のようになります。
public ActionResult SomeDetails(int id, Thing thing)
{
モデル バインディングと検証は、メソッド コードが実行される前に発生します。DefaultModelBinder は、FormCollection またはその他の非永続的なソースからのみクラスを設定します。
私がお勧めする秘訣は、ルックアップを実行する Thing クラスにカスタム モデル バインダー (IModelBinder) を提供することです。DefaultModelBinder から派生させ、IThingFactory を注入し、BindModel() をオーバーライドして、独自の方法でルックアップを行います。
public class ThingModelBinder : DefaultModelBinder
{
IThingFactory ThingFactory;
public ThingModelBinder(IThingFactory thingFactory)
{
this.IThingFactory = thingFactory;
}
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
Thing thing = new Thing();
string id_string = controllerContext.RouteData.Values["id"].ToString();
int id = 0;
Int32.TryParse(id_string, out id);
var thing = thingFactory.Get(id);
return thing;
}
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException("bindingContext");
}
// custom section
object model = this.CreateModel(controllerContext, bindingContext, typeof(Thing));
// set back to ModelBindingContext
bindingContext.ModelMetadata.Model = model;
// call base class version
// this will use the overridden version of CreateModel() which calls the Repository
// object model = BindComplexModel(controllerContext, bindingContext);
return base.BindModel(controllerContext, bindingContext);
}
次に、既にコンテナーを作成している global.asax Application_Start() でモデル バインダーを構成します。
// Custom Model Binders
System.Web.Mvc.ModelBinders.Binders.Add(
typeof(MyCompany.Thing)
, new MyMvcApplication.ModelBinders.ThingModelBinder(
WindsorContainer.Resolve<IThingFactory>()
)
);
これにより、カスタム モデル バインダーが呼び出されます。
通常の方法で Windsor の依存関係を解決します。
これは、私が行った投稿に基づいています。