Controllori e separazione delle preoccupazioni: discutere possibili strategie

-2

Ho lavorato a un progetto basato su questo esercitazione .

Sfortunatamente, le classi di controller in questo sono abbastanza dense e hanno una terribile separazione delle preoccupazioni. Avrei dovuto capirlo in origine ma, ci sono riuscito e ora sono bloccato a gestire il terribile design di questo tutorial con le mie funzionalità aggiunte / decisioni sbagliate.

Nel mio caso, ho 3 controller: Hardware, Dipendente, Progetto. Accedono al database, filtrano i dati e li passano alla vista. Creo anche alcuni componenti dell'interfaccia utente nel controller (vedi Seleziona elenco nell'esempio seguente).

Ho letto di Dependency Injection, del modello di deposito e del modello di unità di lavoro. Sono un po 'confuso con tutti e 3 questi, ma sono tendenzialmente d'accordo con "Il repository è il nuovo Singleton ". Se questo è ciò che fa EF6, non penso che sia una buona idea riorganizzarlo. Penso che DI è sicuramente il posto dove dovrei essere diretto, ma penso che la mia comprensione di ciò non sia ancora finita lì.

Voglio suddividere questi controller in parti più piccole e riusabili. Il filtraggio, ad esempio, potrebbe essere riutilizzato da modelli diversi, ma non riesco ad astrarre completamente questo nella mia testa. Nella maggior parte dei controller succede molto:

public class HardwareController : Controller
{
    private LATTContext db = new LATTContext();

    // GET: Hardware
    public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
    {
        ViewBag.CurrentSort = sortOrder;
        ViewBag.SerialNoParm = sortOrder == "serialNo" ? "serialNo_desc" : "serialNo";
        ViewBag.CabModelParm = sortOrder == "cabModel" ? "cabModel_desc" : "cabModel";
        ViewBag.PlatformParm = sortOrder == "plat" ? "plat_desc" : "plat";
        ViewBag.VendorParm = sortOrder == "vendor" ? "vendor_desc" : "vendor";
        ViewBag.CategoryParm = sortOrder == "category" ? "category_desc" : "category";
        ViewBag.EmployeeParm = sortOrder == "employee" ? "employee_desc" : "employee";

        if (searchString != null)
        {
            page = 1;
        }
        else
        {
            searchString = currentFilter;
        }

        ViewBag.CurrentFilter = searchString;

        var hardwares = from h in db.hardwares
                        select h;
        if (!String.IsNullOrEmpty(searchString))
        {
            hardwares = hardwares.Where(h => h.SerialNo.ToLower().Contains(searchString.ToLower()) ||
                h.model.Name.ToLower().Contains(searchString.ToLower()) ||
                h.platform.Name.ToLower().Contains(searchString.ToLower()) ||
                h.vendor.Name.ToLower().Contains(searchString.ToLower()) ||
                h.category.Type.ToLower().Contains(searchString.ToLower()));
        }
        switch (sortOrder)
        {
            case "serialNo":
                hardwares = hardwares.OrderBy(h => h.SerialNo);
                break;
            case "serialNo_desc":
                hardwares = hardwares.OrderByDescending(h => h.SerialNo);
                break;
            case "cabModel":
                hardwares = hardwares.OrderBy(h => h.model.Name);
                break;
            case "cabModel_desc":
                hardwares = hardwares.OrderByDescending(h => h.model.Name);
                break;
            case "plat":
                hardwares = hardwares.OrderBy(h => h.platform.Name);
                break;
            case "plat_desc":
                hardwares = hardwares.OrderByDescending(h => h.platform.Name);
                break;
            case "vendor":
                hardwares = hardwares.OrderBy(h => h.vendor.Name);
                break;
            case "vendor_desc":
                hardwares = hardwares.OrderByDescending(h => h.vendor.Name);
                break;
            case "category":
                hardwares = hardwares.OrderBy(h => h.category.Type);
                break;
            case "category_desc":
                hardwares = hardwares.OrderByDescending(h => h.category.Type);
                break;
            case "employee":
                hardwares = hardwares.OrderBy(h => h.employee.FirstName);
                break;
            case "employee_desc":
                hardwares = hardwares.OrderByDescending(h => h.employee.FirstName);
                break;
            default:
                hardwares = hardwares.OrderBy(h => h.model.Name);
                break;
        }
        int pageSize = 10;
        int pageNumber = (page ?? 1);

        return View(hardwares.ToPagedList(pageNumber, pageSize));
    }

    // GET: Hardware/Details/5
    public ActionResult Details(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Hardware hardware = db.hardwares.Find(id);
        if (hardware == null)
        {
            return HttpNotFound();
        }
        return View(hardware);
    }

    // GET: Hardware/Create
    public ActionResult Create()
    {
        ViewBag.Category_ID = new SelectList(db.categories, "CategoryID", "Type");
        ViewBag.Employee_ID = new SelectList(db.employees, "EmployeeID", "FullName");
        ViewBag.Model_ID = new SelectList(db.models, "CabinetModelID", "Name");
        ViewBag.Platform_ID = new SelectList(db.platforms, "PlatformID", "Name");
        ViewBag.Vendor_ID = new SelectList(db.vendors, "VendorID", "Name");
        return View();
    }

    // POST: Hardware/Create
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "HardwareID,SerialNo,Comment,Platform_ID,Category_ID,Vendor_ID,Model_ID,Employee_ID")] Hardware hardware)
    {
        try
        {
            if (ModelState.IsValid)
            {
                db.hardwares.Add(hardware);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
        }
        catch (DbUpdateException /*ex*/)
        {
            ModelState.AddModelError("", "Problem updating database. Please verify that Serial No is unique");
        }


        ViewBag.Category_ID = new SelectList(db.categories, "CategoryID", "Type", hardware.Category_ID);
        ViewBag.Employee_ID = new SelectList(db.employees, "EmployeeID", "FullName", hardware.Employee_ID);
        ViewBag.Model_ID = new SelectList(db.models, "CabinetModelID", "Name", hardware.Model_ID);
        ViewBag.Platform_ID = new SelectList(db.platforms, "PlatformID", "Name", hardware.Platform_ID);
        ViewBag.Vendor_ID = new SelectList(db.vendors, "VendorID", "Name", hardware.Vendor_ID);
        return View(hardware);
    }

    // GET: Hardware/Edit/5
    public ActionResult Edit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Hardware hardware = db.hardwares.Find(id);
        if (hardware == null)
        {
            return HttpNotFound();
        }

        ViewBag.Category_ID = new SelectList(db.categories, "CategoryID", "Type", hardware.Category_ID);
        ViewBag.Employee_ID = new SelectList(db.employees, "EmployeeID", "FullName", hardware.Employee_ID);
        ViewBag.Model_ID = new SelectList(db.models, "CabinetModelID", "Name", hardware.Model_ID);
        ViewBag.Platform_ID = new SelectList(db.platforms, "PlatformID", "Name", hardware.Platform_ID);
        ViewBag.Vendor_ID = new SelectList(db.vendors, "VendorID", "Name", hardware.Vendor_ID);

        return View(hardware);
    }



    // POST: Hardware/Edit/5
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include = "HardwareID,SerialNo,Comment,Platform_ID,Category_ID,Vendor_ID,Model_ID,Employee_ID")] Hardware hardware)
    {
        if (ModelState.IsValid)
        {
            db.Entry(hardware).State = EntityState.Modified;
            db.SaveChanges();
            if (Request.UrlReferrer.ToString().Contains("hardware/Edit"))
            {
                return RedirectToAction("Index");
            }
            else
            {
                return RedirectToAction("Index", "Project");
            }
        }
        ViewBag.Category_ID = new SelectList(db.categories, "CategoryID", "Type", hardware.Category_ID);
        ViewBag.Employee_ID = new SelectList(db.employees, "EmployeeID", "FirstName", hardware.Employee_ID);
        ViewBag.Model_ID = new SelectList(db.models, "CabinetModelID", "Name", hardware.Model_ID);
        ViewBag.Platform_ID = new SelectList(db.platforms, "PlatformID", "Name", hardware.Platform_ID);
        ViewBag.Vendor_ID = new SelectList(db.vendors, "VendorID", "Name", hardware.Vendor_ID);
        return View(hardware);
    }

    // GET: Hardware/Delete/5
    public ActionResult Delete(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Hardware hardware = db.hardwares.Find(id);
        if (hardware == null)
        {
            return HttpNotFound();
        }
        return View(hardware);
    }

    // POST: Hardware/Delete/5
    [HttpPost, ActionName("Delete")]
    [ValidateAntiForgeryToken]
    public ActionResult DeleteConfirmed(int id)
    {

        //TODO catch inner sql exception when hardware is assigned
        if (ModelState.IsValid)
        {
            Hardware hardware = db.hardwares.Find(id);
            db.hardwares.Remove(hardware);
            db.SaveChanges();

        }

        return RedirectToAction("Index");
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }
        base.Dispose(disposing);
    }
}
    
posta J Hache 21.06.2016 - 15:07
fonte

1 risposta

0

Se fossi in te, inizierei utilizzando la "M" in MVC e abbandonando il ViewBag: inizia a creare i modelli di visualizzazione. Se inizi a creare un modello per l'ordinamento, il filtraggio e il paging della griglia, inizierai a vedere dove si trova la funzionalità comune e non lo è, ovvero cosa è specifico per una determinata griglia e cosa è generale.

Non è necessario accedere al modello di repository per separare l'accesso ai dati dai problemi di interfaccia utente. Inizia spostando la logica dei dati solo in un'altra classe e cerca di stabilire le interfacce / API tra l'interfaccia utente e la business logic / accesso ai dati.

Non saltare ancora a DI neanche. Questo potrebbe essere un obiettivo a lungo termine, ma inizia a separare le tue preoccupazioni.

    
risposta data 21.06.2016 - 16:46
fonte

Leggi altre domande sui tag