2010-07-22 12 views
16

Ho sempre contrassegnato i miei assembly .NET come visibili a COM con [assembly: ComVisible(true)], pensando che non so mai quando qualcuno potrebbe aver bisogno di chiamarli da COM. Ho anche iniziato ad usare FxCop e cominciato a vedere questo avvertimento da analisi del codice:Perché contrassegnare un assieme ComVisible (true) scoraggiato?

CA1017: Microsoft.Design: Perché 'MyLibrary.dll' espone esternamente tipi visibili, contrassegnare con ComVisible (false) a livello di assieme e poi contrassegnare tutti i tipi all'interno dell'assemblea che dovrebbe essere esposto al client COM con ComVisible (vera)

c'è qualche motivo per cui non dovrebbe semplicemente vuole tutte dei tipi di pubblico esposti a COM? Immagino che ci sia, ma non riesco a immaginare quale sia questa ragione. Semmai, sembra decisamente sconveniente.

risposta

22

Non ho lavorato con l'interoperabilità COM per un po 'di tempo, ma in passato ho sempre lavorato con la filosofia "opt-in" piuttosto che con "opt-out", cioè piuttosto che rendere visibile tutto ciò che è COM, contrassegno il assemblaggio come non visibile COM. Mi concentro quindi sull'esposizione selettiva di tipi \ membri (cioè optando in), e mi assicuro che l'API che viene esposta sia sana per COM (ad esempio COM non supporta Genrics, overload di metodi o costruttori che prendono parametri) e anche che ha stato testato con COM in mente. In questo modo, l'esposizione di un'API a COM viene eseguita in modo rigoroso, testato, limitato e gestibile.

Questo è l'opposto di rendere tutto COM visibile e quindi preoccuparsi di eventuali problemi futuri, tenendo presente che se si è esposto tutto, potrebbero esserci accoppiamenti con gli utenti dell'interfaccia COM che non ci si aspettava e che verranno ora avere difficoltà a uscire.

Dalla memoria un paio di esempi di conseguenze inaspettate:

  1. Durante l'esportazione di metodi di overload, vengono esportati e denominate di default con un numero di sequenza per esempio OverloadedMethod1, OverloadedMethod2, ecc. Se si effettua il refactoring del codice e si modifica l'ordine dei metodi o si inserisce un sovraccarico, ecc., Si è quindi in difficoltà con chiunque abbia utilizzato questi metodi dalla precedente interfaccia COM. OverloadedMethod1 e OverloadedMethod2 potrebbero essere stati scambiati.

  2. Le classi esposte a COM devono disporre di un costruttore senza parametri. Se non esiste un test unitario che mantenga questo contratto, allora è facile cambiare quella classe in un secondo momento in modo che non abbia un costruttore senza parametri e quindi interrompa gli utenti dell'interfaccia COM.

La cosa fondamentale è che l'esportazione di un interfaccia COM non viene gratis in quanto vi sono incompatibilità e requisiti che devono essere soddisfatti. Questo deve essere pensato e poi mantenuto. Attenzione CA1017 allude a questo.

5

Con l'avvento dei farmaci generici e di altri tipi avanzati, è più comune ora metodi per esporre i tipi che non può essere COM visibile di quello che è per loro di esporre i tipi che può.

Il metodo raccomandato in CA1017 ha lo scopo di incoraggiare a esporre solo quei tipi che si intende per essere esposto a COM.

2

Contrassegnare l'assieme non visibile COM è molto utile when you have a bunch of public classes inside that you don't want to expose to COM. Tali classi potrebbero ad esempio essere classi proxy di un servizio Web che il tuo assembly consuma. O contrassegni accuratamente ciascuna classe di questo tipo non COM visibile o contrassegni semplicemente l'assembly non COM visble e quindi contrassegni ciascuna classe per esporla a COM. Questo è un grado molto più elevato di controllo e minore manutenzione.

4

Per riferimento, se non viene applicato alcun livello di assembly ComVisibleAttribute, si presuppone che tutte le classi pubbliche siano COM Visible. Non riuscendo a segnare un assieme come [assembly: ComVisible(false)] provocherà spesso il seguente avviso analisi del codice, anche per i tipi che non sono contrassegnati [ComVisible(true)]:

CA1405: COM tipi di base di tipo visibile dovrebbero essere COM visibile

1

E 'facile e dato su MSDN. questo è il modo come risolvere questo avviso:

using System; 
using System.Runtime.InteropServices; 

[assembly: ComVisible(false)] 
namespace InteroperabilityLibrary 
{ 
    [ComVisible(false)] 
    public class BaseClass 
    { 
     public void SomeMethod(int valueOne) {} 
    } 

    // This class violates the rule. 
    [ComVisible(true)] 
    public class DerivedClass : BaseClass 
    { 
     public void AnotherMethod(int valueOne, int valueTwo) {} 
    } 
} 

Se la classe base è in alcun dll cui si fa riferimento nel codice. Quindi, Crea [COMVisibible (True)] per la classe derivata. Funziona nel mio scenario.

+0

La domanda non era come risolvere. La domanda era, in primo luogo, cosa stesse cercando di mettere in guardia da questo avvertimento. – sharptooth

+0

AS MSDN definisce anche la causa principale di questo avviso, ad es. "Un tipo visibile COM (Component Object Model) deriva da un tipo che non è COM visibile." –

+1

Questo non è un problema difficile da trovare anche senza un avviso. Una parte molto volgare e sottile è che avrete tutte le cose pubbliche registrate in COM con un assembly ComVisible. – sharptooth

Problemi correlati