2009-09-20 12 views
5

Przechodzę przez samouczki (szczególnie te przy użyciu Linq-To-Entities) i rozumiem podstawowe pojęcia, jednak niektóre rzeczy dają mi problemy.Czy moja aplikacja ASP.NET MVC ma właściwą strukturę?

Samouczki zazwyczaj dotyczą tylko prostych modeli i formularzy, które wykorzystują jedynie proste instrukcje tworzenia, aktualizowania i usuwania. Moje są nieco bardziej skomplikowane i nie jestem pewien, czy podążam tą drogą we właściwy sposób, ponieważ kiedy przychodzi czas na obsługę relacji pół tuzina obiektów bazy danych, samouczki przestają pomagać.

Dla metody post, zwykły sposób wykonywania operacji CRUD

entities.AddToTableSet(myClass); 
entities.SaveChanges(); 

nie zrobi tego, co chcę, bo w pełni wdrożone klasa nie jest uzyskiwanie wysłana do metody kontrolera. Mogę umieszczać pojedyncze pola, tworzyć kolekcje lub wiele obiektów DTO, a następnie wywoływać metodę w usłudze lub repozytorium, aby pobierać informacje, które otrzymuję z postu formularza, wraz z informacjami, których potrzebuje do zapytania lub utworzenia się, a następnie od wszystkie te rzeczy, utwórz mój obiekt bazy danych, który mogę zapisać.

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Add(int id, [Bind(Exclude = "Id")] ClassA classA, 
         [Bind(Exclude = "Id")]ClassB classB) 
{ 
    // Validation occurs here 

    if(!ModelState.IsValid) 
     return View(); 

    try 
    { 
     _someRepositoryOrService.Add(id, classA, classB); 
     return RedirectToAction("Index", new { id = id }); 
    } 
    catch(Exception ex) 
    { 
     // Logging and exception handling occurs here 
    } 
} 


public void Add(int id, ClassA classA, ClassB classB) 
{ 
    EntityA eA = new EntityA 
    { 
     // Set a bunch of properties using the two classes and 
     // whatever queries are needed 
    }; 

    EntityB eB = new EntityB 
    { 
     // Set a bunch of properties using the two classes and 
     // whatever queries are needed 
    }; 

    _entity.AddToEntityASet(eA); 
    _entity.AddToEntityBSet(eB); 
    _entity.SaveChanges(); 
} 

Czy poprawiam to poprawnie, czy też dnuję ramę? Nigdy nie używam obiektu podmiotu bezpośrednio, ilekroć pytam o jedno, umieszczam potrzebne informacje w DTO i opieram moje widoki z tego. To samo dotyczy stworzenia. Czy jest to dozwolone, czy też moje unikanie korzystania z podmiotów bezpośrednio sprzecznych z celem korzystania z tej struktury?

Edycja: Jestem również zaniepokojony tym podejściu, ponieważ wymaga pustych konstruktorów właściwie dzieje zapytań LINQ powodu tego komunikatu o błędzie:

tylko konstruktorzy bez parametrów i inicjalizatory są obsługiwane w LINQ do Podmioty .

To nie jest wielka sprawa, ponieważ rzadko potrzebuję logiki w konstruktorach, ale czy to nie jest kwestia konstruktorów i tylko właściwości publicznych?

+1

Tekst kontekstowy użyty przez Linq do Entities używa odbicia, aby utworzyć obiekty z odwzorowania danych, soit jest ważny i wymaga, aby wszystkie elementy miały konstruktor bez parametrów, dzięki czemu można go zainicjować, a jeśli chcesz móc serializować typy, będzie potrzebował także publicznego konstruktora. – dmportella

Odpowiedz

4

_someRepositoryOrService.Add (identyfikator, klasa A, klasa B);

Powiedziałbym, że łączysz swoje repozytoria z warstwą prezentacji. Tak nie powinno być. Twoje repozytoria powinny działać tylko z jednostkami.Następnie zauważyć, w jaki sposób dodawania metoda

public void Add (int id, ClassA ClassA, ClassB ClassB)

przerwy separacji obawy (SoC). Wykonuje dwa zadania:

  1. widoku mapy dane do podmiotów
  2. Zapisz w repozytorium

Oczywiście pierwszym krokiem powinno być wykonane w warstwie prezentacji. Rozważ zastosowanie do tego celu modeli spinerów. Może również pomóc w rozwiązaniu problemu konstruktorów, ponieważ twoje segregatory mogą zostać uświadomione o wymaganiach konstrukcyjnych.

Sprawdź także ten znakomity post autorstwa Jimmy'ego Bogarda (współautor programu ASP.NET MVC In Action) na temat ViewModels. Może to pomóc w automatyzacji mapowania. Sugeruje również odwrotną technikę - spraw, by kontrolerzy pracowali z podmiotami, a nie z ViewModels! Filtry niestandardowych akcji i narzędzia do łączenia modeli są tak naprawdę kluczem do wyeliminowania rutyny, że nie należą one do kontrolerów, lecz stanowią szczegół infrastruktury między widokiem a kontrolerem. Na przykład: here, w jaki sposób automatyzuję pobieranie obiektów. Here - jak widzę, co powinni zrobić kontrolerzy.

