سؤال

دعنا نقول أن لدي كيان مستخدم وأريد ضبط خاصية CreateTime في المُنشئ إلى DateTime.ar. لكن كوني اختبارًا للوحدة ، لا أريد الوصول إلى DateTime. الآن ولكن استخدم itimeprovider:

public class User {
    public User(ITimeProvider timeProvider) {
        // ...
        this.CreationTime = timeProvider.Now;
    }

    // .....
}

public interface ITimeProvider { 
    public DateTime Now { get; }
}

public class TimeProvider : ITimeProvider {
    public DateTime Now { get { return DateTime.Now; } }
}

أنا أستخدم Ninject 2 في تطبيق ASP.NET MVC 2.0 الخاص بي. لديّ UserController وطريقتين إنشاء (واحدة لـ Get وواحدة للنشر). الشخص الذي يحصل على جائزة مستقيمة إلى الأمام ، لكن واحد للنشر ليس مستقيمًا جدًا وليس إلى الأمام: P لأنني بحاجة إلى العبث مع الموثق النموذجي لأخبره للحصول على مرجع لتنفيذ ItimeProvider حتى أتمكن من بناء مثيل المستخدم.

public class UserController : Controller {

    [HttpGet]
    public ViewResult Create() {
         return View();
    }

    [HttpPost]
    public ActionResult Create(User user) {

         // ...

    }
}

أود أيضًا أن أكون قادرًا على الاحتفاظ بجميع ميزات موثق الطراز الافتراضي.

أي فرصة لحل هذا بسيط/أنيق/إلخ؟ :د

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

المحلول

ماذا عن بدلا من استخدام ITimeProvider جرب هذا:

public class User 
{
    public Func<DateTime> DateTimeProvider = () => DateTime.Now;

    public User() 
    {
        this.CreationTime = DateTimeProvider();
    }
}

وفي اختبار وحدتك:

var user = new User();
user.DateTimeProvider = () => new DateTime(2010, 5, 24);

أعلم أن هذا ليس أنيقًا للغاية ، ولكن بدلاً من العبث مع الموثق النموذجي ، قد يكون هذا حلًا. إذا لم يكن هذا هو الحل الجيد ، فيمكنك تنفيذ موثق نموذج مخصص وتجاوز CreateModel الطريقة التي يمكنك فيها حقن التبعيات في مُنشئ النموذج.

نصائح أخرى

بعض الملاحظات:

لا تضخ التبعيات فقط للاستعلام عنها في المنشئ

لا يوجد سبب لحقن itimeprovider في مستخدم فقط للاستدعاء Now في الحال. فقط حقن وقت الخلق مباشرة بدلاً من ذلك:

public User(DateTime creationTime)
{
     this.CreationTime = creationTime;
}

قاعدة جيدة حقًا تتعلق بـ DI يجب على المُنشئين أداء أي منطق.

لا تستخدم DI مع ModelBinders

يعد ASP.NET MVC Modelbinder مكانًا سيئًا حقًا للقيام به ، خاصةً لأنه لا يمكنك استخدام حقن المنشئ. الخيار الوحيد المتبقي هو محدد خدمة ثابتة لمكافحة النشرات.

يترجم نموذج نموذج HTTP وينشر المعلومات إلى كائن مكتوب بقوة ، ولكن من الناحية المفاهيمية هذه الأنواع ليست كائنات مجال ، ولكنها تشبه كائنات نقل البيانات.

حل أفضل بكثير لـ ASP.NET MVC هو التخلي عن طرازات مخصصة تمامًا وبدلاً من ذلك احتضان صراحة أن ما تتلقاه من اتصال HTTP هو ليس كائن المجال الكامل الخاص بك.

يمكنك الحصول على بحث بسيط أو Mapper لاسترداد كائن المجال الخاص بك في وحدة التحكم الخاصة بك:

public ActionResult Create(UserPostModel userPost)
{
    User u = this.userRepository.Lookup(userPost);
    // ...
}

أين this.userRepository هو التبعية المحقونة.

هناك خيار آخر هو إنشاء فئة مختلفة لتمثيل المستخدمين الذين لم يتم استمرارهم بعد أن لا يحتوي على خاصية تاريخ إنشاء على الإطلاق.

حتى لو CreationDate هو واحد من User'shariants ، يمكن أن تكون قابلة للبطولة في نموذج العرض الخاص بك - ويمكنك ضبطه بعيدًا عن المصب ، في وحدة التحكم أو طبقة المجال.

بعد كل شيء ، ربما لا يهم ، ولكن إذا تمثل سمة تاريخ الإنشاء لحظة لك حقًا بناء مثيل المستخدم, ، أم أنه سيكون من الأنسب أن يمثل اللحظة التي يقدم فيها المستخدم بياناته؟

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