Problemi con l'esposizione delle proprietà di classe tra i progetti

4

Ho diversi progetti nella mia soluzione:

  • Logan.Web.DBContext definisce DbContext per il database e crea il modello dati
  • Logan.Web.Objects definisce le classi che rappresenteranno le tabelle nel database
  • Logan.Web.Data definisce il livello dati che l'applicazione utilizzerà
  • LoganMVC è il sito web MVC effettivo

Ovviamente non voglio che il sito Web MVC sappia troppo del database, quindi non ho collegamenti tra esso e i progetti Objects / DBContext. Invece, il progetto Data agisce come un "intermediario" tra loro e contiene tutte le funzionalità CRUD.

Il problema che sto avendo con questa struttura è che, per mostrare qualcosa sulle Views, i Modelli devono conoscere le proprietà per i dati come definito nelle classi Objects.

Non sono sicuro di come esporli senza fare riferimento al progetto Objects nel progetto MVC, ma è a mia conoscenza che questa non sarebbe una buona pratica. Invece, preferirei, se possibile, esporli attraverso il livello dati, ma non riesco nemmeno a capire come farlo in un modo che abbia senso.

Ho pubblicato tutto il codice per la maggior parte di questi progetti attualmente esistenti su pastebin:

link

  • Lo spazio dei nomi DBContext inizia alla riga 1
  • Lo spazio dei nomi DBObjects inizia sulla riga 141
  • Lo spazio dei nomi dati inizia alla riga 185

Qual è il modo migliore per esporre le proprietà delle classi in Logan.Web.Objects in modo che possano essere utilizzate in LoganMVC data la struttura definita qui?

    
posta Ortund 25.06.2014 - 17:06
fonte

2 risposte

1

I don't want the MVC website to know too much about the database so I have no links between [the MVC website] and the Objects/DBContext projects

The problem I'm having with this structure is that, to show anything on the Views, the [MVC] Models need to know the properties for the data as defined in the Objects classes.

Questa è una contraddizione. Non stai intenzionalmente facendo riferimento al progetto Objects nel progetto MVC, ma ti aspetti di essere in grado di utilizzare le classi Objects (e le relative proprietà) nel progetto MVC.

È l'uno o l'altro. Non puoi avere la tua torta e mangiarla. O, più appropriatamente, non puoi non fare riferimento al tuo progetto e quindi fare riferimento alle sue classi.

Hai separato le tue entità dal tuo progetto MVC, ma non stai offrendo un sostituto. Se il tuo progetto MVC non può usare le tue entità; allora cosa dovrebbe usare?

Nota: generalmente sono preoccupato per il superingegnerizzazione. Posso essere d'accordo con i commentatori che menzionano il fatto che si stia esagerando. Ma per la tua domanda, è chiaro che vuoi questa separazione, quindi risponderò come tale.

Il tuo progetto Data non dovrebbe inviare le classi oggetto al progetto MVC, ma piuttosto DTO (che possono essere copie speculari delle classi entità, che non è intrinsecamente sbagliato da fare).

Un semplice esempio:

Nel progetto Oggetti:

public class Person 
{
    public string Name { get; set; }
}

Nel progetto Dati:

public class PersonDto
{
    public string Name { get; set; }
}

Anche nel progetto Dati, a livello di repository:

public PersonDto GetPersonById(int personId)
{
    Objects.Person person = myContext.People.Single(p => p.Id == personId);

    Data.PersonDto personDto = new PersonDTO();
    personDto.Name = person.Name;

    return personDto;
}

In questo modo, l'oggetto Person non lascia mai il progetto Dati. Il progetto MVC non è consapevole del fatto che Person esiste, ma sa solo che PersonDto esiste.

Ulteriori menzioni:

  • AutoMapper è una libreria comunemente utilizzata per automatizzare la mappatura tra un'entità e la sua classe DTO equivalente. Se le proprietà hanno lo stesso nome e tipo, è possibile che Automapper si converta molto rapidamente in automatico. Se i nomi sono diversi, è necessario specificare la mappatura, naturalmente.
  • Il codice qui è strongmente semplificato a titolo di esempio.
  • Nel caso in cui si desideri fare ciò, la separazione dei dati (business query logic) e DTO (cloni di entità) non ha senso. Tutti i progetti che ho visto mantengono questi due insieme, poiché sono strettamente legati tra loro
    • I DTO esistono in particolare perché la classe Data esiste come livello di astrazione. Avere uno senza l'altro è un po 'sciocco.
    • Hai separato il tuo DbContext dalle tue entità. Questo è un po 'diverso, c'è una distinzione significativa lì (ad esempio se si supporta sia il database che l'archiviazione di file XML con le stesse classi di entità). Tuttavia, un livello dati è generalmente inteso come un livello univoco , che pertanto dispone anche di oggetti univoci DTO.
  • Personalmente, non mi piace usare i tipi restituiti dalle librerie (Oggetti) ai chiamanti esterni (MVC), in particolare perché richiede che il chiamante esterno (MVC) faccia riferimento anche alla libreria (Oggetti). Il più delle volte, doverlo fare per sconfiggere lo scopo di creare l'astrazione in primo luogo.
    • Si possono fare eccezioni per le librerie che vengono utilizzate a tutti i livelli per altri scopi, ad es. utilizzando NLog se si desidera accedere a tutti i livelli dell'applicazione. Ma generalmente non restituirai gli oggetti / tipi NLog da un progetto all'altro.
risposta data 16.05.2018 - 16:00
fonte
0

Quello che potresti voler vedere è la segregazione sulla responsabilità della query dei comandi. La base dell'idea è che le interazioni con le tue informazioni avvengano tramite i comandi (le operazioni di CRUD possono anche essere modellate come comandi. Per la visualizzazione dovrai quindi creare modelli molto specifici che possono essere visualizzati come sono. in questo caso è possibile guidare le operazioni CRUD dal progetto MVC effettuando chiamate al progetto Dati. È quindi possibile aggiungere un progetto Logan.Web.Models che è possibile utilizzare per eseguire letture di dati che consentiranno di creare rappresentazioni di oggetti che non esporre la funzionalità CRUD e servirebbe solo come oggetti di sola lettura.

    
risposta data 20.06.2017 - 09:14
fonte

Leggi altre domande sui tag