Ho appena iniziato a utilizzare e mi sto innamorando del modello di progettazione MVC.MVC Riduzione del codice ripetitivo
Il mio unico cruccio è che sembra produrre un sacco di codice ripetitivo. Per esempio.
Ho una MVC App standard con il mio DB (modelli) in un progetto, separato dai miei controller/viste/viewmodels in un altro, nuovamente separato dai miei metodi di test in un altro. Tutto funziona alla grande.
Modelli: Ora ho un bel po 'di belle classi EF4 nel mio progetto DB, che devo usare ViewModels per il mio vero progetto per accedere ai miei dati. Nessun problema qui.
Controllers: Tuttavia, ogni controller che ho, essenzialmente fa la stessa cosa. Ottiene e imposta i dati da ViewModels così mentre ciascun controller è diverso in quanto ottiene solo dati diversi, tutti svolgono essenzialmente lo stesso lavoro, nello stesso modo. (Al momento ne ho 9, ma potrebbe facilmente esplodere a oltre 50).
Ad esempio:
public class Dummy1Controller : Controller
{
private MyProj.Data.Entities _entities = new Data.Entities();
private MyProj.Data.Entities2 _coreEntities = new Data.Entities2();
//GET: /Customers/
public ActionResult Index()
{
if (_entities.table1.Count() == 0) return View();
var pastObj = _entities.table1.First();
return View(new Table1ViewModel()
{
Id = pastObj.Id,
FirstName = pastObj.FirstName,
LastName = pastObj.LastName,
.
.
.
.
});
}
}
public class Dummy2Controller : Controller
{
private MyProj.Data.Entities _entities = new Data.Entities();
private MyProj.Data.Entities2 _coreEntities = new Data.Entities2();
//GET: /Vehicles/
public ActionResult Index()
{
if (_entities.table2.Count() == 0) return View();
var pastObj = _entities.table2.First();
return View(new Table1ViewModel()
{
RegNo = pastObj.RegNo,
Make = pastObj.Make,
Model = pastObj.Model,
.
.
.
.
});
}
}
public class Dummy3Controller : Controller
{
private MyProj.Data.Entities _entities = new Data.Entities();
private MyProj.Data.Entities2 _coreEntities = new Data.Entities2();
//GET: /Invoices/
public ActionResult Index()
{
if (_entities.table3.Count() == 0) return View();
var pastObj = _entities.table3.First();
return View(new Table1ViewModel()
{
InvNo = pastObj.InvNo,
Amount = pastObj.Amount,
Tax = pastObj.Tax,
.
.
.
.
});
}
}
Visualizzazioni: ogni vista generato dai contollers grande lavoro. Execpt, quell'unica cosa che cambia sono i dati (campi con etichette e caselle di testo). Ancora una volta, fanno tutti lo stesso lavoro (ma con set di dati diversi).
@model MyProject.Web.ViewModels.Table1ViewModel
@{
ViewBag.Title = "Index";
}
<link href="@Url.Content("~/Content/CSS/GenericDetailStyles.css")" rel="stylesheet" type="text/css" />
<section id="content">
<div id="table">
<div>
<h2>Customer</h2>
</div>
<div class="row">
<div class="left">@Html.LabelFor(x=>x.Id)</div>
<div class="right">@Html.TextBoxFor(model => model.Id)</div>
</div>
<div class="row">
<div class="left">@Html.LabelFor(x=>x.FirstName)</div>
<div class="right">@Html.TextBoxFor(model => model.FirstName)</div>
</div>
<div class="row">
<div class="left">@Html.LabelFor(x=>x.LastName)</div>
<div class="right">@Html.TextBoxFor(model => model.LastName)</div>
</div>
.
.
.
.
</div>
</section>
@{Html.RenderAction("Index", "FooterPartial");}
--------------------------------------------------------------------------------------
@model MyProject.Web.ViewModels.Table2ViewModel
@{
ViewBag.Title = "Index";
}
<link href="@Url.Content("~/Content/CSS/GenericDetailStyles.css")" rel="stylesheet" type="text/css" />
<section id="content">
<div id="table">
<div>
<h2>Vehicle</h2>
</div>
<div class="row">
<div class="left">@Html.LabelFor(x=>x.RegNo)</div>
<div class="right">@Html.TextBoxFor(model => model.RegNo)</div>
</div>
<div class="row">
<div class="left">@Html.LabelFor(x=>x.Make)</div>
<div class="right">@Html.TextBoxFor(model => model.Make)</div>
</div>
<div class="row">
<div class="left">@Html.LabelFor(x=>x.PatientID)</div>
<div class="right">@Html.TextBoxFor(model => model.Model)</div>
</div>
.
.
.
.
</div>
</section>
@{Html.RenderAction("Index", "FooterPartial");}
--------------------------------------------------------------------------------------
@model MyProject.Web.ViewModels.Table3ViewModel
@{
ViewBag.Title = "Index";
}
<link href="@Url.Content("~/Content/CSS/GenericDetailStyles.css")" rel="stylesheet" type="text/css" />
<section id="content">
<div id="table">
<div>
<h2>Invoice</h2>
</div>
<div class="row">
<div class="left">@Html.LabelFor(x=>x.InvNo)</div>
<div class="right">@Html.TextBoxFor(model => model.InvNo)</div>
</div>
<div class="row">
<div class="left">@Html.LabelFor(x=>x.Amount)</div>
<div class="right">@Html.TextBoxFor(model => model.Amount)</div>
</div>
<div class="row">
<div class="left">@Html.LabelFor(x=>x.Tax)</div>
<div class="right">@Html.TextBoxFor(model => model.Tax)</div>
</div>
.
.
.
.
</div>
</section>
@{Html.RenderAction("Index", "FooterPartial");}
Problema: Voglio fare un singolo controller, e renderlo dinamico. In modo che possa leggere i dati da diversi modelli di vista. (Perché 9 o 50 controller eseguono in modo identico lo stesso lavoro)
Quindi voglio fare lo stesso con le viste. In modo che i diversi campi possano essere generati dinamicamente. (Perché 9 o 50 visualizzazioni fanno tutti lo stesso lavoro). Se la vista è basata sul controller, la vista dovrebbe essere in grado di cambiare in base alle sue proprietà.
In sostanza, tutto quello che voglio fare è trovare il modo di dire al controller di leggere da viewmodel X o VM-Y o VM-Z ect e dovrebbe essere in grado di generare le proprietà, recuperare i dati associati e passarli alla vista, che al momento della ricezione, genererà i campi con etichette e caselle di testo.
Immagino di voler sapere se c'è un modo per farlo usando il riflesso. Poiché i modelli di vista sono classi base con proprietà semplici. Si potrebbe potenzialmente creare una classe controller di base che abbia un metodo per leggere in un oggetto viewmodel specificato, ottenere le sue proprietà, leggere anche una tabella associata e abbinare i campi in quella tabella con le proprietà nella classe. Finalmente si può passare nel record dal tavolo per visualizzare. La vista quindi può essere generata automaticamente in base a questo utilizzando un qualche tipo di rasoio, C# o javascript.
Qualsiasi accorgimento se ciò è possibile o meno sarebbe gradito.
Perché si mescolano il pattern MVC e MVVM? Credo che quello che sto chiedendo sia, a cosa serve il ViewModel e non solo a passare il Modello? – Brunner
@Brunner - Beh, in primo luogo, è come mi è stato mostrato e non so come farlo direttamente (sono relativamente nuovo a MVC). In secondo luogo, il mio datore di lavoro vuole farlo in questo modo. Infine, quando lavoro sui miei progetti, lo faccio in questo modo perché non mi piace avere il DB attuale come parte del progetto come mostrano i molti esempi, e averlo generato o rigenerato automaticamente. Ci sono pochissimi esempi pratici che mostrano come connettersi ad un vero database live. Se ne conosci qualcuno, vorrei davvero appregiare dei link a loro. Grazie per la tua risposta. –
Non sono sicuro di cosa intendi per "dbs live reali", ma potresti voler guardare i POCO in combinazione con EF (ad esempio Code-First) - è più o meno quello che hai già, solo impacchettato. Inoltre non sono sicuro di cosa intendi per non avere il DB effettivo nel progetto, dato l'esempio che potresti fare "return new View (pastObj);" e non devi nemmeno modificare la vista (tranne la dichiarazione @model) – Brunner