Componentizzazione. Servono strumenti diversi

Ciao,

Vorrei discute un attimo del funzionamento di INDE in un progetto completamente componentizzato.
Dopo un lungo lavoro di ristrutturazione del codice, sono arrivato al punto di avere una applicazione composta solo da un menù e tutta una pletora di componenti che vengono utilizzati alla bisogna.
Il problema nasce dal fatto che TeamWork si è dimostrato inadatto a gestire questo tipo di architettura (l’ho verificato con Lanzi), Il problema sostanzialmente nasce dal fatto che se un componente è completamente isolato, all’atto della compilazione non c’è modo di farlo andare nella bin dell’applicazione. Tutte le volte che compilo devo andare a copiare le dll dalle output dei componenti e portarle dentro la bin dell’applicazione. Questo deriva da fatto che non essendoci riferimenti Inde non considera come ‘necessari al funzionamento’ tali componenti. Mi sono fatto dei .bat che copiano le dll necessarie ma è veramente un ‘casino’ gestire la cosa in questo modo. Mi chiedevo se non fosse possibile inserire un flag sul componente che dica ‘includi sempre nell’applicazione’ (o una cosa del genere).

Grazie

3 Mi Piace

L’argomento è molto interessante. Noi volevamo scorporare il “progettone” in tanti componenti standalone e toglierli dal progetto. Quindi i componenti non erano più presenti nel progetto. Quando l’applicazione (o un altro componente) necessitavano di una funzionalità di un componente, usavano createFormFromLibrary indicando in quale dll cercare la classe/videata.
Funzionava tutto ma ci siamo scontrati su due ostacoli:

  1. Il modulo RTC non è a conoscenza di cosa c’è nelle dll, quindi le videate presenti nei componenti così scorporati non compaiono.
  2. Visto che ogni componente è in un progetto a se stante, c’è la necessità di mantenere allineati la struttura dei database e tutte le costanti/liste valori. Purtroppo lo strumento che TW mette a disposizione per questo è, per noi, lento e macchinoso, aumentando a dismisura i tempi di produzione.

Alla fine, pur mantenendo il progetto suddiviso in componenti (con notevole vantaggio), tutti i componenti sono ancora nel “progettone” dell’applicazione.

Sarebbe veramente bello poter arrivare a scomporre completamente il progetto.

Per risolvere il problema che indichi tu, noi abbiamo fatto così:
In ogni componente abbiamo aggiunto una proceduta pubblica “uncino”, vuota, che richiamiamo nell’Init dell’applicazione. In questo modo l’IDE percepisce il componente come usato ne mette la dll nella bin dell’applicazione.

2 Mi Piace

Confermo. Anche io faccio così.

2 Mi Piace

Grazie del suggerimento Riccardo. Purtroppo non posso fare questa cosa in quanto il mio progetto mira alla totale indipendenza del componente (cosa che sono riuscito ad ottenere) e creare l’uncino farebbe si che a livello applicativo scattino delle cose che non devono scattare. Per capirci, se non “invoco” un oggetto, un metodo, una proprietà di un determinato componente, questi non si deve nemmeno aprire (nel senso che non deve rispondere alle sendAppMessage). Mi accontenterei di non dovere copiare a mano le dll tutte le volte che compilo. Confermo il fatto che il TW non è in grado di gestire questo tipo di gestione ed è un vero peccato perché questa mancanza rende molto complesso l’aggiornamento.

" 1. Visto che ogni componente è in un progetto a se stante, c’è la necessità di mantenere allineati la struttura dei database e tutte le costanti/liste valori. Purtroppo lo strumento che TW mette a disposizione per questo è, per noi, lento e macchinoso, aumentando a dismisura i tempi di produzione."

Riccardo, ho dimenticato di commentare questo tuo punto. Per quanto riguarda l’allineamento del DB io utilizzo TW con le sottoscrizioni. Il progetto di sviluppo ‘master’ pubblica come componente il DB in tw e i progetti titolari dei componenti sottoscrivono e prendono gli aggiornamenti.

1 Mi Piace

Se ho capito bene quello a cui miri, le dll dei componenti non dovrebbero trovarsi nella bin, ma in un’altra cartella, perché altrimenti l’applicazione le carica anche se non le usa (non ne sono certissimo, ma ricordo sia così).
Quindi, le metti un una cartella risorse, e poi tramite funzione istanzi l’oggetto al volo, indicando dove si trova la dll che lo contiene.
A questo punto nasce il problema: come mantengo aggiornata la cartella che contiene le dll di tutti i componenti? Se non ricordo male, anche noi eseguivamo un file bat che si occupava di questo.

1 Mi Piace

Abbiamo provato a seguire questa strada ma, pur funzionando, i tempi di sviluppo erano insostenibili. Magari abbiamo sbagliato qualcosa noi, non saprei. Grazie cmq.

1 Mi Piace

Ciao Riccardo.
Dai test che ho effettuato le dll vengono ‘caricate’ solo se nel codice vi è un riferimento ad un elemento contenute in esse. Questo comportamento lo puoi verificare lanciando un sendAppMessage. Nel debug puoi vedere che i componenti che non sono stati esplicitamente chiamati in questo modo non rispondono al sendAppMessage ed è esattamente quello che volevo. Sulla base di meccanismi che ho implementato provoco l’apertura del componente che mi interessa. Quindi posso avere anche tutti i componenti dentro la bin ma verranno aperti unicamente quelli che gli indico. Per me era importante raggiungere questo risultato per potere ‘comporre’ l’applicazione con i soli elementi necessari a seconda di chi sarà il cliente finale. All’inizio avevo anche io fatto una cosa simile a quella che hai fatto tu. Avevo messo nel componente una variabile chiamata starterVar che aveva come unico scopo quello di provocare l’apertura del componente nel caso in cui nell’afterlogin l’avessi valorizzata. Ho dovuto abbandonare questo approccio in quanto anche il solo fatto di avere una riga di codice che punta al componente ne provoca l’apertura anche se non eseguita. Per evitare questo comportamento ho implementato delle procedure che astraendo i componenti mi permettessero di ‘invocarli’ in modo dinamico aprendo così solo quelli che mi interessavano. In questo modo, sempre osservando il debug, il sendAppMessage viene ricevuto unicamente dai componenti di cui ho provocato l’apertura, a prescindere da quanti ne ho nella bin.

Sono praticamente organizzato così:

  1. Una installazione che contiene l’applicazione e 2 componenti che tassativamente devono essere sempre presenti in tutte le applicazioni. E’ questa l’unica applicazione autorizzata a modificare questi due componenti

  2. Per ogni cliente ho una installazione che contiene l’applicazione, i componenti obbligatori e il componente specifico di quel cliente. Solo questa installazione può modificare il componente del cliente.

Il punto 1 esporta in una cartella di rete i componenti
il punto 2 esporta sempre in quella cartella di rete il solo componente del cliente

Alla fine, nella cartella di rete mi trovo i componenti ‘standard’ e i componenti customizzati dei clienti.
Quindi se sono, ad esempio, nel progetto del cliente, importo i 2 standard e lavoro sul suo. Però tutte le volte che faccio una modifica sul suo Componente, devo copiare la dll nella bin perchè anchlui, come gli altri, non viene mai invocato da nessuno e non ha riferimenti che ne possano provocare l’apertura e la conseguente copia nell bin.

In questa struttura bisogna stare molto attenti a quello che si fa, ma i risultati sono ottimi e la portabilità nonché il mantenimento degli standard e delle personalizzazioni sono ottimi.

1 Mi Piace

“Abbiamo provato a seguire questa strada ma, pur funzionando, i tempi di sviluppo erano insostenibili. Magari abbiamo sbagliato qualcosa noi, non saprei. Grazie comunque.”

Si, è vero. La procedura è lunghetta. Purtroppo non ho trovato vie più veloci. A volte, se ho fretta, comparo i DB dei due progetti e li allineo con il drag & drop. Per questo nel titolo del post ho scritto che servono strumenti diversi che tengono conto di questa architettura anche perché se è quella consigliata è curioso che sia la più penalizzata dagli strumenti di INDE.

1 Mi Piace

Sì, mi pare molto bello. Noi ancora non ci siamo arrivati.

Confermo anche noi abbiamo una procedura statica “BindComponent” in ogni componente e l’app che lo vuole usare deve chiamare in qualche punto del codice questa procedura.

2 Mi Piace