Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

294
Visualizações
¿Cuál es la diferencia entre la clase estática y el singleton en el proyecto .net mvc?

Entiendo la diferencia entre la clase estática y el singleton, lo que es más importante, se puede crear una instancia de singleton una vez, ya que la clase estática no necesita una instancia.

Esta pregunta es con la perspectiva de un proyecto .net mvc, para ayudarme a tomar una decisión entre usar cualquiera de ellos.

Entonces, suponiendo que tengo Clase(s) con métodos como los ejemplos que se dan a continuación:

  1. Tengo un método como ConvertMeterToMiles(int mtr) , donde no se inyecta ninguna dependencia.

  2. O un método como SendEmail(str eaddress) , donde no se inyecta ninguna dependencia pero new SMTPClient... seguido de desechar el SMTPClient en el final

Suponiendo que quiero poner el método en la clase de servicio de utilidad, ¿debería crear una clase estática o singleton (por supuesto con inyección de dependencia)?

Entiendo que no tiene sentido el ámbito o el transitorio porque no hay ningún beneficio en tener nuevas instancias.

over 4 years ago · Santiago Trujillo
7 Respostas
Responde à pergunta

0

Agregar un singleton a través de la inyección de dependencia crea una instancia de la clase solicitada. No se puede crear una instancia de una clase estática, por lo que simplemente accede a sus métodos desde otro lugar, en función de los modificadores de acceso de la clase estática.

over 4 years ago · Santiago Trujillo Relatório

0

Una clase estática es un singleton. La única diferencia entre crear un singleton como un campo estático o mediante inyección de dependencia es cómo se accede a él, eso es todo.

Pero en el contexto de SmtpClient , no es seguro para subprocesos . De hecho, la documentación dice:

Nota

Si hay una transmisión de correo electrónico en curso y vuelve a llamar a SendAsync o Enviar , recibirá una InvalidOperationException .

En otras palabras, no puede enviar dos correos electrónicos al mismo tiempo usando la misma instancia de SmtpClient . Por lo tanto, usar SmtpClient como cualquier tipo de singleton no es una buena idea de todos modos. Es mejor que lo haga con alcance, o que no use DI para nada y simplemente declare uno nuevo cuando lo necesite.

over 4 years ago · Santiago Trujillo Relatório

0

Diría que en el contexto de su aplicación, la diferencia se reduce a usar DI o no y quién controla la vida útil/la creación de instancias/la inyección.

Mover alguna funcionalidad a alguna clase auxiliar estática puede estar bastante bien si no debe diferir según el entorno o alguna otra fuente de variabilidad. Por ejemplo ConvertMeterToMiles parece ser un buen candidato para tal manejo.

SendEmail , por otro lado, no parece ser uno: puede haber entornos en los que no desea enviar correos electrónicos (prueba, por ejemplo), o en el futuro anticipa tener múltiples implementaciones (o necesita volver a implementarlas) para esta funcionalidad ( por ejemplo, para algunos contextos, el envío de correo electrónico se puede diferir utilizando la cola, por ejemplo, que será manejada por algún trabajador en segundo plano u otro servicio). En este caso, puede aprovechar en gran medida la existencia de DI y haber encapsulado esta funcionalidad y ocultarla detrás del contrato (también diría que el manejo de la configuración de SMTPClient es más limpio cuando se registran en DI y se resuelven para una implementación encapsulada).

over 4 years ago · Santiago Trujillo Relatório

0

Recomendaría usar un singleton inyectado. Funcionalmente, hace muy poca diferencia, pero inyectar un singleton tiene grandes ventajas cuando se trata de pruebas .

Si bien los métodos estáticos en sí mismos son fáciles de probar, se vuelve muy difícil probar el código que los usa de forma independiente.

Tomemos su ejemplo de SendEmail(str eaddress) . Si implementamos esto como un método auxiliar estático, será imposible realizar pruebas unitarias del código que utiliza este método sin crear un SMTPClient real. Por el contrario, si inyectamos una clase de ayuda singleton con una interfaz, esta interfaz puede burlarse al probar el código que llama a SendEmail.

over 4 years ago · Santiago Trujillo Relatório

0

Como dijo, se puede crear una instancia de singleton una vez, por lo que es un buen lugar para mantener vivo el objeto, objeto que puede usar durante la vida útil de la aplicación. Para el proyecto mvc, los objetos singleton son los mismos para cada solicitud.

En su método 2, su SmtpClient no necesita crear una nueva instancia y desecharla cada vez.

Del documento msdn:

La implementación de la clase SmtpClient agrupa las conexiones SMTP para evitar la sobrecarga de restablecer una conexión para cada mensaje al mismo servidor. Una aplicación puede reutilizar el mismo objeto SmtpClient para enviar muchos correos electrónicos diferentes al mismo servidor SMTP ya muchos servidores SMTP diferentes. Como resultado, no hay forma de determinar cuándo finaliza una aplicación utilizando el objeto SmtpClient y debe limpiarse.

