Singleton e HttpApplicationState

Em um aplicativo da web, preciso ter apenas uma instância de uma class chamada ProcessManager. Uma maneira é torná-lo um singleton. A outra maneira é usar o HttpApplicationState para ter certeza de que eu sempre acesse a mesma instância, assim:

public static ProcessManager ProcessManager { get { HttpApplicationState applicationState = HttpContext.Current.Application; if (applicationState["ProcessManager"] == null) { applicationState["ProcessManager"] = new ProcessManager(); } return (ProcessManager)applicationState["ProcessManager"]; } } 

Qual método é melhor e por quê?

Com base na descrição limitada que você deu, eu escolheria um Singleton, porque ele não tem dependência do HttpContext.Current e pode ser usado fora do pipeline do ASP.Net (por exemplo, quando você deseja gravar testes unitários.)

(Como um aparte, quando você coloca algo no ApplicationState, você também precisa primeiro chamar o Lock () nele, e então Desbloquear () depois de terminar de escrever para ele, para ter certeza de que ele é thread safe.)

Como alternativa, permita a injeção de um HttpContext ao criar o seu ProcessManager, de modo que você possa usá-lo com um HttpContext falsificado.

Se você pretende implementá-lo como singleton, como por Jon Skeet (também conhecido como C # guru), ele pessoalmente prefere o código abaixo

 public sealed class Singleton { static readonly Singleton instance=new Singleton(); // Explicit static constructor to tell C# compiler // not to mark type as beforefieldinit static Singleton() { } Singleton() { } public static Singleton Instance { get { return instance; } } } 

(Estou assumindo que seu construtor ProcessManager é privado.)

Torná-lo um singleton real seria melhor, porque essa abordagem tornaria estruturalmente impossível para outros programadores que estão mantendo seu código acidentalmente criar várias instâncias. Não há nada que impeça que um consumidor acesse o HttpApplicationState diretamente e remova e substitua a instância do ProcessManager. Portanto, você deve confiar na convenção para proteger a instância do ProcessManager no HttpApplicationState.

Somente se houver um caso de uso real para várias instâncias da class existir, faz sentido permitir várias instanciações, enquanto se baseia na convenção para proteger a instância no HttpApplicationState.