2009-02-14 22 views
12

Sto cercando di determinare il modo migliore per progettare un progetto .NET Entity Framework per ottenere un buon approccio a livelli. Finora l'ho provato in un gioco basato sulla navigazione in cui i giocatori possiedono e gestiscono pianeti. Ecco come li ho:Layout del progetto .NET Entity (architettura)

Sito Web

Questo contiene tutte le front-end.

C# Project - MLS.Game.Data

Questo contiene il file EDMX con tutti i miei mappature dei dati. Non molto altro qui.

C# Project - MLS.Game.Business

Contiene varie classi che io chiamo come PlanetManager.cs 'Managers'. Il gestore del pianeta ha vari metodi statici utilizzati per interagire con il pianeta, come ad esempio getPlanet (int planetID) che restituirebbe un oggetto codice generato da MLS.Game.Data.

Dal sito, farò qualcosa di simile:

var planet = PlanetManager.getPlanet(1);

restituisce un oggettopianeta dal dal MLS.Game.Data (generato dal EDMX). Funziona, ma mi dà fastidio perché significa che il mio front end deve fare riferimento a MLS.Game.Data. Ho sempre pensato che la GUI avrebbe dovuto solo fare riferimento al progetto Business.

Inoltre, ho scoperto che le mie lezioni di Manager tendono a diventare molto pesanti. Finirò con dozzine di metodi statici in loro.

Quindi ... la mia domanda è: come fanno tutti gli altri progetti ASP EF?

EDIT

Dopo un po 'di più, però, ci sono elementi aggiuntivi che mi preoccupano. Ad esempio, supponiamo di avere il mio oggetto Planet, che viene generato nuovamente dal codice della procedura guidata. E se fosse venuto il momento che il mio pianeta avesse bisogno di avere una proprietà specializzata, diciamo "Popolazione", che è un calcolo di qualche tipo basato su altre proprietà dell'oggetto Planet. Vorrei creare una nuova classe che erediti da Planet e poi restituirla? (Hmm, mi chiedo se le classi sono sigillate dalla EF?)

Grazie

+0

in risposta alla sua modifica - che è dove la separazione dei dati e oggetti ricchi entra in proprio. gli oggetti ricchi comprendono come esporre le loro proprietà mentre incapsulano le operazioni che li modificano. le DTO sono semplicemente per il trasferimento dei dati allo strato di persistenza e non richiedono alcuna logica. – flesh

risposta

3

si potrebbe provare le seguenti operazioni per migliorare le cose:

  • Usa EF per andare a prendere DTOS nel vostro livello di Data, quindi utilizzare queste DTOs per popolare gli oggetti di business più ricchi nel vostro livello di business. L'interfaccia utente dovrebbe quindi solo fare riferimento al livello aziendale.
  • Dopo aver creato gli oggetti business ricchi, è possibile iniziare a internalizzare parte della logica dalle classi gestore, eliminando efficacemente il livello aziendale.

Personalmente preferisco il modello più ricco al modello di gestore perché, come dici tu, si finisce con un carico di metodi statici, che inevitabilmente finiscono per incatenarsi all'interno di altri metodi statici. Trovo questo sia troppo disordinato e, cosa più importante, più difficile da capire e garantire la coerenza dei tuoi oggetti in un dato momento.

Se si incapsula la logica all'interno della classe stessa, è possibile essere più certi dello stato dell'oggetto indipendentemente dalla natura del chiamante esterno.

Una buona domanda, a proposito.

+0

Mi piace dove sta andando la tua idea, tuttavia, non stai duplicando molto lavoro? Ad esempio, se un DTO ha varie proprietà, è probabile che crei di nuovo tutte queste proprietà nella tua versione "più ricca" della classe. Destra? – bugfixr

+0

Dopo aver aggiunto altro - hai mai creato classi nel tuo livello BLL che ereditano dal DTO nel livello dati? Ciò consentirebbe alcune personalizzazioni. Pensieri? Cattiva idea? L'ereditarietà di – bugfixr

+1

aumenterebbe l'accoppiamento tra i livelli (anziché ridurlo) e potreste ritrovarvi con dipendenze di riferimento circolari, che comunque lo farebbero scoppiare. Sì, ci sarebbe qualche duplicazione, ma ricorda che EF può generare i tuoi DTO quindi non mi preoccuperei troppo di questo .. – flesh

0

