Acabo de empezar a usar y me estoy enamorando del patrón de diseño MVC.MVC Reducir el código repetitivo
Mi único problema favorito es que parece producir muchos códigos repetitivos. Por ejemplo.
Tengo una aplicación MVC estándar con mi base de datos (modelos) en un proyecto, separada de mis controladores/vistas/modelos de vista en otro, nuevamente separado de mis métodos de prueba en otro. Todo funciona genial
Modelos: Ahora, tengo un montón de buenas clases de EF4 en mi proyecto de base de datos, para lo cual tengo que usar ViewModels en mi proyecto real para acceder a mis datos. No hay problema aqui
Controladores: Sin embargo, cada controlador que tengo, básicamente hace exactamente lo mismo. Obtiene y establece los datos de ViewModels, por lo que aunque cada controlador es diferente, ya que solo obtiene datos diferentes, todos realizan esencialmente el mismo trabajo, de la misma manera. (Actualmente tengo 9, pero esto podría explotar fácilmente a más de 50).
Por ejemplo:
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,
.
.
.
.
});
}
}
Vistas: todas las vistas generadas a partir de los contollers funcionan muy bien. Execpt, lo único que cambia son los datos (campos con etiquetas y cuadros de texto). Una vez más, todos hacen el mismo trabajo (pero con diferentes conjuntos de datos).
@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: Quiero hacer un solo controlador, y que sea dinámico. Para que pueda leer datos de diferentes modelos de vista. (¿Por qué tener 9 o 50 controladores esencialmente haciendo el mismo trabajo)
Luego quiero hacer lo mismo con las vistas. Para que diferentes campos puedan generarse dinámicamente. (¿Por qué tener 9 o 50 vistas todas haciendo el mismo trabajo). Si la vista se basa en el controlador, la vista debería poder cambiar en función de sus propiedades.
Esencialmente, todo lo que quiero hacer es encontrar una manera de decirle al controlador que lea desde el modelo de vista X o VM - Y o VM - Z ect y debe poder generar las propiedades, recuperar los datos asociados y pasarlo a la vista, que al recibir, generará los campos con etiquetas y cuadros de texto.
Supongo que quiero saber si hay alguna manera de hacerlo utilizando la reflexión. Como los modelos de vista son clases básicas con propiedades simples. Uno podría crear potencialmente una clase de controlador base que tenga un método para leer en un objeto viewmodel especificado, obtener sus propiedades, leer también una tabla asociada y hacer coincidir los campos en esa tabla con las propiedades de la clase. Finalmente uno puede pasar el registro de la tabla para mostrar. La vista se puede generar automáticamente basándose en esto usando algún tipo de afeitadora, C# o javascript.
Cualquier comentario sobre si es posible o no sería bienvenido.
¿Por qué mezclar el patrón MVC y MVVM? Supongo que lo que estoy preguntando es, ¿para qué necesitas ViewModel y no solo pasas el Modelo? – Brunner
@Brunner - Bueno, en primer lugar, es la forma en que me mostraron y no sé cómo hacerlo directamente (soy relativamente nuevo en MVC). En segundo lugar, mi empleadora quiere que se haga de esta manera. Finalmente, cuando trabajo en mis propios proyectos, lo hago de esta manera porque no me gusta tener el DB real como parte del proyecto, como muestran muchos ejemplos, y tenerlo generado automáticamente o regenerado. Hay muy pocos ejemplos prácticos que le muestran cómo conectarse a una base de datos real en vivo. Si conoces alguno, realmente apreciaría los enlaces a ellos. Gracias por su respuesta. –
No estoy seguro de lo que quiere decir con "dbs reales en vivo", pero es posible que desee ver las POCO en combinación con EF (por ejemplo, Code-First): es más o menos lo que ya tiene, simplemente empacado cuidadosamente. Tampoco estoy seguro de lo que quiere decir con no tener el DB real en el proyecto, dado su ejemplo, podría hacer "devolver nueva Vista (pastObj);" y ni siquiera tiene que editar la Vista (excepto la declaración @model) – Brunner