2

私の MVC 4 プロジェクトでは、次のようなモデルがあります。

public class MyModel
{
    private readonly IService MyService;

    public MyModel([Dependency]IService service)
    {
        this.MyService = service;
    }
    // ...
}

私のコントローラーには、次のような HttpPost であるアクションがあります。

[HttpPost]
public ActionResult Show(MyModel myModel)
{
    // do stuff

私のコントローラーには、私の IoC コンテナーのインスタンスがありません (そしてすべきではありません)。HttpPost が発生してアクションが呼び出されると、MVC はモデル バインディングを実行するときにモデルのインスタンスを作成しようとします。そのためには、パラメーターなしのコンストラクターが必要です。デフォルトのコンストラクターを使用してモデルを作成する場合、MyService は設定されず、モデルにはすべての依存関係が存在しません。myModel.Init(someIServiceInstance) を呼び出す必要はありません。モデルの作成時に依存関係が解決される (正しいコンストラクターが呼び出される) ように、フレームワークにプラグインしたいと考えています。

現在、Unity を依存関係リゾルバーとして使用しており、コントローラー、サービス クライアントなどのファクトリーをいくつか持っています。コントローラーについては、ControllerFactory を登録して依存関係をコントローラーに渡すことができましたが、登録できるModelFactory。私はバインディング プロセス自体にはあまり関心がありません。モデルがインスタンス化されると、バインドがどのように行われるかに満足しています。モデルの作成/構築方法を実装したいだけです。依存関係を解決するために ModelFactory がコンテナーへの参照を使用する場合も問題ありません (コンストラクターへのパラメーターとしてコンテナーをファクトリに挿入できます。コントローラーに直接参照を持たせたくないだけです)。コンテナ)。

モデルの作成を処理し、残りのバインディング プロセスを実行するためにフレームワークの実装に依存する ModelFactory (または ModelBinder、および/または ModelBinderResolver など) のサンプルを持っている人はいますか?

4

2 に答える 2

4

カスタム モデル バインダーを作成できます。

public class MyModelModelBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        // TODO: create the model instance here using your DI framework or the 
        // DependencyResolver which is more correct
    }
}

次に、このモデル バインダーを に登録しますGlobal.asax

ModelBinders.Binders.Add(typeof(MyModel), new MyModelModelBinder());

しかし、通常、これは悪い習慣です。ビュー モデルを使用し、コントローラー アクションでビュー モデルをパラメーターとして受け取り、ビュー モデルをビューに渡すことをお勧めします。これらのビュー モデルには、パラメーターのないコンストラクターがあります。そして、ドメイン モデルまたはリポジトリをコントローラー コンストラクターに挿入することができます。

于 2012-10-18T16:06:07.010 に答える
2

私はそれを理解したと思います:

public class MyModelBinder : DefaultModelBinder
{
    private readonly UnityContainer container;

    public MyModelBinder(UnityContainer container)
    {
        this.container = container;
    }

    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        if (modelType == null)
        {
            return base.CreateModel(controllerContext, bindingContext, null);
        }

        return this.container.Resolve(modelType);
    }
}

また、Global.asax、Application_Start() 内、または IoC 構成で:

ModelBinders.Binders.Add(typeof(object), new MyModelBinder(container));
于 2012-10-18T17:19:25.000 に答える