lunes, 16 de julio de 2007

Internos no tan internos

La necesidad de que una clase interna sea accesible desde otro Assembly puede llegar a ser considerado como un problema de diseño, mucho más para mi que me encanta todas esas cuestiones de responsabilidades, patrones y otras yerbas, pero me encontré con dos problemáticas en las cuales necesitaba hacer que una clase interna sea utilizada desde otros Assemblies pero que siga siendo interna.

Caso 1: Extensiones de Domain Objects
Domain Objects está dividido básicamente en 2 assemblies: DomainObjects.Core y DomainObjects.Extensions, la razón de esta división es que el Core es independiente de la base de datos y Extensions tiene todas las dependencias con las bases de datos.
Ahora bien, DomainObjects es uno solo es Core+Extensions, entonces hay clases de Core que tienen que ser internas pero que a su vez Extensions las tiene que poder ver para poder extenderlas.

Caso 2: Generación automática de ServerDelegates y BSDelegates con Exoditus.
Exoditos es una pequeña Tool que hice cuyo objetivo es que al momento que se compila la clase de negocios (BS) Exoditus genere las clases ServerDelegates (fachadas del lado del servidor que son la puerta de entrada a los BSDelegates) y las clases BSDelegates en un Assembly llamado BS.Client.
Ahora bien, por cuestiones técnicas (Exoditus no puede generar clases dentro del Assembly que se está compilando), las clases ServerDelegates están en otro Assembly.
Arquitectónicamente las clases de negocios deberían ser internas y deberían ser accesibles solo por las clases ServerDelegates, por lo tanto las clases internas del BS deberían poder ser accesibles solo por las clases del BS.Client.

Para solucionar esto el .Net Framework provee un atributo aplicable a nivel del Assembly llamado InternalsVisibleTo que permite definir que Assembly puede ver las clases internas del Assembly en cuestión.
Este esquema es seguro ya que es el Assembly el que define en forma específica que otros Assemblies lo puede ver.

Para ello, en la clase AssemblyInfo del proyecto se puede agregar la siguiente línea:

[assembly: InternalsVisibleTo("Domain.Objects.Extensions")]


Sic sic, bonita solución

No hay comentarios: