Meglio scrivere la libreria .NET tenendo conto delle limitazioni COM, oppure separare la libreria .NET da Interop?

8

Mi sono imbattuto in questo interessante articolo: Come mi è piaciuto amare COM Interoperabilità su CodeProject, che mi ha fatto pensare ...

L'autore sostiene che non vogliono alcuna COM-libreria nella propria libreria .NET perché toglie la bellezza della propria libreria .NET. Piuttosto, preferirebbe scrivere una libreria Interop separata che esponga la loro libreria .NET a COM. Questa libreria di interoperabilità gestirà il fatto che COM non supporta i costruttori con parametri, metodi sovraccaricati, generici, ereditarietà, metodi statici, ecc.

E anche se penso che sia molto originale, non si limita a completare il progetto?

  • Ora è necessario testare la libreria .NET e una libreria Interop.
  • Ora hai bisogno di dedicare del tempo a capire come aggirare la tua bellissima libreria .NET ed esporla a COM.
  • Devi, efficacemente, raddoppiare o triplicare il conteggio delle classi.

Posso sicuramente capire se hai bisogno della tua libreria per supportare sia COM che non COM. Tuttavia, se si intende utilizzare solo la COM, questo tipo di progettazione offre vantaggi che non vedo? Guadagni solo i vantaggi del linguaggio C #?

Oppure, rende più semplice il controllo delle versioni della tua biblioteca fornendoti un wrapper? Rende più veloci i test delle unità non richiedendo l'uso di COM?

    
posta robodude666 24.03.2015 - 16:09
fonte

3 risposte

5

However, if you only intend to use COM does this sort of design bring any benefits that I don't see?

Questo frammento della tua domanda è la parte più importante della tua decisione di progettazione qui, e la risposta è (come sempre) dipende .

Se si intende utilizzare la libreria solo tramite COM Interop, è necessario progettare l'intero sistema tenendo conto di ciò. Non c'è motivo di triplicare il conteggio delle righe. Più LoC nel sistema, più difetti avrà. Pertanto, è necessario progettare il sistema in modo che utilizzi solo le funzionalità COM compatibili.

Tuttavia , non riesco a pensare a una buona ragione per limitare l'uso di una libreria .Net a COM. Perché non vorrei vuoi essere in grado di utilizzare l'assembly in un altro codice .Net? Ha poco senso limitarsi in questo modo.

Ho una certa esperienza con questo, quindi condividerò come l'ho gestito. Non è certamente l'ideale. Ho fatto qualche scambio. Io uso solo una facciata per le classi COM (davvero le interfacce) che sono incompatibili con i più recenti idiomi .Net, altrimenti espongo direttamente l'interfaccia .Net a COM. Questo in pratica significa che io uso una facciata per qualsiasi interfaccia che usi i generici. I generici sono l'unica cosa che ho trovato che sono semplicemente incompatibili. Sfortunatamente, questo significa una facciata per tutto ciò che restituisce un IEnumerable<T> , che è abbastanza comune.

Tuttavia, questo non è così male come sembra, perché la classe della facciata eredita dalla tua classe .Net e implementa un'interfaccia Interop specifica. Qualcosa come questo.

namespace Company.Product.Feature
{
    public class MyClass : INetInterface 
    {
        // lots of code
    }
}

namespace Company.Product.Interop
{
    public class MyClass : Feature.MyClass, IComInterface
    {
        // over ride only the  incompatible properties/methods
    }
}

Questo mantiene il tuo codice duplicato al minimo e protegge la tua interfaccia COM da modifiche "non intenzionali". Man mano che la tua classe principale / interfaccia cambia, la classe dell'adattatore deve superare più metodi (o interrompere l'interfaccia e battere il numero della versione principale). D'altra parte, non tutto il tuo codice Interop è memorizzato nello spazio dei nomi Interop , il che può portare a un'organizzazione dei file confusa. Come ho detto, è un compromesso.

Per un esempio completo, puoi sfogliare il SourceControl e Interop cartelle del mio repository. ISourceControlProvider e GitProvider saranno di particolare interesse.

    
risposta data 04.04.2015 - 21:11
fonte
7

