.NET Core Singleton

Odpowiedz Nowy wątek
2020-06-30 10:22

Rejestracja: 5 lat temu

Ostatnio: 2 godziny temu

0

Cześć,

w moim testowym projekcie mam sobie 3 klasy:

Program.cs, którego zadaniem jest konfiguracja singletonu:

 public static IConfigurationRoot Configuration { get; set; }

        static void Main(string[] args)
        {
            Configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddCommandLine(args)
            .Build();

            var services = ConfigureServices();
            var serviceProvider = services.BuildServiceProvider();

            serviceProvider.GetService<App>().Run();
        }

        private static IServiceCollection ConfigureServices()
        {
            IServiceCollection services = new ServiceCollection();

            var config = LoadConfiguration();

            ConnectionString con = new ConnectionString();
            Configuration.Bind("ConnectionStrings", con);

            services.AddSingleton(config);
            services.AddSingleton(con);
            services.AddSingleton(Configuration);

            // required to run the application
            services.AddTransient<App>();

            return services;
        }

        public static IConfiguration LoadConfiguration()
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

            return builder.Build();
        }

App.cs, która odpowiada za komunikacje z Userem (taka główna klasa aplikacji), mam tam taki konstruktor:


public App(IConfiguration config, ConnectionString con)
        {
            conf = config;

            var args = Environment.GetCommandLineArgs();

        }

I jest sobie też klasa FileService:

    public class FileService : File, IFile
    {
        private readonly ConnectionString con;

        public FileService(ConnectionString c) => con = c;

        public void GetFiles()
        {
            using (var connection = new SqlConnection(con.GetConnectionString()))
            {
                var procedure = "raporty_pobierz_pliki";
                var values = new { KoId = 200 };
                var results = connection.Query(procedure, values, commandType: CommandType.StoredProcedure).ToList();
                results.ForEach(r => Console.WriteLine($"{r.OrderID} {r.Subtotal}"));
            }
        }

        public void Save()
        {

        }
    }

Być może źle do tego podchodzę i czegoś nie rozumiem, ale chciałbym doprowadzić do sytuacji,w której, w FileService będę miał dane z singletona, którego dodałem tutaj: services.AddSingleton(con);. W jaki sposób to osiągnąć? Czy poprawnym rozwiązaniem jest przekazanie tego w konstruktorze gdy wywołuję klasę w App.cs new FileService(con).GetFiles();?

EDIT: Moje pytanie wiąże się też z tym, że chciałbym móc mieć dostęp z dowolnego miejsca aplikacji do drugiego singletonu, który przechowuje argumenty podane podczas uruchomienia aplikacji.

edytowany 1x, ostatnio: kobi55, 2020-06-30 10:26

Pozostało 580 znaków

2020-06-30 10:40

Rejestracja: 17 lat temu

Ostatnio: 1 dzień temu

1

Coś tu namieszałeś. IConfiguration masz już za darmo dodane, więc nie dodajesz tego. Nie powinieneś też rejestrować innych swoich rzeczy.
Cała konfiguracja wczytuje Ci się automatycznie. Wystarczy, że będziesz wstrzykiwał do serwisów/kontrolerów IConfiguration. I tyle.

Pozostało 580 znaków

2020-06-30 10:47

Rejestracja: 5 lat temu

Ostatnio: 2 godziny temu

0

Dziękuję, pozbyłem się dodania IConfiguration i rzeczywiście działa.

Juhas napisał(a):

Coś tu namieszałeś. IConfiguration masz już za darmo dodane, więc nie dodajesz tego. Nie powinieneś też rejestrować innych swoich rzeczy.
Cała konfiguracja wczytuje Ci się automatycznie. Wystarczy, że będziesz wstrzykiwał do serwisów/kontrolerów IConfiguration. I tyle.

Dlaczego nie powinienem rejestrować swoich rzeczy?

