{"id":1310,"date":"2026-03-21T21:59:12","date_gmt":"2026-03-22T00:59:12","guid":{"rendered":"https:\/\/maurobernal.com.ar\/blog\/?p=1310"},"modified":"2026-03-24T12:20:46","modified_gmt":"2026-03-24T15:20:46","slug":"singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad","status":"publish","type":"post","link":"https:\/\/maurobernal.com.ar\/blog\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\/","title":{"rendered":"Singleton Pattern en C#: Buenas Pr\u00e1cticas, Organizaci\u00f3n y Mantenibilidad"},"content":{"rendered":"\n<p>El patr\u00f3n Singleton es uno de los m\u00e1s conocidos del cat\u00e1logo de Gang of Four \u2014 y tambi\u00e9n uno de los m\u00e1s malentendidos. Bien usado, resuelve problemas reales. Mal usado, se convierte en un generador de bugs sutiles, acoplamiento oculto y tests imposibles de escribir.<\/p>\n\n\n\n<p>En este post vamos a ver c\u00f3mo implementarlo correctamente en C#, cu\u00e1ndo tiene sentido usarlo, y cu\u00e1ndo deber\u00edas elegir otra alternativa.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfQu\u00e9 es el patr\u00f3n Singleton?<\/h2>\n\n\n\n<p>El Singleton garantiza que una clase tenga <strong>una sola instancia<\/strong> durante toda la vida de la aplicaci\u00f3n, y provee un punto de acceso global a esa instancia. Pertenece a la familia de patrones creacionales.<\/p>\n\n\n\n<p>El caso de uso cl\u00e1sico: configuraci\u00f3n de la aplicaci\u00f3n, conexiones a recursos costosos, loggers, o cualquier componente del que realmente necesit\u00e9s una \u00fanica instancia.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">La implementaci\u00f3n moderna: Lazy&lt;T&gt;<\/h2>\n\n\n\n<p>En C# moderno, la forma can\u00f3nica de implementar un Singleton thread-safe es con <code>Lazy&lt;T&gt;<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"csharp\" class=\"language-csharp\">public sealed class Singleton\n{\n    private static readonly Lazy&lt;Singleton&gt; _instance =\n        new Lazy&lt;Singleton&gt;(() => new Singleton());\n\n    public static Singleton Instance => _instance.Value;\n\n    private Singleton() { }\n\n    public void DoSomething() { \/* ... *\/ }\n}<\/code><\/pre>\n\n\n\n<p><strong>\u00bfPor qu\u00e9 <code>Lazy&lt;T&gt;<\/code>?<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Thread-safe por defecto:<\/strong> el runtime garantiza que el factory se ejecuta una sola vez, sin que vos tengas que escribir un solo lock.<\/li><li><strong>Lazy initialization:<\/strong> la instancia se crea reci\u00e9n cuando alguien accede a <code>Instance<\/code> por primera vez. Si nunca se usa, nunca se instancia.<\/li><li><strong>Sin boilerplate:<\/strong> nada de double-checked locking manual, que es complejo y propenso a errores sutiles.<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfPor qu\u00e9 sealed?<\/h3>\n\n\n\n<p>Si alguien puede heredar de tu clase Singleton, puede crear instancias adicionales a trav\u00e9s de la clase derivada, rompiendo la garant\u00eda del patr\u00f3n. <code>sealed<\/code> cierra esa puerta.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"csharp\" class=\"language-csharp\">\/\/ &#x2705; Correcto\npublic sealed class Singleton { }\n\n\/\/ &#x274c; Evitar \u2014 heredable\npublic class Singleton { }<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Evoluci\u00f3n hist\u00f3rica: los enfoques anteriores<\/h2>\n\n\n\n<p>Para entender por qu\u00e9 <code>Lazy&lt;T&gt;<\/code> es la mejor opci\u00f3n hoy, vale repasar c\u00f3mo se implementaba antes:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. Eager initialization (est\u00e1tico)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"csharp\" class=\"language-csharp\">public sealed class Singleton\n{\n    private static readonly Singleton _instance = new Singleton();\n    public static Singleton Instance => _instance;\n    private Singleton() { }\n}<\/code><\/pre>\n\n\n\n<p>Thread-safe gracias al garantismo del CLR para inicializadores est\u00e1ticos. Pero la instancia se crea al cargar el tipo, aunque nunca se use.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. Double-checked locking manual<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"csharp\" class=\"language-csharp\">public sealed class Singleton\n{\n    private static volatile Singleton? _instance;\n    private static readonly object _lock = new object();\n\n    public static Singleton Instance\n    {\n        get\n        {\n            if (_instance == null)\n            {\n                lock (_lock)\n                {\n                    if (_instance == null)\n                        _instance = new Singleton();\n                }\n            }\n            return _instance;\n        }\n    }\n\n    private Singleton() { }\n}<\/code><\/pre>\n\n\n\n<p>Funciona, pero es verboso, dif\u00edcil de leer y f\u00e1cil de romper si olvid\u00e1s el <code>volatile<\/code>. <strong>Hoy no hay raz\u00f3n para elegir este enfoque sobre <code>Lazy&lt;T&gt;<\/code><\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Organizaci\u00f3n del c\u00f3digo: estructura recomendada<\/h2>\n\n\n\n<p>Cuando implement\u00e1s un Singleton, segu\u00ed un orden consistente dentro de la clase:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"csharp\" class=\"language-csharp\">\/\/\/ &lt;summary&gt;\n\/\/\/ Singleton para configuraci\u00f3n de la aplicaci\u00f3n.\n\/\/\/ Usa Lazy&lt;T&gt; para thread safety autom\u00e1tico.\n\/\/\/ Consider\u00e1 DI como alternativa si necesit\u00e1s testeabilidad.\n\/\/\/ &lt;\/summary&gt;\npublic sealed class AppConfiguration\n{\n    \/\/ 1. Instancia est\u00e1tica privada\n    private static readonly Lazy&lt;AppConfiguration&gt; _instance =\n        new Lazy&lt;AppConfiguration&gt;(() => new AppConfiguration());\n\n    \/\/ 2. Acceso p\u00fablico est\u00e1tico\n    public static AppConfiguration Instance => _instance.Value;\n\n    \/\/ 3. Constructor privado\n    private AppConfiguration()\n    {\n        LoadConfiguration();\n    }\n\n    \/\/ 4. Campos inmutables (si los necesit\u00e1s)\n    private readonly string _connectionString;\n    public string ConnectionString => _connectionString;\n\n    \/\/ 5. M\u00e9todos p\u00fablicos\n    public string GetSetting(string key) { \/* ... *\/ return string.Empty; }\n\n    \/\/ 6. Helpers privados\n    private void LoadConfiguration() { \/* leer appsettings, etc. *\/ }\n}<\/code><\/pre>\n\n\n\n<p>Documentar la decisi\u00f3n es parte de la buena organizaci\u00f3n. Un comentario explicando <em>por qu\u00e9<\/em> elegiste Singleton (y no DI) le ahorra horas de confusi\u00f3n a quien lea el c\u00f3digo despu\u00e9s.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Las reglas de oro<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">&#x2705; Hac\u00e9 esto: Singleton sin estado (o inmutable)<\/h3>\n\n\n\n<p>El mejor Singleton es el que no tiene estado mutable. Las operaciones son stateless y solo operan sobre lo que reciben como par\u00e1metro:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"csharp\" class=\"language-csharp\">public sealed class MathHelper\n{\n    private static readonly Lazy&lt;MathHelper&gt; _instance =\n        new Lazy&lt;MathHelper&gt;(() => new MathHelper());\n\n    public static MathHelper Instance => _instance.Value;\n    private MathHelper() { }\n\n    \/\/ Sin estado \u2014 solo l\u00f3gica pura\n    public double CalcularDistancia(Point a, Point b) =>\n        Math.Sqrt(Math.Pow(b.X - a.X, 2) + Math.Pow(b.Y - a.Y, 2));\n\n    public double CalcularIVA(decimal monto, double porcentaje) =>\n        (double)monto * porcentaje \/ 100;\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">&#x274c; Evit\u00e1 esto: estado global mutable<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"csharp\" class=\"language-csharp\">\/\/ &#x274c; Anti-patr\u00f3n: estado global mutable\npublic sealed class AppState\n{\n    private static readonly Lazy&lt;AppState&gt; _instance =\n        new Lazy&lt;AppState&gt;(() => new AppState());\n\n    public static AppState Instance => _instance.Value;\n\n    public string? UsuarioActual { get; set; }  \/\/ Estado mutable \u2014 problema\n    public int ContadorSesiones { get; set; }   \/\/ Estado mutable \u2014 problema\n}<\/code><\/pre>\n\n\n\n<p>Esto crea dependencias ocultas entre distintas partes de la aplicaci\u00f3n. Si alguien modifica <code>UsuarioActual<\/code> en un thread y otro lo lee, ten\u00e9s una race condition. Y en tests, el estado del test anterior contamina el siguiente.<\/p>\n\n\n\n<p><strong>La alternativa:<\/strong> si necesit\u00e1s estado compartido, us\u00e1 DI con servicios scoped\/singleton declarados expl\u00edcitamente, o patrones como CQRS con un store centralizado.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">El elefante en la habitaci\u00f3n: Singleton vs Dependency Injection<\/h2>\n\n\n\n<p>En aplicaciones ASP.NET Core modernas, la recomendaci\u00f3n es clara: <strong>registr\u00e1 tus servicios como singleton en el contenedor de DI en lugar de implementar el patr\u00f3n manualmente<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"csharp\" class=\"language-csharp\">\/\/ En Program.cs\nbuilder.Services.AddSingleton&lt;ILogger, AppLogger&gt;();\nbuilder.Services.AddSingleton&lt;ICacheService, MemoryCacheService&gt;();\n\n\/\/ En tu servicio \u2014 inyectado, no accedido globalmente\npublic class PedidoService\n{\n    private readonly ILogger _logger;\n    private readonly ICacheService _cache;\n\n    public PedidoService(ILogger logger, ICacheService cache)\n    {\n        _logger = logger;\n        _cache = cache;\n    }\n}<\/code><\/pre>\n\n\n\n<p><strong>\u00bfPor qu\u00e9 DI es mejor en este contexto?<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Testeabilidad:<\/strong> pod\u00e9s mockear <code>ILogger<\/code> en tests sin tocar el Singleton real.<\/li><li><strong>Dependencias expl\u00edcitas:<\/strong> los constructores muestran exactamente qu\u00e9 necesita cada clase.<\/li><li><strong>Desacoplamiento:<\/strong> el servicio depende de la interfaz, no de la implementaci\u00f3n concreta.<\/li><li><strong>El container maneja el ciclo de vida:<\/strong> no necesit\u00e1s implementar la l\u00f3gica de instancia \u00fanica vos mismo.<\/li><\/ul>\n\n\n\n<p><strong>\u00bfCu\u00e1ndo s\u00ed tiene sentido el Singleton cl\u00e1sico (est\u00e1tico)?<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Librer\u00edas de utilidades stateless sin dependencias externas.<\/li><li>C\u00f3digo que corre fuera de un host DI (scripts, herramientas de l\u00ednea de comandos simples).<\/li><li>Cuando el overhead del container es genuinamente inaceptable (raro).<\/li><\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Consideraciones para tests<\/h2>\n\n\n\n<p>El mayor problema de los Singletons cl\u00e1sicos es la testeabilidad. Si tu c\u00f3digo hace <code>MiSingleton.Instance.HacerAlgo()<\/code>, no pod\u00e9s reemplazarlo con un mock en tests.<\/p>\n\n\n\n<p>Si aun as\u00ed necesit\u00e1s un Singleton testeable, expon\u00e9 una interfaz:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"csharp\" class=\"language-csharp\">public interface IAppLogger\n{\n    void Log(string mensaje);\n    void LogError(Exception ex, string contexto);\n}\n\npublic sealed class AppLogger : IAppLogger\n{\n    private static readonly Lazy&lt;AppLogger&gt; _instance =\n        new Lazy&lt;AppLogger&gt;(() => new AppLogger());\n\n    public static IAppLogger Instance => _instance.Value;\n\n    private AppLogger() { }\n\n    public void Log(string mensaje) { \/* ... *\/ }\n    public void LogError(Exception ex, string contexto) { \/* ... *\/ }\n}\n\n\/\/ En producci\u00f3n:\nAppLogger.Instance.Log(\"Pedido creado\");\n\n\/\/ En tests: pod\u00e9s mockear IAppLogger sin usar el Singleton real\nvar mockLogger = new Mock&lt;IAppLogger&gt;();<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Inicializaci\u00f3n asincr\u00f3nica: un caso especial<\/h2>\n\n\n\n<p><code>Lazy&lt;T&gt;<\/code> no soporta constructores async. Si tu Singleton necesita inicializaci\u00f3n asincr\u00f3nica (por ejemplo, cargar datos de una base de datos), no lo hagas en el constructor. Us\u00e1 un m\u00e9todo de inicializaci\u00f3n expl\u00edcito:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"csharp\" class=\"language-csharp\">public sealed class DatabaseConfig\n{\n    private static readonly Lazy&lt;DatabaseConfig&gt; _instance =\n        new Lazy&lt;DatabaseConfig&gt;(() => new DatabaseConfig());\n\n    public static DatabaseConfig Instance => _instance.Value;\n\n    private string? _connectionString;\n    private bool _initialized;\n\n    private DatabaseConfig() { }\n\n    \/\/ Inicializaci\u00f3n async separada\n    public async Task InitializeAsync()\n    {\n        if (_initialized) return;\n        _connectionString = await LoadFromSecretsManagerAsync();\n        _initialized = true;\n    }\n\n    private async Task&lt;string&gt; LoadFromSecretsManagerAsync()\n    {\n        \/\/ Llamada async real\n        await Task.Delay(100); \/\/ simulaci\u00f3n\n        return \"Server=...;Database=...;\";\n    }\n}\n\n\/\/ Uso:\nvar config = DatabaseConfig.Instance;\nawait config.InitializeAsync();  \/\/ Llamado expl\u00edcitamente al arranque<\/code><\/pre>\n\n\n\n<p>En ASP.NET Core, esto se maneja mejor con <code>IHostedService<\/code> o llamando al init en el startup pipeline.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Resumen: cu\u00e1ndo s\u00ed, cu\u00e1ndo no<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Situaci\u00f3n<\/th><th>Recomendaci\u00f3n<\/th><\/tr><\/thead><tbody><tr><td>App ASP.NET Core con DI<\/td><td>Us\u00e1 <code>AddSingleton()<\/code> en el container<\/td><\/tr><tr><td>Librer\u00eda de utilidades stateless<\/td><td>Singleton con <code>Lazy&lt;T&gt;<\/code> &#x2705;<\/td><\/tr><tr><td>Estado mutable compartido<\/td><td>Evit\u00e1 Singleton, busc\u00e1 otra soluci\u00f3n<\/td><\/tr><tr><td>L\u00f3gica de negocio<\/td><td>Nunca Singleton \u2014 us\u00e1 DI<\/td><\/tr><tr><td>Necesit\u00e1s testeabilidad<\/td><td>Expon\u00e9 interfaz o us\u00e1 DI<\/td><\/tr><tr><td>Script\/herramienta sin DI<\/td><td>Singleton con <code>Lazy&lt;T&gt;<\/code> puede ser OK<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusi\u00f3n<\/h2>\n\n\n\n<p>El Singleton tiene mala fama en parte merecida \u2014 pero generalmente porque se usa donde no corresponde. La receta para usarlo bien es simple:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><strong><code>sealed<\/code> + constructor privado<\/strong> siempre.<\/li><li><strong><code>Lazy&lt;T&gt;<\/code><\/strong> para thread safety sin drama.<\/li><li><strong>Sin estado mutable<\/strong> \u2014 si necesit\u00e1s estado, hay mejores herramientas.<\/li><li><strong>Document\u00e1 la decisi\u00f3n<\/strong> \u2014 el pr\u00f3ximo developer (quiz\u00e1s vos en 6 meses) va a agradecer el contexto.<\/li><li><strong>Prefer\u00ed DI<\/strong> si est\u00e1s en una aplicaci\u00f3n con contenedor. <code>AddSingleton()<\/code> te da los mismos beneficios con mucha m\u00e1s flexibilidad.<\/li><\/ol>\n\n\n\n<p>El patr\u00f3n no es el problema. El problema es usarlo como caj\u00f3n de sastre para todo lo que quer\u00e9s que sea global.<\/p>\n\n\n\n<p><strong>\u00bfUs\u00e1s Singleton est\u00e1tico o prefer\u00eds DI en tus proyectos? Contame en los comentarios.<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>C\u00f3mo implementar correctamente el patr\u00f3n Singleton en C# con Lazy<T>, cu\u00e1ndo usarlo vs Dependency Injection, c\u00f3mo mantenerlo testeable y los errores m\u00e1s comunes a evitar.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[38,245,267,39,18],"class_list":["post-1310","post","type-post","status-publish","format-standard","hentry","category-blog","tag-net","tag-arquitectura","tag-arquitectura-software","tag-c","tag-dotnet"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Singleton Pattern en C#: Buenas Pr\u00e1cticas, Organizaci\u00f3n y Mantenibilidad &#183; devops Mauro Bernal<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/maurobernal.com.ar\/blog\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Singleton Pattern en C#: Buenas Pr\u00e1cticas, Organizaci\u00f3n y Mantenibilidad &#183; devops Mauro Bernal\" \/>\n<meta property=\"og:description\" content=\"C\u00f3mo implementar correctamente el patr\u00f3n Singleton en C# con Lazy, cu\u00e1ndo usarlo vs Dependency Injection, c\u00f3mo mantenerlo testeable y los errores m\u00e1s comunes a evitar.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/maurobernal.com.ar\/blog\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\/\" \/>\n<meta property=\"og:site_name\" content=\"devops Mauro Bernal\" \/>\n<meta property=\"article:published_time\" content=\"2026-03-22T00:59:12+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-24T15:20:46+00:00\" \/>\n<meta name=\"author\" content=\"Mauro Bernal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@_maurobernal\" \/>\n<meta name=\"twitter:site\" content=\"@_maurobernal\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mauro Bernal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\\\/\"},\"author\":{\"name\":\"Mauro Bernal\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#\\\/schema\\\/person\\\/09c4dbdfb59b20e015c703fd19713283\"},\"headline\":\"Singleton Pattern en C#: Buenas Pr\u00e1cticas, Organizaci\u00f3n y Mantenibilidad\",\"datePublished\":\"2026-03-22T00:59:12+00:00\",\"dateModified\":\"2026-03-24T15:20:46+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\\\/\"},\"wordCount\":941,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#\\\/schema\\\/person\\\/09c4dbdfb59b20e015c703fd19713283\"},\"keywords\":[\".NET\",\"arquitectura\",\"arquitectura-software\",\"c#\",\"dotnet\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\\\/\",\"url\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\\\/\",\"name\":\"Singleton Pattern en C#: Buenas Pr\u00e1cticas, Organizaci\u00f3n y Mantenibilidad &#183; devops Mauro Bernal\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#website\"},\"datePublished\":\"2026-03-22T00:59:12+00:00\",\"dateModified\":\"2026-03-24T15:20:46+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Portada\",\"item\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Singleton Pattern en C#: Buenas Pr\u00e1cticas, Organizaci\u00f3n y Mantenibilidad\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/\",\"name\":\"devops Mauro Bernal\",\"description\":\"Cuando tu trabajo es hacer que las cosas funcionen bien...\",\"publisher\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#\\\/schema\\\/person\\\/09c4dbdfb59b20e015c703fd19713283\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#\\\/schema\\\/person\\\/09c4dbdfb59b20e015c703fd19713283\",\"name\":\"Mauro Bernal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/i0.wp.com\\\/maurobernal.com.ar\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-maurobernal.png?fit=1740%2C1740&ssl=1\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/maurobernal.com.ar\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-maurobernal.png?fit=1740%2C1740&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/maurobernal.com.ar\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-maurobernal.png?fit=1740%2C1740&ssl=1\",\"width\":1740,\"height\":1740,\"caption\":\"Mauro Bernal\"},\"logo\":{\"@id\":\"https:\\\/\\\/i0.wp.com\\\/maurobernal.com.ar\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-maurobernal.png?fit=1740%2C1740&ssl=1\"},\"description\":\"Desarrollo de Sistemas en .Net, IT Callcenters, DBA de SQL Server, Mikrotik, Pentest y T\u00e9cnico consultor de Sistemas Bejerman\",\"sameAs\":[\"https:\\\/\\\/maurobernal.com.ar\",\"https:\\\/\\\/x.com\\\/_maurobernal\",\"https:\\\/\\\/youtube.com\\\/maurobernal\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Singleton Pattern en C#: Buenas Pr\u00e1cticas, Organizaci\u00f3n y Mantenibilidad &#183; devops Mauro Bernal","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/maurobernal.com.ar\/blog\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\/","og_locale":"es_ES","og_type":"article","og_title":"Singleton Pattern en C#: Buenas Pr\u00e1cticas, Organizaci\u00f3n y Mantenibilidad &#183; devops Mauro Bernal","og_description":"C\u00f3mo implementar correctamente el patr\u00f3n Singleton en C# con Lazy, cu\u00e1ndo usarlo vs Dependency Injection, c\u00f3mo mantenerlo testeable y los errores m\u00e1s comunes a evitar.","og_url":"https:\/\/maurobernal.com.ar\/blog\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\/","og_site_name":"devops Mauro Bernal","article_published_time":"2026-03-22T00:59:12+00:00","article_modified_time":"2026-03-24T15:20:46+00:00","author":"Mauro Bernal","twitter_card":"summary_large_image","twitter_creator":"@_maurobernal","twitter_site":"@_maurobernal","twitter_misc":{"Escrito por":"Mauro Bernal","Tiempo de lectura":"7 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/maurobernal.com.ar\/blog\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\/#article","isPartOf":{"@id":"https:\/\/maurobernal.com.ar\/blog\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\/"},"author":{"name":"Mauro Bernal","@id":"https:\/\/maurobernal.com.ar\/blog\/#\/schema\/person\/09c4dbdfb59b20e015c703fd19713283"},"headline":"Singleton Pattern en C#: Buenas Pr\u00e1cticas, Organizaci\u00f3n y Mantenibilidad","datePublished":"2026-03-22T00:59:12+00:00","dateModified":"2026-03-24T15:20:46+00:00","mainEntityOfPage":{"@id":"https:\/\/maurobernal.com.ar\/blog\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\/"},"wordCount":941,"commentCount":0,"publisher":{"@id":"https:\/\/maurobernal.com.ar\/blog\/#\/schema\/person\/09c4dbdfb59b20e015c703fd19713283"},"keywords":[".NET","arquitectura","arquitectura-software","c#","dotnet"],"articleSection":["Blog"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/maurobernal.com.ar\/blog\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/maurobernal.com.ar\/blog\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\/","url":"https:\/\/maurobernal.com.ar\/blog\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\/","name":"Singleton Pattern en C#: Buenas Pr\u00e1cticas, Organizaci\u00f3n y Mantenibilidad &#183; devops Mauro Bernal","isPartOf":{"@id":"https:\/\/maurobernal.com.ar\/blog\/#website"},"datePublished":"2026-03-22T00:59:12+00:00","dateModified":"2026-03-24T15:20:46+00:00","breadcrumb":{"@id":"https:\/\/maurobernal.com.ar\/blog\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/maurobernal.com.ar\/blog\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/maurobernal.com.ar\/blog\/singleton-pattern-en-c-buenas-practicas-organizacion-y-mantenibilidad\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Portada","item":"https:\/\/maurobernal.com.ar\/blog\/"},{"@type":"ListItem","position":2,"name":"Singleton Pattern en C#: Buenas Pr\u00e1cticas, Organizaci\u00f3n y Mantenibilidad"}]},{"@type":"WebSite","@id":"https:\/\/maurobernal.com.ar\/blog\/#website","url":"https:\/\/maurobernal.com.ar\/blog\/","name":"devops Mauro Bernal","description":"Cuando tu trabajo es hacer que las cosas funcionen bien...","publisher":{"@id":"https:\/\/maurobernal.com.ar\/blog\/#\/schema\/person\/09c4dbdfb59b20e015c703fd19713283"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/maurobernal.com.ar\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":["Person","Organization"],"@id":"https:\/\/maurobernal.com.ar\/blog\/#\/schema\/person\/09c4dbdfb59b20e015c703fd19713283","name":"Mauro Bernal","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/i0.wp.com\/maurobernal.com.ar\/blog\/wp-content\/uploads\/2023\/07\/logo-maurobernal.png?fit=1740%2C1740&ssl=1","url":"https:\/\/i0.wp.com\/maurobernal.com.ar\/blog\/wp-content\/uploads\/2023\/07\/logo-maurobernal.png?fit=1740%2C1740&ssl=1","contentUrl":"https:\/\/i0.wp.com\/maurobernal.com.ar\/blog\/wp-content\/uploads\/2023\/07\/logo-maurobernal.png?fit=1740%2C1740&ssl=1","width":1740,"height":1740,"caption":"Mauro Bernal"},"logo":{"@id":"https:\/\/i0.wp.com\/maurobernal.com.ar\/blog\/wp-content\/uploads\/2023\/07\/logo-maurobernal.png?fit=1740%2C1740&ssl=1"},"description":"Desarrollo de Sistemas en .Net, IT Callcenters, DBA de SQL Server, Mikrotik, Pentest y T\u00e9cnico consultor de Sistemas Bejerman","sameAs":["https:\/\/maurobernal.com.ar","https:\/\/x.com\/_maurobernal","https:\/\/youtube.com\/maurobernal"]}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/posts\/1310","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/comments?post=1310"}],"version-history":[{"count":1,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/posts\/1310\/revisions"}],"predecessor-version":[{"id":1311,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/posts\/1310\/revisions\/1311"}],"wp:attachment":[{"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/media?parent=1310"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/categories?post=1310"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/tags?post=1310"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}