3

ASP.NET MVC で Spring.NET IoC 機能を利用するデモに取り組んでいます。これは、www.asp.net サイトのペア プログラミング ビデオ チュートリアルで紹介されている MyBlog アプリケーションのようなものです。Microsoft の Unity フレームワークを使用して同じデモを完了したので、Spring コンテナーを試してみたいと思います。そのために、最初に Spring オブジェクト ファクトリを次のように作成する単純な IControllerFactory を実装しました。

IObjectFactory factory;
(....)
factory = new XmlObjectFactory(new FileSystemResource(application.Server.MapPath("objects.xml")))

次に、次のようにそのファクトリからコントローラーを取得します。

public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) {
    IController result = context.GetObject(controllerName) as IController;
    return result;
}

(簡略化のためにエラー処理を省略しています)。

今私の HomeController のどこかに私はこの種のアクションを持っています:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddEntry([Bind] BlogEntry entry, int id) {
    entry.EntryDate = DateTime.Now;
....

そして、エントリ パラメーター (本当に基本的なもの) のエディターを定義する AddEntry.aspx ビューの一部を次に示します。

<form method="post" action="/Home/AddEntry/<%= ViewData["id"] %>">
    <table>
        <tr>
            <td><label for="Title">Title</label></td>
            <td><input name="entry.Title" type="text"/></td>
        </tr>
        <tr>
            <td><label for="Text">Content</label></td>
            <td><input name="entry.Text" type="text"/></td>
        </tr>
    </table>
    <br />
    <input type="submit" value="Add entry" />
    <input type="button" value="Cancel" onclick="history.back(-1);" />
</form>

Unity IoC を使用しているときは、魅力的に機能します。「エントリ」パラメーターは、本来のようにフォームから逆シリアル化され、行

entry.EntryDate = DateTime.Now; 

問題なく完了します。

しかし、Spring.NET オブジェクト ファクトリ (上記のように) に切り替えると、事態はおかしくなり始めます。まず、パラメータ「entry」が null になるため、例外がスローされます。私の側で考えられる問題を追跡するために、次のようなカスタム IModelBinder を実装しました。

public class BlogEntryBinder : IModelBinder {
    public ModelBinderResult BindModel(ModelBindingContext bindingContext) {
        ModelBinderResult result = ModelBinders.DefaultBinder.BindModel(bindingContext);
        return result;
    }
}

Unity フレームワークを使用してここに来て、bindingContext から HttpRequest にドリルダウンすると、Request.HttpMethod が「POST」であり、Request.Form が適切に入力されていることがわかります。Spring.NET を使用して同じことを行うと、メソッドは「GET」になり、Request.Form は空になります。ただし、コントローラー アクション (AddEntry) に進み、両方の状況で Request にドリルダウンすると、Request.HttpMethod と Request.Form に適切な値があることがわかります。

問題は、Spring.NET でバージョンを修正して、Unity フレームワークを使用するバージョンと同じように機能させるにはどうすればよいかということです。

4

2 に答える 2

4

私は答えを見つけました!

私のオブジェクト定義は次のようになりました:

<!-- Controlers -->
<object name="Home" type="MyBlog.Controllers.HomeController">
    <property name="BlogService" ref="BlogService" />
    <property name="BlogEntryService" ref="BlogEntryService" />
    <property name="BlogEntryCommentService" ref="BlogEntryCommentService" />
</object>

設定されているプロパティが実際に何をするかは気にしないでください。

IController result = context.GetObject(controllerName) as IController;

したがって、定義を次のように変更すると、

<!-- Controlers -->
<object name="Home" type="MyBlog.Controllers.HomeController" singleton="false">
    <property name="BlogService" ref="BlogService" />
    <property name="BlogEntryService" ref="BlogEntryService" />
    <property name="BlogEntryCommentService" ref="BlogEntryCommentService" />
</object>

すべてがうまくいき始めました。

よろしく、マティアス。

于 2008-12-29T21:35:41.057 に答える
2

この動作を明確にするための追加のメモ: コントローラーは ASP.NET MVC フレームワークによってプロトタイプとして扱われますが、Spring はデフォルトでシングルトン モードになります。したがって、コンテナー構成でオブジェクトを非シングルトンとして明示的にマークする必要があります。今後の Spring MVC 統合モジュールがこれを処理するため、これに遭遇することはありません。

hth、エーリッヒ

于 2009-01-04T17:47:28.430 に答える