edytowany 1x, ostatnio: kobi55, 2020-06-30 10:53
Wydaje mi się, że chodzi o to, że konfiguracja jest już singletonem w samym freamwork`u, dlatego nie musisz tego dodawać. Po prostu w klasie w której chcesz to użyć dodajesz sobie w konstruktorze jako IConfiguration i tyle. - Phoryn 2020-06-30 10:54
@Phoryn: no tak, tą część zrozumiałem. Chodzi mi o to dlaczego nie powinienem dodawać swoich obiektów? Przykładowo pobieram sobie z pliku konfiguracyjnego connection string i nie rozumiem dlaczego nie mogę go wrzucić jako singleton? - kobi55 2020-06-30 10:58
jeśli chcesz tak zrobić to zrób klasę, która będzie dziedziczyła interfejs w której będziesz pobierał connectionstringa i wtedy dodaj singleton w configuracji addsingleton<interfejs,klasa implementująca> Wtedy będziesz miał to co chcesz. Ale po co? Jeśli już przypiszesz raz connectionstringa to możesz go później pobierać z pliku konfiguracyjnego - Phoryn 2020-06-30 11:03

Pozostało 580 znaków

2020-06-30 11:49

Rejestracja: 17 lat temu

Ostatnio: 1 dzień temu

1

Ale już istnieje obiekt implementujący interfejs IConfiguration, który ma CAŁĄ konfigurację, razem z connection stringami (jest metoda GetConnectionString), więc po co robić coś, co już jest? Zwłaszcza, że dodajesz jakieś 3 konfiguracje. To naprawdę jest mega dziwne i nie powinno się tak tego robić. Jeśli już musisz coś mieć w jakieś swojej klasie konfiguracyjnej, to poczytaj o IOptions

Pozostało 580 znaków

2020-06-30 11:49

Rejestracja: 5 lat temu

Ostatnio: 12 godzin temu

0
Juhas napisał(a):

Cała konfiguracja wczytuje Ci się automatycznie. Wystarczy, że będziesz wstrzykiwał do serwisów/kontrolerów IConfiguration. I tyle.

Mi wstrzykiwanie IConfiguration do kontrolerów/serwisów się nie podoba.
Dlaczego nie zrobić dedykowanych klas z opcjami/konfiguracją i do serwisów/kontrolerów wstrzykiwać tylko to co rzeczywiście tam jest potrzebne

Pozostało 580 znaków

2020-06-30 11:51
Moderator

Rejestracja: 12 lat temu

Ostatnio: 1 godzina temu

Lokalizacja: Wrocław

1

A jaki jest w ogóle sens wstrzykiwania ConnectionString do globalnego rejestru serwisów? Po pierwsze i tak jest dostępny wszędzie przez IConfiguration, po drugie to jest przecież szczególik implementacji, nie element API żadnego modułu typu serwis, handler czy kontroler.


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."

Pozostało 580 znaków

2020-06-30 11:57

Rejestracja: 5 lat temu

Ostatnio: 1 minuta temu

Lokalizacja: Krakow

1
some_ONE napisał(a):
Juhas napisał(a):

Cała konfiguracja wczytuje Ci się automatycznie. Wystarczy, że będziesz wstrzykiwał do serwisów/kontrolerów IConfiguration. I tyle.

Mi wstrzykiwanie IConfiguration do kontrolerów/serwisów się nie podoba.
Dlaczego nie zrobić dedykowanych klas z opcjami/konfiguracją i do serwisów/kontrolerów wstrzykiwać tylko to co rzeczywiście tam jest potrzebne

No jest taki dedykowana klasa, IOptions<toptions>:, która ładnie działa z IConfiguration, no ale ludzie nie potrafią czytać dokumentacji

IOptions może być chociaż ja i tak wolę wstrzyknąć zwykłą klasę a nie IOptions który w większości przypadków zupełnie nic nie daje. - some_ONE 2020-06-30 19:58

Pozostało 580 znaków

2020-07-01 10:03

Rejestracja: 5 lat temu

Ostatnio: 2 godziny temu

0
somekind napisał(a):

A jaki jest w ogóle sens wstrzykiwania ConnectionString do globalnego rejestru serwisów? Po pierwsze i tak jest dostępny wszędzie przez IConfiguration, po drugie to jest przecież szczególik implementacji, nie element API żadnego modułu typu serwis, handler czy kontroler.

ConnectionString jest tylko przykładem. Równie dobrze mogły to być np. Logger. Czyli coś co ma być dostępne z każdego miejsca aplikacji.

Pozostało 580 znaków

2020-07-01 10:10
Moderator

Rejestracja: 12 lat temu

Ostatnio: 1 godzina temu

Lokalizacja: Wrocław

2

No to bardzo nietrafiony przykład, bo ConnectionString to jest coś, co nie powinno być dostępne z każdego miejsca aplikacji.


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."

Pozostało 580 znaków

2020-07-01 14:17

Rejestracja: 5 lat temu

Ostatnio: 2 godziny temu

0
somekind napisał(a):

No to bardzo nietrafiony przykład, bo ConnectionString to jest coś, co nie powinno być dostępne z każdego miejsca aplikacji.

W sumie masz racje, nie trafiłem z tym ConnectionStringiem ;)

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0