Żółwie tempo rozszerzania się rtęci

Jako że udało mi się już napisać solidny kęs kodu, postanowiłem wreszcie opublikować projekt na CodePlex i stworzyć lokalne repozytorium. Ale zanim o tym…

Struktura projektu
Nie wspomniałem jeszcze ani słowem o strukturze utworzonej w Visual Studio solucji. Teraz, kiedy jest już ona publcznie dostępna, wypadałoby objaśnić zastosowany podział na projekty. Prezentuje się on tak:

solution

W projekcie InvoiceInvoker.Logic umieściłem bazę danych i repozytoria odpowiedzialne za dostęp do nich, a także logikę biznesową. Właściwie powinienem przeznaczyć na te warstwy dwa projekty – jeśli któraś z nich rozrośnie się ponad spodziewane rozmiary, zapewne tak uczynię. Natomiast projekt InvoiceInvoker.Logic.Tests zawiera testy jednostkowe, pisane pod NUnit. W niedalekiej przyszłości do już istniejącego duetu dołączy projekt odpowiedzialny za interakcję z użytkownikiem.

TortoiseHg
Zrelacjonuję teraz pokrótce pionierską wyprawę plików projektu do repozytorium (w systemie Mercurial) utworzonego automatycznie przez CodePlex. Zacząć należało od stworzenia repozytorium lokalnego. Pomógł mi w tym prosty tutorial. Nie obeszło się jednak bez problemów.
Początkowo w głównym katalogu projektu utworzyłem podkatalog Repository i to do niego sklonowałem repozytorium z CodePlex. Po chwili zorientowałem się, że jednak nie o to chodzi – aby Żółw zuważył swym leniwym okiem moje pliki, musiałem je kopiować do utworzonego katalogu. Sklonowałem więc repozytorium do głównego katalogu – IvoiceInvoker. Stworzył się w nim podkatalog invoiceinvoker i dopiero tam repozytorium. Miałem więc sytuację analogiczną do tej z podkatalogiem Repository. Po chwili konsternacji wpadłem na rozwiązanie: przeniosłem całą zawartość głównego katalogu w inne miejsce i sklonowałem repozytorium z CodePlex do pustego już InvoiceInvoker – tym razem się udało (wniosek: jeśli TortoiseHg klonuje repozytorium do niepustego katalogu, to tworzy w nim podkatalog – i tam repozytorium). Pozostało tylko przerzucić z powrotem pliki projektu do katalogu głównego i zabrać się za pierwszy commit.
(W tym miejscu wyrażam ubolewanie nad brakiem synonimów słów: katalog, repozytorium. Konsekwencją tego braku jest, co czytelnik z pewnością zauważył, nachalne występowanie wymienionych słów w każdym zdaniu powyższego akapitu…)

Mercurial
Popełniając pierwszy commit, byłem chyba zbyt przepełniony euforią wywołaną przez pomyślne utworzenie lokalnego repozytorium – na CodePlex’owe repo wysłałem wszystkie pliki projektu, włącznie ze skompilowanym kodem. Kiedy (już po raz drugi) zorientowałem się, że to nie o to chodzi, zacząłem szukać sposobu na usunięcie niepotrzebnych plików z commita. Większość tutoriali w sieci pokazuje tylko taką sekwencję: add -> commit -> push. Po jakimś czasie poszukiwań i badań metodą prób i błędów, doszedłem do, jakże banalnego, rozwiązania. Wystarczyło zauważyć przycisk Forget – i użyć go po zaznaczeniu niepotrzebnych plików.
Oprócz katalogów zawierających projekty, wrzuciłem także katalog libraries – znajdować się w nim będą wykorzystywane w projekcie biblioteki zewnętrzne (na razie tylko nunit.framework). Z kolei plik InvoiceInvoker.config zawiera ścieżkę do bazy danych znajdującej się w katalogu InvoiceInvoker.Logic. Ze ścieżki tej korzysta NUnit przeprowadzając testy jednostkowe, dlatego chętni do testowania – ponieważ ścieżka jest bezwzględna – powinni ją odpowiednio edytować.

Takim to sposobem utworzyłem i okiełznałem swoje pierwsze repozytorium. Zajęło mi to kilka godzin, co jest niewątpliwie żółwim tempem, jednak teraz moja rtęć będzie się rozszerzać coraz sprawniej i szybciej.

Solution: making of

Skoro etap formułowania, studiowania i interpretowania wymagań mam już za sobą, czas przejść do etapu kolejnego: projektowania aplikacji. Niechże składa się ono z takich oto kroków:
1. projektowanie solucji,
2. projektowanie bazy danych,
3. projektowanie warstwy logiki biznesowej,
4. projektowanie warstwy interfejsu użytkownika.

Zaprojektować by się można na amen, dlatego pomiędzy powyższymi punktami odbywać się będzie kodowanie zaprojektowanych modułów.

Ale do rzeczy. Punkt pierwszy rzecze: projektowanie solucji. W tym kroku pomocne będzie zerknięcie na pozostałe punkty – widać, że logika jest wyraźnie oddzielona od interfejsu użytkownika. Aby podkreślić ten podział, elementy te zostaną umieszczone w osobnych projektach: DigitalWallet.Logic i DigitalWallet.UI. Nie wspomniałem jeszcze o testach jednostkowych logiki biznesowej – one też zasługują na osobny projekt. Do już wspomnianej dwójki dodaję więc DigitalWallet.Logic.Tests. Utworzone mam zatem trzy projekty w jednej solucji, to bring them all and in Solution Explorer bind them