Domanda

Sto progettando una libreria di classi riutilizzabile che contiene 2 assembly (tra gli altri) denominati core.xml.dll e core.string.dll.

L'assembly xml fa riferimento all'assembly stringa per utilizzare alcuni metodi di supporto delle stringhe.

Tuttavia ora esiste un metodo stringa che trarrebbe beneficio dall'uso di un metodo contenuto nell'assembly xml.

Se faccio riferimento all'assembly xml dall'assembly stringa, avrò creato una dipendenza circolare e non sarò in grado di costruire entrambi gli assembly dal codice sorgente. (ovvero il problema del pollo e delle uova).

Al fine di seguire il " Non ripetere te stesso " Principio Vorrei evitare di duplicare la funzionalità in entrambi gli assiemi. Se trovo un bug nell'implementazione, voglio solo risolverlo in un unico posto.

Mentre potrei unire gli assiemi in uno, questo non è l'ideale in quanto riduce la coesione dell'assieme.

Avrei bisogno di ricostruire e ridistribuire l'intero assembly solo per una piccola modifica a una classe specifica. Inoltre, alla fine, con così tante dipendenze probabilmente finirei con un grande assemblaggio di biblioteche.

Quindi, nel contesto di una serie riutilizzabile di assiemi di biblioteche, qual è l'approccio migliore da usare qui? Inoltre, in che modo .NET Framework gestisce questo problema?

(In Reflector sembra che System.Configuration.dll faccia riferimento a System.XML.DLL e viceversa. È effettivamente corretto, in tal caso come viene gestita la dipendenza circolare?)

È stato utile?

Soluzione

Accetto con i coltelli. Le dipendenze circolari sono un odore di design. Rifattatelo senza pietà!

Questo può essere difficile nel caso in cui gli oggetti business siano strettamente accoppiati. Nella maggior parte dei casi ciò può essere risolto tramite l'iniezione di dipendenza.

Esempio di Pseudo C ++:

class Employee {
    Company company;
};

class Company {
    vector<Employee> employees;
};

Tricky? Non necessariamente:

template<class CompanyT>
class Employee {
    CompanyT company;
};

class Company {
    vector<Employee<Company> > employees;
};

Tipi più primitivi, che devono dipendere da un livello superiore, possono essere astratti per funzionare con qualsiasi tipo di altro tipo, purché adempia ai suoi contratti.

Altri suggerimenti

Sembra che tu abbia bisogno di un terzo assembly ...

Se la tua libreria String ha davvero bisogno della tua libreria XML, è probabilmente un'indicazione che la tua libreria String deve essere rifattorizzata in una definizione del tipo di dati di livello inferiore e "utilità di base". (nessuna dipendenza esterna, se possibile) e un'altra libreria di livello superiore che può portare in XML, SQL, espressioni regolari o qualsiasi altra cosa che ritieni utile a livello di applicazione.

Rendi questo un metodo di estensione definito nell'assembly xml (basato sul tuo commento "metodo di conversione che accetta XML e converte in un formato basato su stringhe"). Si tratta di XML. Proprio come Linq fa per IEnumerable.

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