Estoy usando el atributo "InternalsVisibleTo" con un ensamblado para exponer los métodos/clases internos a mi proyecto de prueba de unidad.
Ahora necesito instalar ese ensamblaje en el GAC, por lo que debo darle un nombre seguro. Cuando intento hacer eso, aparece el siguiente error en Visual Studio.
Los ensamblados firmados con nombre seguro deben especificar una clave pública en sus declaraciones InternalsVisibleTo
Un poco de Google me llevó al siguiente artículo:
https://msdn.microsoft.com/en-us/library/bb763089.aspx
Este artículo dice:
"Determinar la clave pública para la asamblea de amigos con nombre seguro".
Este artículo no dice cómo determinar la clave pública. ¿Dónde encuentro la clave pública para la asamblea? Además, una vez que tenga la clave pública, ¿sería esta la forma correcta de declarar el atributo?
[assembly: InternalsVisibleTo("Namespace.Assembly.Example.Name, PublicKey=ThePublicKey")]ACTUALIZACIÓN de mayo de 2019: funciona perfectamente con Visual Studio 2019.
Para cualquiera que esté usando Visual Studio 2017, existe el último método:
Desde nuestro querido IDE, vaya a " Herramientas > Herramientas externas... " y " Agregar " una nueva herramienta con esa configuración:
Aplicar/Aceptar esos cambios.
En el "Explorador de soluciones", haga clic en el nombre del ensamblado de su proyecto y luego diríjase a " Herramientas > Obtener clave pública ". La ventana de salida debe mostrar la clave pública (bastante larga), junto con la clave del token público.
Finalmente, en el proyecto que contiene la clase interna (es decir, el proyecto probado) que desea exponer, abra el archivo " AssemblyInfo.cs " y agregue la línea:
[ensamblado: InternalsVisibleTo("MyCompany.SolutionName.ProjectName, PublicKey= Pegue su clave pública aquí ")]
/!\ Debe eliminar los saltos de línea de su clave pública.
Funcionó perfectamente para mí, ¡así que espero que también funcione para ti!
Para usar InternalsVisibleTo con un ensamblaje fuertemente firmado, sus ensamblajes de "amigos" también deben estar fuertemente firmados. El token público del ensamblado de prueba debe especificarse como parte del valor de InternalsVisibleTo .
Tenga en cuenta que el atributo no se usa para la validación real del ensamblado en el momento de la compilación: solo especifica que las comprobaciones en tiempo de ejecución (y las comprobaciones en tiempo de compilación para el ensamblado de un amigo) deben validar esa identidad. Entonces, si solo necesita compilar su ensamblaje principal, puede especificar cualquier token de clave pública (es decir, uno de los ensamblajes de Microsoft que se encuentra en todas las referencias de ensamblaje en su Web.Config, por ejemplo).
En general, dado que firmará ensamblajes, conocerá la clave pública. Es decir, si tiene un archivo snk, entonces sn -t youSnk.snk mostraría la clave pública. O puede seguir los pasos en Obtener token de clave pública de ensamblado dentro de Visual Studio para configurar su VS para mostrar token público para cualquier ensamblado que use sn -Tp {path to assembly} para obtener la clave pública del ensamblado. (Si el documento se ha ido, los pasos se copian a la otra respuesta a esta pregunta )
Utilizo un buen método antiguo de las películas de ficción clásicas: "el hacker siempre adivina la contraseña en un segundo intento". Es una técnica simple y no requiere ninguna herramienta además de lo que ya tiene: algún marco de prueba de unidad. Y sí, el ensamblaje bajo prueba debe estar firmado, como se menciona aquí varias veces.
Copie y pegue esta clase a continuación en su archivo DLL de prueba. Es una prueba xUnit, pero el mismo enfoque funciona bien con cualquier marco de prueba unitaria.
public class FindOutAssemblyPublicKey { const string AssemblyPK = "Swordfish"; /// <summary> /// Fake test to find out a correct PublicKey in InternalsVisibleTo for assembly under test. /// </summary> [Fact] public void AssemblyPublicKeyIsAsExpected() { byte[] publicKey = GetType().Assembly.GetName().GetPublicKey(); var sb = new StringBuilder(); foreach (byte @byte in publicKey) sb.AppendFormat("{0:x2}", @byte); // Set breakpoint here to find out what's in sb Assert.Equal(AssemblyPK, sb.ToString()); } }La idea aquí es bastante simple: la prueba falla en la primera ejecución pero revela una clave pública correcta del ensamblado de prueba. Para verificar dos veces, reemplace "Swordfish" con lo que tiene como valor real, ejecute la prueba por segunda vez para asegurarse de que esté verde y aquí está.