Domanda

Ho appena finito di guardare un episodio di Bob Martin alla NDC in cui ha detto "usando" le direttive in C # nella parte superiore di una pagina sono sbagliate a causa del forte accoppiamento che creano / implicano tra i componenti.

In che modo è possibile utilizzare le DLL esterne senza aggiungere un riferimento al progetto e un'istruzione using?

Ricordo che V6 ti consentiva di creare un oggetto con la stringa del ProgId - Non sono sicuro che sia la tecnica che sto cercando, ma è un esempio di un linguaggio che non ha bisogno di un riferimento al progetto usare una dll.

EDIT: Ecco un link alla conferenza . Mi dispiace non ho la citazione o il minuto esatti nella presentazione, vado a memoria.

È stato utile?

Soluzione

Non è l'istruzione using stessa ad essere negativa - è se ne ottieni troppi .

Un'istruzione come che utilizza System; è raramente un problema in sé, ma se ne hai molti (direi più di 3-6, a seconda di quali) nello stesso file di codice , potrebbe essere una indicazione di accoppiamento stretto .

Potresti anche applicare una regola empirica simile al numero di riferimenti in un progetto stesso.

La soluzione all'accoppiamento stretto è la programmazione alle interfacce e Dependency Injection (DI).

Il modo ProgId di fare cose che puoi ricordare da VB era semplicemente COM in azione. In sostanza, hai usato quel ProgId per ottenere un riferimento a un'istanza che implementava l'interfaccia desiderata. Lo svantaggio era che funzionava solo quando l'oggetto COM era universalmente registrato. Ricordi l'inferno?

Puoi comunque applicare lo stesso principio usando certe versioni di DI, solo che ora l'interfaccia è di tipo .NET e non definita in IDL, e hai bisogno di una sorta di contenitore DI per fornire l'implementazione concreta.

Altri suggerimenti

Credo che Bob Martin in realtà si riferisca al legame anticipato rispetto a quello tardivo.

In .NET il binding tardivo è possibile tramite reflection e più specificamente la classe Activator che consente la creazione di un tipo in un assembly esterno utilizzando un nome file o un nome assembly.

Normalmente, l'uso delle direttive (non l'istruzione using) vanno di pari passo con il riferimento diretto a un assembly esterno. vale a dire. Aggiungete un riferimento a un assembly e quindi aggiungete usando le direttive per evitare di dover digitare la gerarchia completa dello spazio dei nomi quando utilizzate i tipi esterni.

Quindi, se trovi che il tuo codice ha un gran numero di direttive d'uso in alto, è possibile che tu faccia riferimento a molti altri tipi direttamente e quindi aumenti l'accoppiamento / dipendenza del tuo codice su questi tipi.

Immagino che questo sia il motivo per cui Bob si sta riferendo a loro come cattivo. La risposta alla domanda "è davvero sbagliata?" è molto soggettivo e dipende dal contesto.

In generale, tuttavia, il disaccoppiamento dei componenti è quasi sempre un buon obiettivo da perseguire nella progettazione di software. Questo perché consente di modificare parti del sistema con un impatto minimo sul resto del sistema. Avendo letto uno o due dei libri di Bob Martins, mi aspetterei che questo è ciò a cui sta arrivando.

utilizzando è solo una scorciatoia per gli spazi dei nomi, non sono riferimenti a file esterni. Pertanto, questo non ha proprio senso.

Comunque, ciò che si può fare è avere una DLL di interfaccia (una DLL con solo interfacce), in modo da caricare e utilizzare in modo dinamico diversi assiemi e creare tipi (attraverso la riflessione) che è possibile trasmettere alle interfacce ben note. Questo è il modo corretto di allentare i riferimenti esterni, pur mantenendo i vantaggi del linguaggio fortemente tipizzato e dell'associazione anticipata.

Dai un'occhiata al Assembly e AppDomain per caricare gli assembly e Activator per creare istanze di tipo per nome.

Puoi usare la riflessione:

// Load the assembly
Assembly assembly = Assembly.LoadFrom(@"c:\path\Tools.dll");
// Select a type
Type type = assembly.GetType("Tools.Utility");
// invoke a method on this type
type.InvokeMember("SomeMethod", BindingFlags.Static, null, null, new object[0]);

Puoi fare ciò a cui ti riferisci attraverso la riflessione. È possibile caricare l'assembly in fase di esecuzione e riflettere attraverso di esso per ottenere le classi ecc. E chiamarle in modo dinamico.

Personalmente, non lo farei però per evitare l'accoppiamento. Per me è un cattivo uso della riflessione, e preferirei di gran lunga aggiungerlo al progetto e fare riferimento a esso, a meno che non ci sia un motivo specifico per cui non farlo. Reflection aggiunge sovraccarico al sistema e non si ottiene il vantaggio della sicurezza del tempo di compilazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top