tecnologia objects interfaces component .net com

.net - objects - tecnologia component object model



¿Por qué se desaconseja marcar un conjunto ComVisible(verdadero)? (5)

Siempre he marcado mis ensamblajes .NET como visibles para COM con [assembly: ComVisible(true)] , pensando que nunca sé cuándo alguien podría necesitar llamarlos desde COM. También comencé a usar FxCop y comencé a ver esta advertencia del análisis de código:

CA1017: Microsoft.Design: debido a que ''MyLibrary.dll'' expone los tipos visibles externamente, márquelos con ComVisible (falso) en el nivel del ensamblaje y luego marque todos los tipos dentro del ensamblaje que deberían exponerse a los clientes COM con ComVisible (verdadero)

¿Hay alguna razón por la que no querría que todos sus tipos de público estén expuestos a COM? Supongo que hay, pero no puedo imaginar cuál es esta razón. En todo caso, parece notablemente inconveniente.


Con el advenimiento de Generics y otros tipos avanzados, ahora es más común que los métodos para exponer los tipos que no pueden ser visibles a través de COM que los que pueden exponer los tipos que pueden .

El método recomendado en CA1017 tiene la intención de alentarlo a exponer solo aquellos tipos que pretende exponer a COM.


Es fácil y dado en MSDN. Esta es la forma de 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 está en cualquier dll a la que hace referencia en su código. Luego, haga [COMVisibible (True)] para la clase derivada. Funciona en mi escenario.


La clave es que exportar una interfaz COM no es gratis ya que hay incompatibilidades y requisitos que deben cumplirse. Esto debe ser pensado y luego mantenido. (La advertencia CA1017 alude a esto.)

Por lo tanto, siempre he trabajado con la filosofía "opt-in" en lugar de "opt-out", es decir, en lugar de hacer que todo sea visible COM, marca el ensamblaje como no visible COM. Luego me concentro en exponer los tipos / miembros de forma selectiva (es decir, optando por), y me aseguro de que la API que está expuesta sea sana para COM (por ejemplo, COM no admite genéricos, métodos de sobrecarga o constructores que toman parámetros) y también que tiene ha sido probado con COM en mente. De esta manera, la exposición de una API a COM se realiza de manera rigurosa, probada, limitada y mantenible.

Esto es lo contrario a hacer que todo sea visible en COM y luego preocuparse por posibles problemas más adelante, teniendo en cuenta que si ha expuesto todo, entonces puede haber acoplamientos con usuarios de su interfaz COM que no esperaba y ahora tendrá dificultades para retirarse. de.

De la memoria un par de ejemplos de consecuencias inesperadas:

  1. Al exportar métodos sobrecargados, se exportan y se nombran de manera 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 está en problemas con cualquier persona que ha utilizado estos métodos de 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 hay una prueba de unidad implementada que mantenga este contrato, es fácil cambiar esa clase en una fecha posterior para que no tenga un constructor sin parámetros y, por lo tanto, rompa los usuarios de la interfaz COM.


Marcar el ensamblaje como no visible a COM es muy útil cuando tiene un montón de clases públicas dentro de las que no desea exponer a COM . Esas clases podrían ser, por ejemplo, clases proxy de un servicio web que consume su ensamblaje. O bien, marca a fondo cada clase de este tipo que no es visible a COM o simplemente marca el conjunto que no es visible a COM y luego marca cada clase para exponer a COM. Eso es un grado mucho mayor de control y menos mantenimiento.


Para referencia, si no se aplica ComVisibleAttribute nivel de ensamblaje, se supone que todas las clases públicas son COM visibles. Si no se marca un ensamblaje como [assembly: ComVisible(false)] , a menudo se producirá la siguiente advertencia de Análisis de código, incluso para los tipos que no están marcados [ComVisible(true)] :

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