سؤال

أنا أعمل على تجريبي يستفيد من قدرة SPRING.NET IOC في ASP.NET MVC. إنه نوع من مثل تطبيق MyBlog الذي تم تقديمه على برنامج تعليم الفيديو برمجة الزوج على موقع www.asp.net. لقد أكملت نفس التجريبي باستخدام إطار الوحدة في Microsoft والآن تريد تجربة حاوية الربيع. لتحقيق هذه الغاية، قمت بتطبيق icontrollerolleroledory بسيط يخلق مصنع كائن الربيع هكذا:

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>

الآن ها هي الصفقة: عندما أستخدم الوحدة IOC، فإنه يعمل مثل سحر. معلمة "الدخول" يحصل على تحل محل من النموذج الخاص بي كما يجب وطرد الخط

entry.EntryDate = DateTime.Now; 

يكمل دون مشاكل.

ومع ذلك، عندما أتحول إلى مصنع كائن Spring.net (أعجبني أعلاه) تبدأ الأمور في الذهاب للمكسرات. أولا وقبل كل شيء "الإدخال" يتحول إلى NULL بحيث يتم طرح استثناء. لتتبع المشكلة المحتملة في نهايتي قمت بتنفيذ نوع من IMODELBINDER المخصصة التي تبدو وكأنها:

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

عندما أتيت إلى هنا باستخدام إطار الوحدة والحفر من BindingContext إلى HTTPRECTEST، أرى أن الطلب. HttpMethod هو "المشاركة" والطلب. عندما أفعل نفس الشيء باستخدام SPRING.NET الطريقة "الحصول عليها" والطلب.form فارغ. عندما أخطو إلى إجراء جهاز التحكم الخاص بي (AddEntry) والحفر لأسفل على الطلب في كلتا الحالتين، أرى أن الطلب. HTTPMethod والطلب كذلك.

الآن السؤال هو كيف يمكنني إصلاح الإصدار مع Spring.net بحيث يعمل تماما مثل الشخص الذي يستخدم إطار الوحدة؟

هل كانت مفيدة؟

المحلول

لقد وجدت الجواب!

بدا تعريف كائني هكذا:

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

neverMind الخصائص التي يجري تعيين ما هو في الواقع هو إرجاع نفس الحالة في كل مرة أطلبها هذا الكائن

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>

كل شيء بدأ العمل على ما يرام.

مع أطيب التحيات، ماتياس.

نصائح أخرى

مجرد ملاحظة إضافية لتوضيح هذا السلوك: يتم التعامل مع وحدات تحكم كتاجر النماذج الناتجة عن طريق إطار ASP.NET MVC، ولكن الافتراضات الربيعية إلى وضع Singleton. لذلك تحتاج إلى وضع علامة كائن الخاص بك بشكل صريح كغير Singleton في تكوين الحاوية. ستعتني وحدة تكامل الربيع MVC القادمة بهذا، لذلك لن ترشح ذلك بعد ذلك.

HTH، إيريتش

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top