Referencia
Mantener tu app en funcionamiento
La reflexión, la serialización, la DI, EF y XAML resuelven nombres en tiempo de ejecución — esto es lo que Nebula preserva automáticamente y cómo preservar el resto.
La ofuscación renombra tipos y miembros. Lo único que rompe una app es cuando algo se busca por nombre en tiempo de ejecución — reflexión, serialización, DI por convención, enlace de XAML/Razor, enlace de configuración — y ese nombre fue renombrado. Esta página explica qué preserva Nebula por ti y cómo preservar cualquier otra cosa.
La regla de oro: si el código (o un framework) encuentra un tipo o miembro por su nombre en forma de cadena en tiempo de ejecución, ese nombre debe preservarse. Si se encuentra por identidad de tipo (
typeof, genéricos, DI por tipo), la ofuscación es transparente.
Qué preserva Nebula automáticamente
autoDetect está activado de forma predeterminada y escanea tu ensamblado en busca de nombres que deben sobrevivir:
- Reflexión por cadena — se preserva todo lo que se pasa a
Type.GetType,Assembly.GetType,Activator.CreateInstance,AppDomain,GetMethod/GetProperty/GetFieldmediante un literal. - Contratos de serialización — se conservan los tipos/miembros con atributos
[Serializable],[DataContract]/[DataMember],System.Text.Json([JsonPropertyName],[JsonConverter]),Newtonsoft.Json([JsonProperty],[JsonObject]) oSystem.Xml.Serialization([XmlElement], …), de modo que las formas serializadas no cambian. - Contratos de interfaz/virtuales — los miembros que implementan una interfaz que Nebula no puede ver, o que sobrescriben una base externa, se preservan de forma conservadora.
Cada ejecución registra lo que conservó: auto-detect: preserving N name(s) referenced via reflection/serialization/attributes.
Preservar nombres específicos
Cuando algo se resuelve por un nombre que la detección automática no puede ver (p. ej. un nombre construido en tiempo de ejecución, o una convención), presérvalo de forma explícita. Tres maneras, de ámbito más fuerte a más débil:
1. En la configuración — exclude acepta nombres completos de tipo (preserva el tipo + todos sus miembros) o Type.Member (un solo miembro); excludeNamespaces preserva espacios de nombres completos:
{ "preservePublicApi": true,
"exclude": ["MyApp.Models.Customer", "MyApp.Api.OrderController.Create"],
"excludeNamespaces": ["MyApp.PublicContracts"] }
2. Con un atributo — anota el código con el atributo de la BCL System.Reflection.ObfuscationAttribute (no se necesita una referencia a Nebula):
[System.Reflection.Obfuscation(Exclude = true, ApplyToMembers = true)]
public class Customer { public string Name { get; set; } }
3. Preservar toda la superficie pública — preservePublicApi: true conserva todos los nombres públicos/protegidos (el valor predeterminado para bibliotecas).
includees la lista de permitidos inversa: cuando se establece, solo los tipos listados son elegibles para el renombrado y todo lo demás se preserva — útil para proteger un único espacio de nombres interno.
Frameworks comunes
- Serialización JSON / XML — los nombres de las propiedades se convierten en el formato de transmisión. Mantén los atributos (autodetectados) o excluye los DTO; de lo contrario, un
Customer.Namerenombrado se serializa comoa.by rompe el intercambio de ida y vuelta con otros sistemas. - Inyección de dependencias —
AddScoped<IFoo, Foo>()se basa en el tipo y es segura. El registro por escaneo de ensamblados o por convención (p. ej. “todo lo que termina enService”) depende de los nombres — preserva los tipos escaneados. - Entity Framework Core — los nombres de las propiedades de las entidades se asignan a columnas y las migraciones los referencian; preserva los tipos/propiedades de las entidades, o usa asignaciones explícitas
HasColumnNamepara que el esquema de la BD sea independiente de los nombres ofuscados. - Enlace de opciones / configuración —
Configuration.Bind/IOptions<T>asignan claves de configuración a nombres de propiedades; preserva esas clases de configuración. - XAML de WPF / MAUI y Blazor — preserva los modelos de vista y los miembros enlazados en el marcado (consulta Proteger distintos tipos de proyecto).
Cadenas frente a nombres
El cifrado de cadenas oculta los literales de cadena en tu código; no toca los nombres de los miembros. Los nombres de los miembros se gestionan mediante las reglas de renombrado/preservación anteriores. Por eso cifrar cadenas nunca rompe la reflexión — un miembro preservado mantiene su nombre estén o no cifradas otras cadenas.
Un flujo de trabajo seguro
- Ofusca primero con
preservePublicApi: trueyautoDetect: true(conservador). - Ejecuta tu suite de pruebas completa / app contra la compilación protegida — esta es la comprobación real.
- Si algo que se resuelve por nombre se rompe, añade un
excludeespecífico o un atributo[Obfuscation]— no desactives una pasada entera. - Ajusta (desactiva
preservePublicApipara las apps) una vez que esté en verde.
Si una compilación protegida lanza una excepción, Solución de problemas asigna la excepción a su solución, y la desofuscación convierte una traza de pila renombrada de nuevo en los nombres originales.