Co tu będziemy budować
Witaj w pierwszym odcinku serii, w której nie uczymy się .NET-a na przykładach z kosmosu, tylko budujemy coś, co faktycznie rozwiązuje problem biznesowy. Wyobraź sobie marketplace z ogłoszeniami firm fotowoltaicznych — prawdziwa strona na WordPressie, zwykli użytkownicy, zwykłe wyszukiwanie. Problem: baza 55 tysięcy firm, które trzeba tam wrzucić. Ręcznie? Dwie minuty na ogłoszenie to tygodnie klikania w panel administracyjny. Nikt przy zdrowych zmysłach się tego nie podejmie.
Więc robimy to inaczej — piszemy aplikację konsolową w .NET 6, która zaciąga firmy z bazy danych, wzbogaca je o dane z Google Places API (telefon, godziny otwarcia, współrzędne do mapy, opinie), po czym wystrzela gotowe ogłoszenia do WordPressa przez REST API. Na dokładkę zrobimy bota w Selenium, który zaloguje się na stronę jako użytkownik i doda opinie z gwiazdkami — bo akurat tego WordPress API nie obsługuje w sensowny sposób.
To nie jest kolejny kurs, w którym robimy listę todo albo kalkulator. Lecimy na prawdziwym projekcie, z prawdziwymi problemami i prawdziwym deploymentem do działającej strony.
Jeżeli jesteś po podstawach C# i chcesz zobaczyć, jak to wygląda w praktyce — usiądź wygodnie, bo ta seria będzie konkretna.
Stos technologiczny
Zanim przejdziemy do planu, zobacz z czym będziesz pracować. Żadnych egzotycznych wyborów — wszystko to narzędzia, na które natkniesz się w komercyjnych projektach .NET-owych.
- .NET 6 / C# 10 — najnowsze LTS w momencie startu serii, top-level statements, minimal hosting, cała reszta nowinek.
- Aplikacja konsolowa — celowo bez ASP.NET Core, bo chcę pokazać, że hosting generyczny (
IHostBuilder) działa wszędzie, nie tylko w webówce. - Entity Framework Core — do bazy MySQL, z której wyciągamy firmy. Database-first albo code-first — zobaczysz w odcinku drugim.
- Dependency Injection — wbudowany kontener z
Microsoft.Extensions.DependencyInjection. Cały projekt pójdzie w konwencji serwisów rejestrowanych przez DI, bez żadnych statyków i new-ów w losowych miejscach. - IOptions + appsettings.json — żeby klucze do API, connection stringi i ustawienia nie wisiały jako stringi w kodzie.
- HttpClient + IHttpClientFactory — do Google Places API i WordPress REST API. Pokażę, dlaczego
new HttpClient()to pułapka. - Selenium WebDriver — bot, który klika w przeglądarce. Sam nigdy wcześniej tego nie używałem, więc uczymy się razem z dokumentacji.
- WordPress REST API — endpoint
/wp-json/wp/v2/postsplus autoryzacja tokenem Bearer. - Google Places API — Place Details, Find Place, Nearby Search.
Stack jest celowo "zwyczajny". Jak zrobisz tę aplikację, to w pracy przy enterprise'owych systemach nie zobaczysz nic fundamentalnie innego — będą to te same cegiełki, tylko w innym układzie.
Plan na 15 odcinków
Seria jest długa i otwarta — dochodzą nowe rzeczy, jak natrafiamy na ścianę. Ale szkielet wygląda tak:
| # | Odcinek | Tematy techniczne |
|---|---|---|
| 0 | Opis projektu i rozkład jazdy | Architektura, plan działania |
| 1 | Konfiguracja Entity Framework | EF Core, migracje, MySQL |
| 2 | Dependency Injection w konsolówce | IServiceCollection, IHost, lifetime'y |
| 3 | Generowanie klucza Google Places API | Google Cloud Console, billing, restrykcje |
| 4 | Options i appsettings.json | IOptions<T>, konfiguracja środowisk |
| 5 | Integracja z Google Places API | HttpClient, DTO, deserializacja JSON |
| 6 | Przegląd API WordPressa | Endpointy, struktura REST |
| 7 | Pobieranie Bearer Tokena z WP | Auth, JWT, refresh flow |
| 8 | Dodawanie postów przez WP API | POST /wp-json, custom fields, kategorie |
| 9 | Selenium — konfiguracja bota | WebDriver, ChromeDriver, selektory |
| 10 | Spinanie wszystkiego w całość | Orkiestracja modułów, end-to-end test |
| 11 | Zaawansowane operacje z Google API | Paging, rate limiting, cache |
| 12 | Zaawansowane integracje z WordPressem | Media upload, taksonomie, metadane |
| 13 | Zaawansowane operacje na bazie | Transakcje, bulk insert, performance |
| 14 | Obsługa błędów z try/catch | Strategie retry, Polly, logowanie |
Celowo nie rozpisuję każdego odcinka na sztywno w excelu. W realnej pracy programisty i tak wylądujesz w sytuacji, której nie przewidział nikt z architektów. Lepiej nauczyć się reagować niż przewidywać.
Każdy z tych odcinków to osobny film na YouTubie, ale też osobny commit (albo gałąź) w repo, więc możesz iść razem ze mną krok po kroku, wgrywając kod w swoim tempie.
Dlaczego bot Selenium, skoro jest REST API
Ten fragment wymaga osobnego akapitu, bo ludzie pytają za każdym razem. WordPress REST API bez problemu doda ci post z ogłoszeniem — POST /wp-json/wp/v2/posts i jedziesz. Ale kiedy chcesz dodać opinię z oceną w gwiazdkach i dodatkowymi kategoriami (kontakt, cena, jakość wykonania, terminowość), okazuje się, że używana przez marketplace wtyczka nie wystawia tej części przez API. Gwiazdki trzeba kliknąć w UI.
Mamy dwie opcje: reverse-engineerować wtyczkę (tydzień pracy) albo napisać bota, który udaje zalogowanego użytkownika (dwa dni). Wybieramy bota, bo:
- Jest okazja, żeby nauczyć się Selenium w C# — umiejętność przydatna przy pisaniu testów E2E.
- Jest szybciej.
- Dostajesz bonus: prosty algorytm opiniowania, który z jednej oceny Google (np. 4.7) rozbija wynik na cztery kategorie. To ciekawy, mały problem algorytmiczny.
W pracy programisty bardzo często "głupsze" rozwiązanie wygrywa z "eleganckim", bo dowozi wartość biznesową szybciej. Ten bot to dokładnie taki przypadek.
Co dalej?
W następnym odcinku bierzemy się za Entity Framework Core — konfigurujemy DbContext, podpinamy się do MySQL-a i wyciągamy pierwsze rekordy firm. Od tej pory każdy odcinek zamyka się konkretnym kawałkiem działającego kodu, który commitujesz razem ze mną.
Jeżeli chcesz iść razem ze mną kod w kod, całość jest otwarta na GitHubie: github.com/jarmatys/dotnet-wordpress-importer. Forkuj, klonuj, eksperymentuj.
Masz pytania do architektury albo konkretnego etapu, który chciałbyś rozwinąć szerzej (np. sam Google API albo sam Selenium)? Pisz w komentarzach pod filmem — seria jest otwarta i spokojnie mogę wrzucić dodatkowe odcinki, jeśli zobaczę, że jakiś temat wali wam w oczy. To ma być tutorial o praktyce, a nie mój monolog.
Do zobaczenia w odcinku pierwszym. Trzymaj się.



