Generalnie unikam singletonów, ponieważ utrudniają one testowanie aplikacji. Singletony są trudne do podrobienia w testach jednostkowych właśnie ze względu na ich naturę - zawsze otrzymujesz ten sam, a nie taki, który możesz łatwo skonfigurować do testu jednostkowego. Dane konfiguracyjne - mimo wszystko mocno wpisane dane konfiguracyjne - jest jednak jednym wyjątkiem. Zazwyczaj dane konfiguracyjne są względnie statyczne, a alternatywą jest pisanie sporej ilości kodu w celu uniknięcia klas statycznych, które framework zapewnia dostęp do pliku web.config.
Istnieje kilka różnych sposobów korzystania z niego, które pozwolą Ci jeszcze przetestować Twoją aplikację. Jednym ze sposobów (być może w obie strony, jeśli twój singleton nie leniwie czyta app.cofnig) jest posiadanie domyślnego pliku app.config w twoim projekcie testowym jednostki, dostarczającym wartości domyślnych wymaganych dla twoich testów. Możesz użyć odbicia, aby zastąpić określone wartości w miarę potrzeb w testach jednostkowych. Zazwyczaj skonfigurowałem prywatną metodę, która pozwala usunąć prywatną instancję singleton w konfiguracji testowej, jeśli wprowadzę zmiany dla poszczególnych testów.
Innym sposobem jest nie używanie bezpośrednio singletonu, ale stworzenie dla niego interfejsu, który implementuje klasa singleton. Możesz użyć ręcznego wtrysku interfejsu, domyślnie do instancji singleton, jeśli podana wartość jest pusta. Pozwala to utworzyć fałszywą instancję, którą można przekazać do testowanej klasy dla testów, ale w swoim rzeczywistym kodzie użyj instancji singleton. Zasadniczo każda klasa, która tego potrzebuje, zachowuje prywatne odwołanie do instancji singleton i używa jej. Podoba mi się trochę lepiej, ale ponieważ singleton zostanie utworzony, nadal może być potrzebny domyślny plik app.config, chyba że wszystkie wartości są leniwie załadowane.
public class Foo
{
private IAppConfiguration Configuration { get; set; }
public Foo() : this(null) { }
public Foo(IAppConfiguration config)
{
this.Configuration = config ?? AppConfiguration.Instance;
}
public void Bar()
{
var value = this.Config.SomeMaximum;
...
}
}
możliwy duplikat [Czy istnieją realne alternatywy dla wzoru Singleton GOF?] (Http://stackoverflow.com/questions/162042/are-there-any-viable-alternatives-to-the-gof-singleton- wzór) –