2 Stimmen

ASP.NET MVC Design

Wie bereits erwähnt, arbeite ich an einem Dig-Clone, um mir ASP.NET MVC von Grund auf beizubringen, aber ich bin auf ein Problem gestoßen, das ich scheinbar nicht vermeiden kann.

Ich möchte diese Anwendung so gut wie möglich optimieren, daher habe ich meine DAL, die eine Menge Klassen von ...Repository: Repository ist. Um die Leistung zu optimieren, lassen meine Basis-Repository-Klassen meine ViewData-Objekte zurück, damit zusätzliche erforderliche Felder ausgewählt werden können, ohne einen anonymen Typen erstellen zu müssen.

Geschichten haben Benutzer, die sie erstellt haben, und Benutzer haben Stimmen für Geschichten. Ziemlich einfaches Datenbank-Layout. Da die Standard-ASP.NET-Mitgliedschaft so aufgebläht ist, handle ich meine eigene Mitgliedschaft. In meiner Ansicht für die Liste der Geschichten muss ich feststellen, ob der aktuelle Benutzer über die Geschichte abgestimmt hat, die gerendert wird. Da meiner Meinung nach der Datenzugriff in der Ansicht nicht stattfinden sollte, sollte er entweder in meinem Controller oder meiner DAL erfolgen. Da ich bereits ViewData von meiner DAL zurückgebe, habe ich eine weitere Eigenschaft vom Typ StoryViewData mit dem Namen "UserVotedOn" hinzugefügt, die true zurückgibt, wenn der Benutzer über die Geschichte abgestimmt hat.

Das Problem dabei ist, dass ich entweder A) die DAL über die Mitgliedschaft informieren muss oder B) die Benutzer-ID in die Abfrage-Methoden der DAL übergeben muss. Beides fühlt sich für mich nicht richtig an, und ich suche nach guten Lösungen. Jegliches Feedback ist willkommen.

3voto

Paul G. Punkte 489

In meinen MVC-Apps verwende ich die Architektur, die Rob Conery in seiner MVC-Storefront-Videoreihe gezeigt hat, und sie funktioniert wie ein Zauber für mich.

Repository => Service + Filter => Controller => Ansicht

Ich habe versucht zu simulieren, was du erreichen möchtest, und es geschafft, es so zu machen

Bearbeiten1: IList in Repository und Filtern in IQueryable geändert

Repository

public interface IRepository
{
    IQueryable GetVotes();
    IQueryable GetStories();
}

Service zum Abrufen dessen, was du möchtest

public class Service : IService
{
    private IRepository _repository;

    public Service(IRepository repository)
    {
        _repository = repository;
        if (_repository == null) throw new InvalidOperationException("Repository darf nicht null sein");
    }
    public IList GetUserVotes(int userID)
    {
        return _repository.GetVotes().WithUserID(userID).ToList();
    }
    public IList GetNotVotedStories(IList votes)
    {
        return _repository.GetStories().WithoutVotes(votes).ToList();
    }
}

Filter, um deine Geschichten und Benutzerstimmen zu filtern (Dies sind im Wesentlichen Erweiterungsmethoden). Nicht die schönste Implementierung da draußen, aber du kannst später neu schreiben

public static class Filters
{
    public static IQueryable WithUserID(this IQueryable  qry, int userID)
    {
        return from c in qry
               where c.UserID == userID
               select c;
    }
    public static IQueryable WithoutVotes(this IQueryable  qry, IList  votes)
    {
        return  from c in qry
                where votes.Where(x => x.StoryID == c.StoryID).ToList().Count > 0
                select c;
    }
}

Und dann kannst du den aktuellen Benutzer-ID im Controller übergeben, nicht im DAL oder in der Ansicht wie du es früher tun musstest

public class HomeController : Controller
{
    private readonly IRepository _repository;
    private readonly IService _service;

    public HomeController()
    {
        _repository = new Repository();
        _service = new Service.Service(_repository);
    }

    public ActionResult Index()
    {
        var userVotes = _service.GetUserVotes(AktuelleBenutzerID);
        var unvotedStories = _service.GetNotVotedStories(userVotes);

        return View(unvotedStories);
    }
}

Dies ermöglicht es dir, dich davon fernzuhalten, benutzerbezogene UserVotedOn-Eigenschaft zu deinem Story-Modell hinzuzufügen

1voto

User Punkte 29239

Es sieht so aus, als ob Ihnen die BLL fehlt.

Eigentlich ist die richtige Architektur einer MVC-Anwendung etwas, das viele Menschen immer noch zu verstehen versuchen.

Ich persönlich betrachte die Benutzer-ID als eine Art Translay-Konzept. Sie wird sowohl auf den Ebenen DAL als auch BLL erscheinen.

Grundsätzlich sollte Ihre Controller-Methode nur einige sehr grundlegende Aufrufe an die BLL haben, nur um zu bestimmen, wie auf Benutzereingaben reagiert werden soll, ob eine Ansicht zurückgegeben werden soll oder eine andere.

Ihre Ansicht sollte nur mit Modellobjekten umgehen. Ein Modell sollte wahrscheinlich von der Geschäftslogik gefüllt werden. Sie könnten BL-Methoden in einer Controller-Methode aufrufen, um Ihr Modellobjekt zu initialisieren und es dann an die Ansicht zu übergeben.

Der Controller sollte nicht direkt mit der Datenbank kommunizieren. Ebenso sollte er wahrscheinlich nicht mit niedrigstufigen Objekten umgehen, die Ihre Domänenobjekte und Modelle bilden.

P.S. Ich würde versuchen, den umfangreichen Einsatz von ViewData zu vermeiden. Stark typisierte Modellklassen sind eine viel bessere Option. Sie können sie auch in Hierarchien gruppieren, um einige gemeinsame Eigenschaften zu erben. Genauso wie Ihre Domänenmodellklassen von einer Basisklasse ableiten könnten, die eine Benutzer-ID-Eigenschaft definiert hat.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X