Por lo tanto, es un buen candidato para el servicio de servicios públicos singleton.

El patrón singleton se verá así:

 public class SmtpUtilityService : ISmtpUtilityService, IDisposable { private readonly SmtpClient _smtpClient; public SmtpUtilityService() { _smtpClient = new SmtpClient([...]); } public async Task SendEmail(str eaddress) { await _smtpClient.SendAsync([...]); } public void Dispose() { if(_smtpClient != null) { _smtpClient.Dispose(); } } }

En su Statup.cs, agregue SmtpUtilityService como singleton a IServiceCollection y su SmtpClient se instanciará solo una vez.

Por cierto, microsoft no recomienda el uso de SmtpClient (obsoleto en algunas plataformas y no recomendado en otras), por lo que no estoy seguro de si es un buen candidato:/

msdn smtpclient obsoleto

Y para su primer método ConvertMeterToMiles(int mtr), es solo una transformación, un cálculo a la vez. no necesita ninguna propiedad y no necesita una instancia. Entonces, la clase estática completa es una buena opción.

 public static class MeterHelper { public static decimal ConvertMeterToMiles(int mtr) { return mtr * 0.0006213712; } }

Personalmente, no suelo usar singleton. Si necesito propiedades, usaré servicios de alcance o transitorios y, si no, usaré clases estáticas completas (ayudantes).

over 4 years ago · Santiago Trujillo Relatório

0

No hay diferencia de funcionalidad entre Singleton y Static.

En un entorno con subprocesos como el que describe, lo único que sería un problema es compartir datos. Si varios subprocesos acceden a las mismas propiedades, habrá problemas de concurrencia.

Ahora, si solo está utilizando métodos de utilidad como Sum(int a, int b) que no tienen ningún estado, no habrá ningún problema.

Ahora, básicamente no hay diferencia en esta situación entre los dos, aparte de la necesidad de inyectar el singleton. Incluso relacionado con la API web, no hay nada realmente especial.

Excepto tal vez que una clase singleton puede heredar y una clase estática no. Pero ese es otro tema.

over 4 years ago · Santiago Trujillo Relatório

0

Permítanme recapitular esto primero: una clase estática no puede tener instancias, por lo que usa sus métodos con el nombre de la clase y una clase única solo puede tener 1 instancia para ser compartida por otros.

para una clase estática, debe incluir eso en su archivo de código. para una clase singleton, primero creará una instancia y luego la pasará a otros métodos en su lista de parámetros.

En el contexto de aspnet, dado que solo tendremos 1 instancia, dejamos su creación y eliminación al marco con services.AddSingleton<ISingleton, Singleton>(); y llévelo a nuestro controlador mediante public SomeController(ISingleton singleton) . cuando los visitantes lleguen a este punto final del controlador, todas sus solicitudes serán diferentes, pero luego serán manejadas por esta única instancia. aspnet determinará qué singletons necesita su controlador, por sus interfaces, e inyectará solo los solicitados.

ya sea un titular de estado global del lado del servidor, un conector de base de datos o un remitente de correo electrónico en su caso, toda la actividad que implemente pasará por esta instancia única. puede implementar un balanceador de carga para que las solicitudes se puedan procesar sin cuellos de botella.

por otro lado, para una clase estática, preferirá métodos de corta duración, ya que se ejecutarán por separado para cada solicitud al controlador. convertidor de distancia es uno de esos métodos. no requerirá largos procesos para hacer su trabajo, ni dependerá de otros recursos costosos. sin embargo, es posible que desee almacenar en caché los cálculos más frecuentes y enviar respuestas desde el caché, entonces sería una mejor idea convertir este convertidor de distancia en un singleton que utiliza recursos durante mucho tiempo.

en resumen, dependiendo del uso de los recursos, preferirá métodos independientes de corta duración o métodos de larga duración con muchas operaciones costosas.


Al ver que OP tiene una confusión sobre SMTPClient que usa, quería agregar algunas líneas más.

debe hacer una pregunta: ¿este cliente abre un canal al servidor SMTP y lo mantiene durante mucho tiempo, o simplemente envía 1 mensaje y debe cerrarse después?

algunos clientes tienen una funcionalidad principal de un solo uso, otros se basan en este comportamiento principal y agregan un conjunto de conexiones preabiertas de un solo uso. la clase funcional central se puede usar tanto como estática, dados recursos como parámetros, o ser un singleton si permite tener recursos inicializados que no sean la conexión en sí. ambos casos necesitarán abrir un canal al servidor SMTP solo cuando se usen, y eso causará demoras. por último, si tiene que cerrarse después de su uso, entonces la funcionalidad principal no se puede usar como un singleton, ya que necesitamos la vida durante la vida de nuestro servicio.

por otro lado, si el cliente usa un conjunto de conexiones, no se puede argumentar que será un singleton y afectará positivamente la experiencia del usuario. una nota al margen aquí será la implementación de la propia clase que tiene este conjunto de conexiones si no hay otra biblioteca actual disponible en el entorno de uso del proyecto.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda