Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 14
  1. #1
    Utente di HTML.it L'avatar di ybla82
    Registrato dal
    Jan 2009
    Messaggi
    92

    Architettura web-application

    Salve a tutti,
    apro questo post perchè ho bisogno di un consulto da parte di qualche esperto.

    E' da un po' di anni che lavoro soprattutto in c/c++, ma recentemente mi sono ritrovato a
    riprendere in mano alcuni progetti ASP.NET - C# che avevo sepolto in una remota cartella del pc.

    Quando avevo progettato la struttura di queste web-applciation, avevo impostato un'architettura che mi sembrava buona e abbastanza flessibile.
    Riprendendo in mano queste cose ora, però, mi è venuto il dubbio che forse questa architettura è diventata vecchia, e che il buon Microsoft, ha introdotto
    qualche nuovo strumento che mi permette di minimizzare gli sforzi.

    L'architettura usata era banalmente a 3 livelli: interfaccia, dati, e gestore dati.
    In particolare all'interno dell'interfaccia ( leggi pagina.aspx) era presente un oggettoHandler che si occupava di accedere al db ed estrarre degli Oggetti con cui popolavo i controlli.
    Oggetti e OggettiHandler erano su due piani distinti.

    L'aspetto un po' + complesso era legato a questo OggettoHandler.
    All'avvio della web application leggevo da file config tutte le possibili stringhe di connessione, creavo i rispettivi oggetti Connection
    e li infilavo in un dizionario statico in modo da averli disponibili sempre.
    Creavo successivamente tutti gli OggettiHandler necessari per accedere ai dati nel db, li legavo all'oggetto Connection previsto, e anche questi li ficcavo in una collezione statica.

    Tutta questa logica era ovviamente eseguita un'unica volta all'avvio della web-application ( la chiamata principale era nel global.asax)

    A questo punto in ogni pagina era possibile richiamare i vari OggettiHandler presenti nella collezione statica per fare tutte le query del caso.
    Apertura e chiusura connessione erano gestite a livello di classe base, attraverso l'uso dell'oggetto Connection ( opportunamente tipizzato sul tipo di DB).

    Vorrei avere un parere da voi, in modo da capire se quanto ho in mano è una vaccata clamorosa o è qualcosa su cui si può continuare a lavorare.

    Grazie per l'attenzione.

  2. #2
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    se funziona non è una vaccata clamorosa
    Il pattern che usi è abbastanza pulito e molto vicino a cio che in asp.net dovrebbe essere il modo ideale di agire: il pattern MVP. Personalmente mi muovo allo stesso modo.
    Forse il problema sono le prestazioni e la bassa scalabilità visto che fai uso di oggetti statici. Io li evito finche posso a maggior ragione in una applicazione web che di fatto è multithread!

    Per aggiornarti sulle nuove tecnologie che di sicuro ti evitano tanto lavoro manuale...
    Il lavoro che fai con gli oggetti handler oggi viene fatto con entity framework: definisci delle classi che rappresentano il modello dei dati e che vengono mappate in modo AUTOMATICO sul db sottostante. Un unico oggetto, il context, contiene delle collection in memoria per ognuna delle classi definite sopra e che rappresentano in buona sostanza le tabelle del db. Ogni operazione CRUD su queste collection viene tradotta in una query al db in automatico dal context.

    Purtroppo per "goderti" questa e altre tecnologie nuove di MS devi aggiornare le tue vecchie conoscenze di c#, non ho idea a "quando" sei rimasto ma tanto per darti una linea da seguire ti elenco i maggiori cambiamenti su cui vorresti aggiornarti e che oggi sono fondamentali:
    - c# 2: Generics e Collection Generics
    - c# 3: LINQ (è una tecnologia vasta che ha portato al linguaggio un estensione notevole: inferenza di tipo e parola chiave var, metodi anonimi, collection initializer, alberi di espressione e molto altro, vale la pena dare una lettura per ognuno degli argomenti.)
    - c# 4: Dynamics (la novità meno essenziale di tutte ma vale la pena darci un occhiata)

  3. #3
    Utente di HTML.it L'avatar di ybla82
    Registrato dal
    Jan 2009
    Messaggi
    92
    Ciao,
    ti ringrazio per la risposta esauriente.

    Ti vorrei chiedere ancora una cosa, su cui vorrei un maggiore approfondimento.
    Ai tempi del c# 2.0 c'era ADO.NET con i suoi dataset, dataTable e TableAdapter customizzati sul tipo di db. Più o meno automaticamente potevi creare degli oggetti che ti permettevano di avere l'accesso ai dati. Quello strumento a me non è mai piaciuto, soprattutto per le limitazioni in caso di elaborazioni più complesse e particolari.
    Questo nuovo strumento che mi hai descritto, ha limitazioni simili, o è più dinamico? Mi spiego meglio: è possibile eseguire query particolari, magari anche di aggregazione dei dati, senza la necessità di dover costruire un layout esagerato sopra, e sfruttando quanto già generato automaticamente?
    L'accesso al db si occupa anche della gestione delle transazioni?
    Quanto è tipizzato su SqlSever, piuttosto che su mySql o Oracle?

    Ti ringrazio.

  4. #4
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    Non c'è il dataset, la query la fai con LINQ alle liste di oggetti in memoria. Queste liste (Entityset o DBSet) sono mappate sulle tabelle sottostanti per cui una query su queste liste "in memoria" in realtà viene tradotta in una query sql verso il db sottostante. Non ci sono limiti alla complessità delle query anzi, il lavoro è molto piu semplice perchè le join sono automatiche. Una relazione uno a molti tra Categorie e Prodotti viene tradotta in una proprietà List<Prodotti> dentro la classe Categoria, cio che faresti con una join in EF si fa piu o meno con un "List<Prodotti> lista = categoria.Prodotti".
    Il prezzo da pagare per questa semplicità è che non si ha il pieno controllo delle query sottostanti e se si perde di vista questo si rischia di fare delle query troppo complesse al db creando appunto dei cali di performance. L'argomento in questo senso è abbastanza vasto e va studiato.

    Come ti dicevo le operazioni CUD non avvengono in tempo reale ma vengono memorizzate in una sorta di "coda" dall'oggetto context il quale espone un metodo di salvataggio. Questo metodo, in automatico e in un transactionscope, esegue una per una tutte le query verso il db e se una sola non va a buon fine l'intera operazione viene annullata.

    C'è il pieno supporto per sqlserver mentre è cura dei singoli rdbms fornire un driver proprietario per interfacciarsi con ef. MySql e Oracle per quanto ne so supportano abbastanza bene EF.

  5. #5
    ciao, mi intrometto nel discorso per dire anche il mio parere.

    Riguardo al codice presente nel global.asax, non sono per niente d'accordo.
    Questa è una cosa che facevo (e facevo male) ai tempi di asp.

    Un'applicazione web, essendo multithread ed essento multiutente, non dovrebbe avere una connection condivisa e statica!!!!
    Non ho capito benissimo cosa intendi per OggettiHandler, ma nemmeno quelli li metterei in una collection statica.

    Piuttosto userei una classe DBHelper che si occupa di comunicare con il DB. Questa classe deve esporre dei semplici metodi per connettersi e richiedere dati al DB. Ogni pezzo di codice usa DBHelper per fare le query, ma niente è statico all'interno della classe DBHelper, tranne lei stessa.
    Vedi ad esempio Data Access Application Block , o questi esempi:
    http://www.codeproject.com/Articles/...in-C-and-NET-2
    http://msdn.microsoft.com/en-us/library/aa581778.aspx
    http://www.c-sharpcorner.com/uploadf...egant_dal.aspx

    Questa soluzione è implementabile anche con LINQ 2 SQL o con EF (Entity Framework)
    I pro e i contro te li ha già spiegati rsdpzed, ma vorrei fare una precisazione per non confondere le idee:

    LINQ != LONQ2SQL

    Una cosa è poter effettuare delle interrogazioni a degli oggetti in memoria (vedi liste), un'altra cosa è avere uno strato OR/M con SQL.

    Occhio alla differenza, non parlate semplicemente di LINQ intendendo LINQ2SQL, sono ben diversi!!!!

    ciao

  6. #6
    Utente di HTML.it L'avatar di ybla82
    Registrato dal
    Jan 2009
    Messaggi
    92
    Ciao,
    grazie per il commento.

    In realtà quello che proponi in parte lo faccio già. I vari OggettiHandler, al loro interno contengono un riferimento all'oggetto Connessione: questa è una classe che contiene i metodi base per interfacciarsi al db(ExecuteCommand, ExecuteQuery, etc...) oltre all'istanza della connessione. In questo senso quindi ho già un oggetto DbHlerp.
    All'interno di una pagina poi recupero un oggettoHandler creato precedentemente che si occupa di recuperare i dati.
    Una cosa del genere:
    codice:
    aoList = m_oNewsHandler.GetAll();
    La getAll contiene al suo interno la query, che viene data in pastao a questo oggetto "DbHelper", non visibile a chi usa l'interfaccia.


    La differenza invece è che io gestisco le cose in maniera statica.
    Con la tua soluzione invece come ti comporti? L'oggetto DbHelper crea la connessione di volta in volta? In questo modo se non ho capito male avresti nella classe statica solo la stringa di connessione ( o poco altro).

    Il fatto di usare LINQ2SQL , come si integra in una struttra del genere? Dovrei rifare tutto?

  7. #7
    ok, ho capito.
    be, ci siamo, la soluzione è corretta.

    L'unica cosa che non condivido è la staticità della connessione.
    Io nel mio helper (ma anche Application Block se non erro), di statico non ho nulla se non la classe stessa.
    La stringa di connessione la leggo dal web.config, ed un metodo equivalente al tuo GetAll, fa una cosa del genere:

    codice:
    function List<News> getAll()
    {
        String sSQL = "......";
        IDataReader dr = DBHelper.ExecuteReadeer(sSQL);
        ....
        ....
    }
    codice:
    function IDataReader ExecuteReader(string sql)
    {
        using(sqlConnection conn = ... ...)
        {
            ...
            ...
            conn.Open();
            ...
            ...
        }
    }
    naturalmente con relativi try catch, chiusure oggetti ecc, ecc

    Ma quello che volevo farti vedere, è che la connessione ed il comando vengono creati al volo, eseguiti e subito distrutti.

    naturalmente vorrei e gradirei pareri anche dagli altri per confrontarci

    ciao

  8. #8
    Utente di HTML.it L'avatar di ybla82
    Registrato dal
    Jan 2009
    Messaggi
    92
    ma secondo te, avere l'oggetto connessione statico, che problema può causare?

    E' possibile che la richiesta di due connessioni provenienti da due differenti browser, implichi che venga eseguita prima una richiesta e poi l'altra?

    Questa architettura deriva da una progettazione fatta per una applicazione desktop, in cui creavo gli oggetti connessione e i vari handler all'inizio e che quindi erano disponibili per tutta la durata dell'esecuzione dell'applicazione. Ma in contesto del genere ovviamente non avevo il multi user ( almeno non sullo stessa istanza dell'applicaizone )

    Ti ringrazio.

  9. #9
    il fatto di avere una connessione statica, potrebe crearti qualche problema.

    Ora, io non so bene come e quando la istanzi, ma essendo statica, potrebbe benissimo rimanerti appesa qualche connessione che magari rimane aperta (per errore o svista)

    sempre meglio crearla al volo e distruggerla subito.
    Spulciano bene la libreria ApplicationBlock.Data.dll di microsoft, ti confermo che anche questa è fatta così.

    L'unico motivo per cui puoi avere una connessione da tenere "in vita" più a lungo e non distruggerla immediatamente dopo aver letto i dati, è se hai un DataReader con connessione "esterna" alla tua classe, ma non credo sia il tuo caso.

    ciao

  10. #10
    Utente di HTML.it L'avatar di ybla82
    Registrato dal
    Jan 2009
    Messaggi
    92
    La connessione di fatto viene sempre chiusa, quindi da quel punto di vista lì sono tranquillo.
    Anche perchè di fatto è tutto isolato in poche righe di codice che vengono continuamente richiamate.

    Mi rimangono invece dei dubbi sull'osservazione che ho fatto prima, ovvero se due query provenienti da due browser differenti possano in qualche modo dover rispettare un ordine di esecuzione.

    Comunque mi sto convincendo che forse è necessario apportare delle modifiche alla struttura per una gestione più sicura.

    Alla fine terrei statica solo la connectionString, e poi creo la connessione di volta in volta.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.