Skip to content

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/GetField mediante 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]) o System.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).

include es 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.Name renombrado se serializa como a.b y 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 en Service”) 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 HasColumnName para 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

  1. Ofusca primero con preservePublicApi: true y autoDetect: true (conservador).
  2. Ejecuta tu suite de pruebas completa / app contra la compilación protegida — esta es la comprobación real.
  3. Si algo que se resuelve por nombre se rompe, añade un exclude específico o un atributo [Obfuscation] — no desactives una pasada entera.
  4. Ajusta (desactiva preservePublicApi para 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.