2016-10-31 2 views
0

Ich rende eine Create.cshtml, die mit einem neuen ViewModel() geliefert wird. Bevor ich das Formular abschicke, möchte ich Ajax verwenden, um den Preis zu berechnen. Mein Ansichtsmodell kann weder berechnen noch möchte ich die Funktionalität duplizieren. Dieses Verhalten beruht im Domänenmodell auf der Kapselung.Korrekte Möglichkeit, Logik zwischen Domänenmodell und Ansichtsmodell zu teilen

Mit Ajax möchte ich eine 'Calculate' Aktionsmethode auf einem Controller aufrufen, die dem Benutzer einen Gesamtpreis vor dem Ausfüllen des Formulars selbst gibt (bevor das Domain Model jemals erstellt wurde).

Wie kann ich diese Funktionalität erreichen, ohne die Verkapselung zu unterbrechen?

Hinweis: Später wird das DomainModel verwendet, um vor dem Warenkorb/Zahlung/Verarbeitung zu berechnen.

public class DomainModel 
{ 
public int Id { get; set; } 
public int Quantity { get; set; } 
public decimal Price { get; set; } 

public decimal Calculate() 
{ 
    return Quantity*Price; 
} 
} 

public class ViewModel 
{ 
    [Required] 
    public int Id { get; set; } 
    [Required] 
    public int Quantity { get; set; } 
    public decimal Price { get; set; 
} 
+0

diskutierte ich mit einem Kollegen über das Berechnen platzieren() in eine Basisklasse, mit Parametern, anstatt mit den Klassen eigene Eigenschaften. Die Basisklasse kann sowohl von Domänen- als auch von Ansichtsmodellen geerbt werden, aber das fühlt sich einfach falsch an. – ManxJason

+0

Sie können die Verantwortung für das Ausführen dieser Berechnungen an eine separate Klasse (TotalCalculator) delegieren und dann eine Instanz dieser Klasse im DomainModel und im ViewModel verwenden, um die Berechnung durchzuführen. d.h. Verwendung der Zusammensetzung anstelle der Vererbung. – AdaTheDev

+0

@AdaTheDev Was wäre der Unterschied zu Ihrer Methode und einem statischen Rechner? Was bringt es, eine Instanz in diesem Fall zu haben? – ManxJason

Antwort

1

Sie können Schnittstellenerweiterungen verwenden und dann jeweils eine bestimmte Schnittstelle implementieren. Zum Beispiel:

public interface MyAwesomeInterface 
{ 
    int Quantity { get; } 
    decimal Price { get; } 
} 

Dann:

public class DomainModel : MyAwesomeInterface 

public class ViewModel : MyAwesomeInterface 

Endlich:

public static class MyAwesomeInterfaceExtensions 
{ 
    public static Calculate(this MyAwesomeInterface foo) 
    { 
     return foo.Quantity * foo.Price; 
    } 
} 
+0

Das kam mir nicht in den Sinn, und es ist viel sauberer als der ursprüngliche Ansatz der Basisklasse. Danke noch einmal. – ManxJason

Verwandte Themen