2016-08-17 47 views
11

Więc powiedzmy, że mam singleton klasy instancji, że zarejestrować się w DI tak:ASP.NET Rdzeń zainicjować singleton po skonfigurowaniu DI

services.AddSingleton<IFoo, Foo>(); 

I powiedzmy klasa Foo posiada szereg innych uzależnień (głównie klasy repozytoriów, które pozwalają na ładowanie danych).

Zgodnie z moim obecnym zrozumieniem instancja Foo nie jest tworzona, dopóki nie zostanie po raz pierwszy użyta (pytanie). Czy istnieje sposób inicjalizacji tej klasy innej niż konstruktor? Czy po zakończeniu pracy zakończy się ConfigureServices()? A może kod inicjalizacyjny (ładowanie danych z db) powinien być wykonany w konstruktorze Foo?

(Byłoby miło, gdyby ta klasa może załadować swoje dane przed pierwszym użyciem, aby przyspieszyć pierwszy czas dostępu)

+0

Możesz stworzyć "nowy Foo() 'i zarejestruj go w metodzie' ConfigureServices'. –

Odpowiedz

14

Zrób to sam podczas uruchamiania.

var foo = new Foo(); 
services.AddSingleton<IFoo>(foo); 

Albo „podgrzać”

public void Configure(IApplicationBuilder app) 
{ 
    app.ApplicationServices.GetService<IFoo>(); 
} 

lub alternatywnie

public void Configure(IApplicationBuilder app, IFoo foo) 
{ 
    ... 
} 

Ale to czuje się brudna i jest bardziej problem z projektu, jeśli robisz coś, co powinnam w konstruktorze. Inicjacja klasy musi być szybka, a jeśli wykonasz w niej długotrwałe operacje, musisz złamać kilka dobrych praktyk i musisz dokonać refaktoryzacji bazy kodu, zamiast szukać sposobów na hackowanie.

+3

Ale wtedy musiałbym martwić się o wszystkie zależności Foo (wszystkie repozytoria i ich zależności). Zdecydowanie wykonalne, ale szukające sposobu, który nie zwalcza systemu. – pbz

+0

Tak. Zwykle inicjujesz tylko te klasy, które wymagają specjalnego traktowania, jak na przykład uruchamianie połączenia magistrali usług itp., Którego nie chcesz wykonywać podczas uruchamiania systemu. Potrzebujemy więcej informacji, ale co dokładnie wypróbujesz. Podejrzewam, że wykonujesz długo działającą operację w konstruktorze, co jest absolutnie niemożliwe. Inicjowanie klasy powinno być szybką i długotrwałą operacją NIGDY nie wykonaną w konstruktorze. Oczywiście możesz także raz rozwiązać klasę w 'Configure', ale to wydaje się być" brudne ". – Tseng

+0

Tak, względnie długo działa, ponieważ przechodzi do bazy danych w celu pobrania danych (około 50 ms dla wielu zapytań). Ponieważ jest to singleton, można argumentować, że nie ma znaczenia, gdzie jest inicjowany. Myślę, że jest to najlepsza opcja do tej pory (przy okazji błędnie skonfigurowałeś Configure()) Po prostu próbowałem i działa, aby dodać IFoo do listy parametrów dla Configure(), więc w ten sposób nie muszę wywoływać GetService <>(). Dziękujemy: – pbz