Celem jest sprawić, że kontrolerowie będą koncentrować się na zarządzaniu logiką biznesową, odkładając na bok wszystkie szczegóły techniczne, które nie należą do Twojej firmy. To techniczne ograniczenia, o których mówisz w tym pytaniu, i pozwalasz im przeciekać kodu. Ale możesz użyć narzędzi MVC, aby przenieść do nich poziom infrastruktury.

AKTUALIZACJA: Nie, repozytoria nie powinny obsługiwać danych formularzy, to właśnie rozumiem przez "sprzężenie z prezentacją". Tak, repozytoria znajdują się w kontrolerze, ale nie działają z danymi formularza. Możesz (ale nie powinieneś) tworzyć formy z "danymi repozytoriów" - tzn. Encje - i to właśnie robi większość przykładów, np. NerdDinner - ale nie w inny sposób. Jest tak ze względu na ogólną zasadę - wyższe warstwy można łączyć z niższymi (prezentacja połączona z repozytoriami i jednostkami), ale nigdy niski poziom nie powinien być łączony z wyższymi (jednostki zależą od repozytoriów, repozytoria zależą od modelu formularza itp.).

Pierwszy krok powinien zostać wykonany w repozytorium, to prawda - z tą różnicą, że mapowanie z ClassX do EntityX nie należy do tego kroku. To zmartwienie związane z mapowaniem - infrastruktura. Patrz na przykład: this pytanie o mapowanie, ale ogólnie, jeśli masz dwie warstwy (interfejs użytkownika i repozytoriów), nie powinni oni zajmować się mapowaniem - powinna to być usługa/pomocnik mappera. Oprócz bloga Jimmy'ego możesz także przeczytać ASP.NET MVC In Action lub po prostu spojrzeć na ich CodeCampServer, jak mapują z interfejsami IEntityMapper przekazywanymi do konstruktorów kontrolerów (zauważ, że jest to podejście bardziej ręczne i mniej pracujące niż AutoMapper Jimmy'ego Bogarda).

Jeszcze jedno. Przeczytaj o Domain Driven Design, szukaj artykułów, ucz się od nich, ale nie musisz podążać za wszystkim. Są to wytyczne, a nie ścisłe rozwiązania. Sprawdź, czy twój projekt sobie z tym poradzi, sprawdź, czy możesz sobie z tym poradzić i tak dalej. Spróbuj zastosować te techniki, ponieważ są one na ogół doskonałymi i zatwierdzonymi sposobami rozwoju, ale nie bierz ich ślepo - lepiej jest uczyć się po drodze niż stosować coś, czego nie rozumiesz.

+0

Do sprzęgania repozytoriów, nie jestem pewien, co masz na myśli, mając repozytorium w kontrolerze wydaje się, co większość tutoriali również zrobić. Co zrobić w pierwszym kroku w warstwie prezentacji, czy nie powinno się tego robić w repozytorium? Myślałem, że celem repozytoriów było martwienie się o przetwarzanie danych formularzy na konwersję bazy danych? – Brandon

+0

Dziękuję również za przykłady i porady. Nie miałem czasu, aby wprowadzić zmiany, ale to miły ruch w dobrym kierunku. – Brandon

+0

Zobacz aktualizację. Proponuję powolny procesor, na przykład najpierw wykonaj _realEntityRepository.Add (EntityMapper.From (classA)); (lub classA.MapToEntity()), następnie włącz niestandardowy modelBinder (który jest dużym tematem), następnie dodaj kontener IoC (inny duży temat) i tak dalej. – queen3

4

Powiedziałbym, że używanie DTO i owijanie Entity Framework przy użyciu własnych metod dostępu do danych i warstwy biznesowej to świetny sposób na rozpoczęcie pracy. Możesz napisać dużo kodu, ale jest to lepsza architektura niż udawanie, że kod wygenerowany przez Entity Framework jest twoją warstwą biznesową.

Te problemy nie są w żaden sposób związane z ASP.NET MVC. ASP.NET MVC zasadniczo nie daje wskazówek, jak wykonać twój model/dostęp do danych, a większość próbek i samouczków dla ASP.NET MVC nie jest produktywnymi implementacjami modeli, ale tak naprawdę tylko minimalnymi próbkami.

Wygląda na to, że jesteś na dobrej drodze, idź dalej.

W końcu używasz Entity Framework głównie jako generatora kodu, który nie generuje bardzo przydatnego kodu, więc możesz zajrzeć do innych generatorów kodu lub narzędzi lub frameworków, które bardziej pasują do twoich wymagań.

+0

Naprawdę używam tylko struktury Entity, aby spróbować czegoś nowego. Używam nHibernate. Czy masz jakieś sugestie dotyczące lepszego generatora lub architektury, z których powinienem korzystać? – Brandon

+0

Nie znam niczego, co pasowałoby idealnie do twoich potrzeb. Niektóre z nich są komercyjne, a niektóre są bezpłatne. W żadnej kolejności: T4 Templates, CodeSmith, LLBLGen Pro. –

+1

Jest to w większości bardzo dobra odpowiedź (+1), ale nie zgadzam się, że używa on Entity Framework jako generatora kodu. O wiele ważniejsze jest to, że używa Entity Framework do mapowania swojej bazy danych na przestrzeń obiektu. Jest to ważne, nawet jeśli nigdy nie zmaterializujesz typu jednostki; nadal używasz odwzorowań w kwerendzie LINQ do Entities podczas rzutowania ich na inne typy. –

Powiązane problemy