it takes away from the beauty of their .NET library

Quell'autore ha bisogno di uno schiaffo di risveglio. Per qualsiasi progetto professionale, l'obiettivo è quello di creare software di lavoro che le persone vogliano utilizzare. Ogni tipo di idea sbagliata sulla bellezza viene dopo molto tempo. Se questo è il loro unico ragionamento, l'autore ha perso ogni credibilità.

Essere in grado di contrassegnare le tue classi come com-visibili e poter comunicare con il tuo codice .NET tramite COM è estremamente utile. Scartare che il grande beneficio per la produttività per la bellezza è folle.

Tuttavia, far funzionare le cose con COM richiede alcuni compromessi, che richiedono che un costruttore no-arg sia uno di questi e alcune delle altre cose che hai menzionato. Se queste sono funzionalità che non stai utilizzando in ogni caso, o non ti farà male non usarle, allora c'è molto lavoro da salvare usando la stessa classe per COM e non com.

D'altra parte, se i tuoi client COM si aspettano un'interfaccia radicalmente diversa, ha dipendenze o altre limitazioni che sono cattive da affrontare nelle tue classi .NET, o ti aspetti di cambiare in modo significativo le classi .NET e devi mantenere COM retrocompatibilità, quindi con tutti i mezzi creare una classe di Interop per colmare questa lacuna.

Ma non pensare alla "bellezza". Essere in grado di esporre COM tramite .NET è pensato per farti lavorare. Non creare più lavoro per te.

    
risposta data 24.03.2015 - 16:35
fonte
3

Bene, per essere onesti, l'autore originale di quell'articolo non ha usato la parola "bellezza" in nessun punto del suo articolo, cioè tu, che potrebbe dare un'impressione di pregiudizio a coloro che non hanno avuto il tempo di leggere l'articolo da soli.

Per quanto ho capito quell'articolo, la libreria .NET esisteva già e veniva scritta senza COM in mente, probabilmente perché nel momento in cui la libreria è stata creata, non era necessario supportare COM.

Successivamente, è stato introdotto il requisito aggiuntivo di supportare la COM. Di fronte a una situazione del genere, hai due opzioni:

  • ridisegna la lib originale per renderla compatibile con l'interoperabilità COM (con il rischio di rompere le cose)

  • lascia la libreria di lavoro originale per lo più così com'è, e invece crea un assembly separato con la funzione di un "wrapper" (o "adapter")

La creazione di wrapper o adattatori è un schema di progettazione ben noto (o in questo caso più un modello architettonico), e i pro e i contro sono anche ben noti. Un argomento per questo è la migliore "separazione delle preoccupazioni", e questo non ha nulla a che fare con la bellezza.

Per le tue preoccupazioni

Now you need to unit test your .NET library AND an Interop library.

Quando si presenta l'interfaccia COM alla libreria .NET esistente mediante riprogettazione, è necessario testare anche tale interfaccia. L'introduzione di un adattatore scritto manualmente potrebbe richiedere alcuni test aggiuntivi che l'interfaccia sta funzionando, ovviamente, ma non è necessario copiare tutti i test delle unità della funzionalità di business principale della libreria. Non dimenticare che è solo un'altra interfaccia per la lib.

Now you need to spend time figuring out how to work around your beautiful .NET library and expose it to COM.

Quando devi ridisegnare la libreria originale devi capirlo anch'io, e immagino che sarà molto più lavoro.

You need to, effectively, double or triple your class count.

Solo per le classi che sono esposte tramite l'interfaccia COM pubblica, che dovrebbe essere un piccolo numero della parte delle classi della libreria originale.

Ho detto che, per una situazione diversa da te menzionata, quando sai già che devi supportare COM come un cittadino di prima classe fin dall'inizio, penso che tu abbia ragione: uno dovrebbe salvare la seccatura di aggiungere un adattatore separato lib e progettare la lib .NET con il supporto COM direttamente.

    
risposta data 04.04.2015 - 12:46
fonte

Leggi altre domande sui tag