Non sono un esperto, ma che suona abbastanza buono per me. È simile a quello che ho nelle mie soluzioni, eccetto che unire il progetto EF al progetto di business. Le mie soluzioni non sono così grandi e i miei oggetti non richiedono molta intelligenza, quindi va bene per me. Anch'io ho un sacco di metodi diversi per ciascuna delle mie classi di helper statiche.

Se non si desidera che il livello di presentazione conosca il livello di accesso ai dati, è necessario creare alcune classi intermedie, il che probabilmente richiederebbe molto lavoro. Quindi, qual è il problema con la configurazione corrente?

+1

Le dipendenze rendono più difficile la verifica e la modifica dei singoli strati. Per un piccolo progetto è probabilmente di poca importanza. Tuttavia, per progetti di più ampia scala e durata, di solito si consiglia di avere 0 dipendenze tra i livelli tramite l'uso di un'inversione del contenitore di controllo e delle interfacce definite. Questo è al momento abbastanza complicato da fare con le classi generate da Entity Framework. –

2

IMHO, il layout corrente va bene. È perfettamente normale che l'interfaccia utente faccia riferimento al livello "Dati" come lo chiami tu. Penso che forse la tua preoccupazione sia dovuta alla terminologia. I "Dati" che hai descritto più spesso si riferiscono a un livello "oggetti aziendali" (BOL). Un layout comune sarebbe quindi quello di avere un livello di business logic (BLL) che è il tuo livello 'Managers' e un livello di accesso ai dati (DAL). Nel tuo scenario, LINQ alle Entità (supponendo che lo userai) è il tuo DAL. Un modello di riferimento normale sarebbe quindi: -

Riferimenti UI BLL e BOL. BLL restituisce BOL e DAL (LINQ alle entità).

Dai un'occhiata a this series of articles per maggiori dettagli.

+0

Vedo il tuo punto. Sebbene nel caso di EF, non ho altra scelta che combinare il mio BOL con il DAL poiché il BOL è generato dal wizard che fa l'EF. Mi sto perdendo qualcosa? – bugfixr

+0

Mi dispiace, dichiarazione sbagliata da parte mia. L'EF non è il tuo DAL. Qualunque livello utilizzi per estrarre gli elementi dal database sarà il tuo DAL, presumibilmente LINQ to Entitites. In tal caso, il modello che descrivo è ancora valido. Il tuo BOL generato è ancora solo un BOL, utilizzando l'EF. Modificherò il post. –

0

Il layout sembra ok. avrei aggiunto una/strato di comune utilità

interfaccia utente Web
Affari Strato
DataObjects
Utilità

2

Per quanto riguarda la seconda domanda (dopo l'EDIT) se avete bisogno o volete aggiungere funzionalità ai tuoi oggetti EF puoi usare classi parziali. Fare clic con il pulsante destro del mouse sul file EDMX e selezionare il codice di visualizzazione.

Oppure, se ciò non è sufficiente, puoi abbandonare il progettista e scrivere le tue classi abilitate EF.

C'è una (breve) discussione di entrambe le opzioni qui - http://msdn.microsoft.com/en-us/library/bb738612.aspx

0

Vorrei aggiungere DTOs al vostro livello di business che sono rappresentazioni "oggetto muto" (vale a dire solo proprietà) delle entità che compongono la parte dati. Poi le vostre classi "manager" loro possono tornare, come ad esempio:

class PlanetManager 
{ 
    public static PlanetDTO GetPlanet(int id) { // ... } 
} 

e l'interfaccia utente in grado di trattare solo con lo strato BLL via pocos; il Manager (che chiamerei una classe "Mapper") gestisce tutte le traduzioni tra gli oggetti e il livello dati. Inoltre, se è necessario estendere la classe, è possibile avere una proprietà "virtuale" sull'oggetto DTO e farla tradurre dal Manager ai suoi componenti.

1

Per quanto riguarda la seconda domanda nella sezione "EDIT":

Se non mi sbaglio, le classi generate da EF non sono sigillati, e sono PARZIALI classi, così si potrebbe facilmente estendere quelli senza toccare direttamente i file generati.

La classe generato sarà:

public partial class Planet : global::System.Data.Objects.DataClasses.EntityObject 
{ 
... 
} 

modo da poter facilmente creare il proprio "PlanetAddons.cs" (o come volete chiamarlo) di estendere questa classe:

public partial class Planet 
{ 
property int Population {get; set;} 
... 
} 

Piuttosto pulito, eh? Non c'è bisogno di derivare e creare gerarchie di oggetti artificiali ....

Marc

Problemi correlati