Accesso ai dati per applicazioni componibili

5

Mi chiedo se qualcuno possa condividere i loro pensieri, esperienze e indicazioni su come affrontare il livello di accesso ai dati per un'applicazione componibile?

Per applicazione componibile intendo un'applicazione con il livello del dominio costituito da moduli. L'obiettivo è rendere l'applicazione altamente estendibile "collegando" moduli aggiuntivi (o sostitutivi). Ogni modulo incapsula (e isola) un insieme di funzionalità correlate.

Il mio dilemma è l'approccio giusto per il livello di accesso ai dati per supportare questa componibilità (modularità) pur fornendo isolamento dal database di back-end. Poiché ogni "modulo" è in grado di implementare il proprio set di oggetti dominio, non c'è davvero modo di vedere un ORM come l'EF funzionante a meno di creare semplicemente un contesto di dati mega o apportare modifiche al livello di accesso ai dati ogni volta che viene introdotto un nuovo modulo (che non è possibile se il modulo viene aggiunto da una terza parte o come estensione post-distribuzione).

Per quello che vale, questa è un'applicazione su scala aziendale con un database contenente oltre 200 tabelle e una tonnellata di sproc, udfs, ecc.

Che consiglio puoi condividere?

Aggiorna

Ho confermato oggi che utilizzeremo un archivio dati legacy per la soluzione che utilizza stored procedure e funzioni definite dall'utente per la maggior parte delle operazioni di accesso ai dati. La nostra speranza è quella di evolvere da questo tempo, ma il budget e la tempistica per il progetto dettano la nostra creazione in cima ai database esistenti.

Questo cambia i tuoi pensieri?

    
posta SonOfPirate 30.07.2011 - 03:46
fonte

4 risposte

1

Non esiste una regola semplice e veloce per l'applicazione è necessario utilizzare un singolo DbContext; Vorrei separare le cose in un contesto di dati di base e altri DbContext più mirati. O cose che non sono nemmeno DbContexts quando i dati non provengono da un database relazionale. . .

    
risposta data 01.08.2011 - 22:38
fonte
4

Dalla mia esperienza (perché ho realizzato un CMS utilizzando .NET Framework e LINQ in SQL ORM):

Qualsiasi CMS dovrebbe rivolgersi a 3 gruppi, ovvero sviluppatori , designer e utenti . Quando dici modulo, è come se parlassi di gruppo di sviluppatori . Ora hai considerato questi elementi:

  1. Fornisci un'infrastruttura e chiedi ai tuoi utenti di utilizzare la tua infrastruttura quando sviluppi i loro moduli (ad esempio, WordPress è così e ha una classe chiamata wp_options e ogni volta che vuoi archiviare o recuperare un'opzione, sei incoraggiato a usare questo classe). In questo modo, il tuo unico lavoro potrebbe essere quello di creare alcune classi base come DataAccessBase o alcune classi generiche, ecc.
  2. Ogni CMS è composto da core + parti estendibili . In alcune applicazioni CMS, la tassonomia non è estensibile, quindi fa parte del nucleo. In molte applicazioni CMS, la sicurezza non è estensibile, quindi fa parte del nucleo. Qualunque cosa tu faccia, dovresti implementare un nucleo. In questo caso, puoi chiedere agli sviluppatori di utilizzare il tuo core per le parti non estendibili come sicurezza, appartenenza, tassonomia, commenti, opzioni, ecc. Ad esempio, puoi avere una classe chiamata UserFacade con un metodo chiamato IsAuthenticated . Quindi gli sviluppatori possono usare la tua astrazione per ottenere ciò che vogliono dal core.
  3. Ogni CMS ha una diversa implementazione del database. Alcuni usano il modello EAV e ti consentono di creare Tipi di contenuto in modo dinamico, mentre altri ti chiedono semplicemente di creare le tabelle correlate. Se il tuo CMS appartiene alla seconda categoria, lo sviluppatore di moduli può utilizzare l'infrastruttura solo per connettersi al database, ma altre parti del recupero e dell'archiviazione dei dati sono specifiche del modulo e ogni sviluppatore dovrebbe avere la propria implementazione. Tuttavia, se il tuo CMS proviene dalla prima categoria, allora puoi semplicemente fornire un livello di astrazione per gli sviluppatori di moduli per non colpire mai il tuo database (ad esempio possono scrivere una riga di codice come: dynamic riddles = EntityProvider.GetList("Riddle"); o EntityPersister.Save(riddleKeyValueDictionary);
risposta data 30.07.2011 - 09:35
fonte
2

L'ho fatto ed è davvero piuttosto semplice con un ORM come (N-) Hibernate.

Se un EF-Context è simile a una sessione in Hibernate, allora un mega-contesto è chiaramente qualcosa da evitare! Tuttavia, Hibernate ha una Session-Factory, che legge tutti i mapping e crea le sessioni (probabilmente contesti in EF) quando ne hai bisogno. E questa fabbrica può essere la mega-fabbrica senza essere un anti-modello.

Ogni modulo può contenere le proprie mappature ed entità. Hibernate fa un ottimo lavoro di ignoranza di persistenza! Il loro punto chiave è che il contesto è alimentato con i mapping durante il tempo di avvio e non in fase di progettazione.

Ho appena creato un SessionManager (che contiene NHibernates SessionFactory). Durante l'avvio, tutti i mapping da tutti i moduli sono registrati. Abbiamo circa 200 tavoli e quasi altrettante entità e questo non è affatto un problema, non ci sono anche problemi di memoria. Il gestore sessioni crea sessioni di database in base alle nostre esigenze. Di solito abbiamo qui una sessione per approccio caso d'uso (si traduce piuttosto bene in una sessione per finestra di dialogo).

Poiché tutti i moduli condividono lo stesso host, hanno accesso a un contenitore IoC, in modo che possano risolvere la sessione di produzione e ottenere tutte le sessioni che desiderano.

Gli unici problemi pongono di volta in volta mappature di ereditarietà intermodulari. Le mappature di ereditarietà intermodulari possono essere abbastanza complicate e alcune entità non possono essere mappate sull'ereditarietà come vorremmo. Ma questi casi erano rari (forse una, due entità di questi 200) e poi abbiamo per lo più fatto relazioni HasOne ecc.

    
risposta data 30.07.2011 - 09:17
fonte
1

Alcune idee:

Crea un livello di mappatura, che mappa gli oggetti del dominio di livello modulo agli oggetti che il DAL consuma. Il livello di mappatura rappresenterebbe la trasformazione dei dati dei moduli di dominio in dati di consumo DAL. Internamente, il modulo di dominio poteva usare le proprie strutture di dati, ma quando arrivava il momento di parlare con il DAL, quella struttura di dati avrebbe dovuto essere mappata a oggetti comici di DAL.

Modulo - > Oggetti dominio - > Mapper - > Oggetti Dal - > DAL

Se questi moduli estendono effettivamente il database, allora sarebbe necessaria una sorta di schema di database estensibile e i moduli chiamerebbero i metodi generici dello schema estensibile per salvare i dati.

Inoltre, potresti esplorare le parti interne per comunicare con il DAL con un'interfaccia che potrebbe esporre ExecuteReader, ExecuteSclare, ExecuteNonQuery, ecc. Ciò significa che il modulo di dominio può dialogare direttamente con il DAL, ma penso che sia troppo esposizione diretta .

    
risposta data 30.07.2011 - 06:28
fonte

Leggi altre domande sui tag