Frage

Lassen Sie sich sagt, dass ich einen Benutzer Einheit habe und ich würde es die Eigenschaft Creation im Konstruktor DateTime.Now festlegen möge. Aber ein Unit-Test ist adopter Ich möchte nicht den Zugriff auf DateTime.Now direkt, sondern eine ITimeProvider verwenden:

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; } }
}

Ich bin mit ninject 2 in meiner ASP.NET MVC 2.0-Anwendung. Ich habe einen Usercontroller und zwei erstellen Methoden (eine für GET und eine für POST). Die ein für GET ist gerade nach vorne, aber die für POST ist nicht so gerade und nicht so vorwärts: P, weil ich mit dem Modell Bindemittel zu verwirren muss ihm sagen, eine Referenz für eine Implementierung von ITimeProvider zu erhalten, um zu konstruieren zu können, eine Benutzerinstanz.

public class UserController : Controller {

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

    [HttpPost]
    public ActionResult Create(User user) {

         // ...

    }
}

Ich möchte auch alle die Eigenschaften des Standardmodells Bindemittel halten können.

Jede Chance, diesen einfachen / elegant / etc zu lösen? : D

War es hilfreich?

Lösung

Wie wäre es stattdessen eine ITimeProvider der Verwendung versuchen Sie dies:

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

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

Und in Ihrem Gerät zu testen:

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

Ich weiß, dass dies nicht sehr elegant ist, sondern mit dem Modell Messing Binder dies eine Lösung sein könnte. Wenn dies wie eine gute Lösung nicht das Gefühl kann man ein eigenes Modell Bindemittel implementieren und die Create Verfahren, in dem Sie die Abhängigkeiten in dem Konstruktor des Modells injizieren würden.

Andere Tipps

Ein paar Beobachtungen:

Nicht injizieren Abhängigkeiten nur um sich im Konstruktor abfragen

Es gibt keinen Grund, eine ITimeProvider in einem Benutzer zu injizieren nur Now sofort aufzurufen. injiziert nur die Erstellungszeit direkt statt:

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

Eine wirklich gute Faustregel gilt: DI Zusammenhang ist, dass die Konstrukteure keine Logik durchführen sollte .

Verwenden DI nicht mit Modelbinder

Eine ASP.NET MVC ist ein Modelbinder wirklich schlecht Ort DI zu tun, vor allem, weil Sie nicht Constructor Injection verwenden können. Die einzige verbleibende Option ist das statische Service Locator anti-Muster .

Ein Modelbinder übersetzt HTTP GET und POST-Informationen zu einem stark typisierte Objekt, aber konzeptuell Diese Typen sind nicht Domain-Objekte, aber ähnlich wie Datenübertragung Objekte .

Eine viel bessere Lösung für ASP.NET MVC ist benutzerdefinierten Modelbinder vollständig zu verzichten und stattdessen explizit umarmt das, was Sie von der HTTP-Verbindung empfangen ist nicht Ihr vollständiges Domain-Objekt .

Sie können eine einfache Lookup oder Mapper, um Ihre Domain-Objekt in Ihrem Controller abrufen:

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

Dabei gilt this.userRepository eine injiziert Abhängigkeit.

Eine weitere Möglichkeit ist eine andere Klasse erstellen Benutzer darzustellen, die nicht gewesen sein beharrten noch nicht ein Erstellungsdatum Eigentum überhaupt nicht hat.

Auch wenn CreationDate eine von User der Invarianten, kann es Ihrer Ansicht nach Modell nullable sein -. Und Sie können einstellen, es weiter stromabwärts, in dem Controller oder Domänenschicht

Schließlich tut es wahrscheinlich keine Rolle, sollte aber das Erstellungsdatum Attribut wirklich den Moment stellen Sie eine Benutzerinstanz konstruieren , oder wäre es sinnvoller sein, für den Moment, für einen Benutzer trägt ihre Daten?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top