2010-07-22 12 views
16

Siempre he marcado mis conjuntos .NET como visibles para COM con [assembly: ComVisible(true)], pensando que nunca sé cuándo alguien podría necesitar llamarlos desde COM. También empecé a usar FxCop y empecé a ver esta advertencia de análisis de código:¿Por qué se desaconseja marcar un conjunto ComVisible (verdadero)?

CA1017: Microsoft.Design: Porque 'MyLibrary.dll' expone externamente visibles tipos, marcarlo con ComVisible (falso) en el nivel de ensamblado y luego marcar todos los tipos dentro de la asamblea que se deben exponer a los clientes COM con ComVisible (verdadero)

¿hay alguna razón por la que no sólo tendría que desee todos sus tipos públicos expuestos a COM? Supongo que sí, pero no puedo imaginar cuál es esta razón. En todo caso, parece notablemente inconveniente.

Respuesta

22

No he trabajado con COM interopera desde hace bastante tiempo, pero en el pasado siempre he trabajado con la filosofía "opt-in" en lugar de "opt-out", es decir, en lugar de hacer que todo sea visible, marcó el ensamblaje no es COM visible. Luego me concentro en exponer los miembros de los tipos selectivamente (es decir, participando), y me aseguro de que la API que está expuesta esté en forma para COM (por ejemplo, COM no es compatible con Genrics, sobrecarga de métodos o constructores que toman parámetros) y también que tiene probado con COM en mente. De esta manera, exponer una API a COM se hace de una manera rigurosa, probada, limitada y mantenible.

Esto es lo contrario a hacer que todo sea visible y luego preocuparse por posibles problemas posteriores, teniendo en cuenta que si ha expuesto todo, puede haber acoplamientos con usuarios de su interfaz COM que no esperaba y ahora tiene dificultades para retroceder.

de memoria un par de ejemplos de consecuencias inesperadas:

  1. Al exportar métodos sobrecargados, se exportan y se nombran de forma predeterminada con un número de secuencia, por ejemplo, OverloadedMethod1, OverloadedMethod2, etc. Si refactoriza su código y cambia el orden de sus métodos o inserta una sobrecarga, etc., entonces tendrá problemas con cualquiera que haya usado estos métodos desde su interfaz COM anterior. OverloadedMethod1 y OverloadedMethod2 pueden haber sido intercambiados.

  2. Las clases que están expuestas a COM deben tener un constructor sin parámetros. Si no existe una prueba unitaria que mantenga este contrato, entonces es fácil cambiar esa clase en una fecha posterior para que no tenga un constructor sin parámetros y así se rompa la interfaz COM de los usuarios.

La clave es que la exportación de una interfaz COM no viene de forma gratuita, ya que hay incompatibilidades y requisitos que se deben cumplir. Esto tiene que ser pensado y luego mantenido. Advertencia CA1017 alude a esto.

5

Con la llegada de los genéricos y otros tipos avanzados, es más común ahora para los métodos para exponer tipos que no puede ser COM visible de lo que es para ellos para exponer tipos que pueden .

El método recomendado en CA1017 está destinado para animarle a exponer solamente aquellos tipos que intención de estar expuestos a COM.

2

Marcar el conjunto no es visible COM es muy útil when you have a bunch of public classes inside that you don't want to expose to COM. Esas clases podrían ser, por ejemplo, clases proxy de un servidor web que consuma su conjunto. O bien marca completamente cada una de estas clases, no es COM visible, o simplemente marca el ensamblaje no visible y luego marca cada clase para exponer a COM. Eso es un grado mucho más alto de control y menos mantenimiento.

4

Como referencia, si no se aplica ningún nivel de ensamblaje ComVisibleAttribute, se supone que todas las clases públicas son COM Visible. El no poder marcar un conjunto como [assembly: ComVisible(false)] menudo dará lugar a la siguiente advertencia de análisis de código, incluso para tipos que no están marcados [ComVisible(true)]:

CA1405: COM tipos base de tipo visible deben ser COM visibles

1

Es fácil y dan en MSDN. esta es la manera cómo solucionar esta advertencia:

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) {} 
    } 
} 

Si la clase base es de ninguna DLL que usted se refiere en su código. Luego, haga [COMVibible (Verdadero]] para la clase derivada. Funciona en mi escenario.

+0

La pregunta no era cómo solucionarlo. La pregunta era de qué estaba tratando de advertir esta advertencia en primer lugar. – sharptooth

+0

AS MSDN también define la causa raíz de esta advertencia, es decir, "Un tipo visible del Modelo de objetos componentes (COM) deriva de un tipo que no es COM visible". –

+1

No es un problema difícil de encontrar, incluso sin una advertencia. Una parte mucho más sutil y sutil es que tendrá todas las cosas públicas registradas en COM con un ensamblaje ComVisible. – sharptooth

Cuestiones relacionadas