niedziela, 26 marca 2017

Clean Code, dlaczego to takie ważne?


Pewnie nie raz słyszeliście, że istotne jest, by zachować dobre praktyki i wzorce projektowe. Dlaczego jednak jest aż tak ważne, po co „marnować” dodatkowo czas po to, by stosować się do tych reguł?

Zdobywałem doświadczenie przy bardzo dużym projekcie, który jest rozwijany już lata i z tego co wiem, wciąż się trzyma i nadal się rozrasta. Dzięki temu, że właśnie tam stawiałem swoje pierwsze kroki jako programista, mogłem od razu uczyć się programowania na całkiem dobrze napisanym projekcie. Zanim jednak opowiem o tym dlaczego „Clean Code” miał znaczenie tam, zacznę od spraw ogólnych.

Każda branża specjalistów ma specyficzny dla siebie język, którego używa, by opisać swoją pracę bądź napotykane problemy. Weźmy na przykład  budowanie domu. Dom składa się z wielu elementów instalacji i elementów, które trzeba stworzyć, by ktoś mógł w nim zamieszkać i by sprostał oczekiwaniom właścicieli. W budynku możemy wyznaczyć różne komponenty, jednak większość z nich zbudowana jest na bazie już funkcjonujących schematów, bo wymyślanie wszystkiego od podstaw jest znacznie droższe. Istnieją gotowe rozwiązania problemów, które budowniczy mogą napotkać, schematy są sformułowane w taki sposób, że nawet gdy inny specjalista spojrzy na to, co zrobił jego poprzednik, będzie potrafił dość szybko się odnaleźć w danej konstrukcji. Są jednak ludzie, którzy wykonują swoją pracę niechlujnie i niedbale. Tworzą elementy domu „na skróty”, chcąc w teorii zaoszczędzić. Np. elektryk kładący instalację elektryczną, podpiął pod jeden bezpiecznik zbyt dużo kabli lub (lekka skrajność, aczkolwiek sam widziałem tego typu „oszczędność”) przewody po ścianach nie były kładzione pod kątem prostym tak jak każdy inny elektryk by się spodziewał, tylko tak, by zużyć jak najmniej kabla… Brzmi absurdalnie prawa?
Odnieśmy to teraz do naszej branży. Gdy stosujemy się do dobrych praktyk, to tak, jakbyśmy pisali kod zgodnie ze znanymi schematami. Jeżeli możemy, korzystajmy z gotowych rozwiązań problemów nazwanych wzorcami projektowymi. Dzięki temu, gdy ktoś inny spojrzy na to rozwiązanie, zobaczy, że został użyty wzorzec fabryki i od razu będzie wiedział czego może oczekiwać. A jeśli nie wie co to właściwie jest ta fabryka, bardzo łatwo może znaleźć opis wzorca w sieci. Pisząc kod nietypowy, w którym trzeba tworzyć wszystko od zera i idąc na skróty sprawiamy, że całego modułu robiącego daną rzecz będzie nam bardzo trudno ponownie użyć w innym miejscu. Gdyby cały kod został napisany zgodnie z dobrymi praktykami, łatwo moglibyśmy wydzielić go z aplikacji i re-użyć gdzie indziej. Złudna korzyść w postaci zaoszczędzenia czasu na początku, okazuje się dwukrotnie bardziej czasochłonna podczas późniejszego pisania. Kod, który jest pisany na szybko i niechlujnie, bywa też niezrozumiały dla kogoś innego, a przecież przeważnie nad projektem pracuje cały zespół. Tak jak żaden elektryk nie spodziewa się, że kable mogą iść pod różnymi kątami, tak programiści nie spodziewają się, że zmiana logiki „dziwnego kodu” spowoduje wybuch w innej części aplikacji. A to bardzo częste w podejrzanej czystości kodzie. Dobrze napisany kod ma jeszcze jedną, bardzo ważną zaletę. Jest łatwy w testowaniu. Możemy wydzielić moduły z kodu i testować je w izolacji. Możemy też spiąć je w jeden komponent i sprawdzić jak one działają razem. Nazywamy to testami jednostkowymi i integracyjnymi.


Projekt, o którym pisałem na początku nie jest oczywiście ideałem. Miał bardzo wiele swoich problemów i nie wszystkie jego części były dobrze napisane. Jednak jego podstawy i fundamenty były naprawdę solidne. Dzięki zastosowaniu wzorców projektowych i pisaniu „czystego kodu” projekt był rozwijany przez lata bez większych problemów. Te konkretne podstawy umożliwiły ciągły rozwój aplikacji przez lata. Na temat dobrych praktyk programowania można napisać znacznie więcej (polecam książkę „Clean Code” Roberta Martina), jednak cel mojego postu to bardziej zainteresowanie tematem niż szczegółowe opisanie problemu. A Ty jakie masz doświadczenie jeśli chodzi o czysty kod i dobre praktyki? 

Progres Prac

Progres Prac

Jako, że ostatnio brakuje mi nieco czasu, to post będzie jedynie o postępach prac nad projektem i planach na najbliższy czas.

Większość czasu spędzam nad stylowaniem i budowaniem kolejnych komponentów aplikacji. Tu np. prototyp takiej „karty postu” do bloga.




Powstała także już strona „O mnie”



Sporo czasu zajęło mi także poszukanie w sieci portali z zdjęciami, które będę mógł legalnie użyć na blogu. Obecnie w produkcji jest widok posta oraz modułów mu towarzyszących. Kolejnym elementem będzie sprawienie, by strona była bardziej „SEO friendly”. Po tym wszystkim będę mógł już dostosować homepage, puścić wszystko na „produkcję” i tym samym ustawić nową platformę dla mojego bloga. Oczywiście będzie jeszcze sporo rzeczy do zrobienia. Jednak będzie już na tyle dobrze, że obecny blog będzie wyglądał dużo lepiej niż obecnie. Stąd też decyzja o dość szybkim przeniesieniu.


Do zobaczenia wkrótce! 

sobota, 18 marca 2017

Sass, Bootstrap i Font Awesome

Frontend ciąg dalszy

W ostatnim poście na temat Frontendu opisałem używany przeze mnie kompilator do stylów i skryptów. Dziś opiszę nieco szerzej strukturę i użyte frameworki do stylów.


Zastanawiałem się na kilkoma różnymi gotowymi komponentami do frontendu. Ostatecznie wyłoniłem dwóch finalistów: Bootstrap oraz  Semantic UI. Semantic jest znacznie bardziej rozbudowany i zawiera dużo więcej gotowych modułów.  Wiąże się to jednak z tym, że „waży” znacznie więcej niż bootstrap. Oba frameworki mają to, na czym zależało mi najbardziej. Jest to grid do budowy strony oraz podstawowo zdefiniowane najbardziej potrzebne rzeczy jak buttony, checkbox-y, radio buttony itp. Finalnie wygrał Bootstrap, ponieważ jest lżejszy od semantic oraz jest gotowa wersja Sass bootstrapa (Semantic-UI jest w Less-ie, tak wiem, że można znaleźć wersję Sass zrobioną przez kogoś innego, ale chodzi mi o to, co Framework ma w standardzie). Nie zależało mi na tym by wszystko wyglądało pięknie już w samym frameworku, bo nadpisuję wygląd tak, by była to bardziej „moja” strona. Nie chciałbym też, by po wejściu na bloga było znajome uczucie „ale chamski bootstrap”.
Linki do obu frameworków:

Modyfikacja Bootstrapa

Dzięki temu, że bootstrap można ściągnąć w Sass-ie, mam możliwość modyfikacji poprzez nadpisywanie zmiennych, które później są używane w stylach (jeśli nie wiesz co to zmienne i jak pisze się style w Sass-ie, post na ten temat będzie w przyszłości J).

//== Colors
//
//## Gray and brand colors for use across Bootstrap.

$gray-base:              #000 !default;
$gray-darker:            lighten($gray-base, 13.5%) !default; // #222
$gray-dark:              lighten($gray-base, 20%) !default;   // #333
$gray:                   lighten($gray-base, 33.5%) !default; // #555
$gray-light:             lighten($gray-base, 46.7%) !default; // #777
$gray-lighter:           lighten($gray-base, 93.5%) !default; // #eee

$brand-primary:         darken(#428bca, 6.5%) !default; // #337ab7
$brand-success:         #5cb85c !default;
$brand-info:            #5bc0de !default;
$brand-warning:         #f0ad4e !default;
$brand-danger:          #d9534f !default;

Dzięki temu, w bardzo prosty sposób pozbyłem się standardowo zaokrąglonych krawędzi w komponentach bootstrapa oraz gradienty w guzikach (obie z tych rzeczy nie wyglądają dla mnie zbyt atrakcyjnie) w kilku liniach kodu. Dodatkowo, stworzyłem kilka własnych plików, które implementują nowe style lub nadpisują istniejące. Dzięki temu, tworzę stronę, która wygląda tak jak chcę, a zarazem mam dobrą bazę, która rozwiązuje za mnie wiele problemów.    


Kolejnym istotnym komponentem mojego projektu jest otwarta biblioteka z ikonami Font Awesome. Ikon jest mnóstwo i bardzo łatwo się ich używa. Wystarczy jedynie dodać odpowiednią klasę, której nazwę możemy otrzymać po kliknięciu na interesującą nas ikonę.



Po dodaniu plików font awesome do naszego projektu, wszystkie te ikony stają się dla nas dostępne.
Link do Font Awesome: http://fontawesome.io/

Konfiguracja w Gulpie:

Aby wszystko wyżej opisane zadziałało, stworzyłem cztery taski w gulpie. Dwa z nich są odpowiedzialne za skopiowanie fontów z moich folderów z kodem roboczym do docelowego.
gulp.task('fonts',['fonts-bootsrap'], function () {
    return gulp
        .src(fonts.in)
        .pipe(gulp.dest(fonts.out));
});
gulp.task('fonts-bootsrap', function () {
    return gulp
        .src(fonts.inBootstrap)
        .pipe(gulp.dest(fonts.out + 'bootstrap/'));
});
Task z fontami bootstrapowymi zostanie prawdopodobnie wyrzucony z finalnej wersji. Jest tam, ponieważ bootstrap bazuje na ikonach w nich zawartych i rzuca mi błędy do konsoli, a nie lubię tam czerwonych barw J.  Więc gdy tylko pozbędę się zależności w bootstrapie, wyrzucę taska i fonty z projektu.

Pozostałe dwa taski dotyczą kompilacji Sass-ów do plików css.
gulp.task('sass', function () {
    return gulp.src(scss.in)
        .pipe(sass(scss.sassOpts))
        .pipe(gulp.dest(scss.out));
});

gulp.task('sassprod', function () {
    return gulp.src(scss.in)
        .pipe(sass(scss.sassOpts))
        .pipe(cssnano())
        .pipe(gulp.dest(scss.out));
});
Różnią się od siebie tylko jedną rzeczą: style produkcyjne są dodatkowo minifikowane. Task Sass jest używany, gdy kompiluję frontend na potrzeby developmnetu, dla łatwiejszej nawigacji w stylach i debugowaniu problemów. Sassprod natomiast wykorzystywany jest, gdy kompiluję style, które mają pójść na „produkcję”.

Tak wygląda organizacja stylów w moim projekcie. Jak do tej pory, pisze się mi go bardzo przyjemnie, choć nie mam zbyt wiele czasu. Zachęcam do komentarzy i sprawdzenia źródeł na GitHubie. Polecam również frameworki, które dziś opisałem, choć są na tyle znane, że pewnie nie muszę tego robić.

Do następnego razu J

czwartek, 16 marca 2017

IoC contener i Umbraco

IoC contener i Umbraco

Bardzo lubię concept Inversion of Controll oraz Dependency Inversion. Ucieszyłem się na wieść, że IoC Contener będzie dostępny w Umboraco 8 “out of the box”, gdyż twórcy stwierdzili, że społeczność jest już na tyle dojarzała, że udźwignie nieco bardziej zaawansowane tworzenie obiektów. ;)

Niestety w wersji 7 Umbraco jeszcze nie mamy IoC Contenera, ale możemy temu zaradzić instalując samemu któryś z kontenerów. Lubię korzystać z StructureMap-a i to właśnie na niego padł mój wybór. Już nie pamiętam dokładnie skąd wziąłem przykład implementacji, ale np. tu jest dostępny opis, jak to zrobić:


Jest też nowa wersja tej biblioteki, która jest przystosowana do wersji 4 StructureMap-a i tej właśnie używam w swoim projekcie.

Dzięki temu, możemy korzystać z odwrócenia zależności (jednej z zasad SOLID-nego programowania) w prosty sposób. Ja używam StructureMapa do wstrzykiwania zależności w konstruktor klas. Można również za jego pomocą wstrzykiwać właściwości klas, ale ja nie jestem fanem tego rozwiązania. Moim zdaniem kod jest bardziej czytelny przy wstrzykiwaniu do konstruktorów.

Co zyskujemy używając „Dependency Inversion” w naszym kodzie za pomocą StructureMap-a? Postaram się to pokazać na podstawie mojego projektu J
W swoim kodzie mam coś takiego jak Buildery do sekcji na stronie. Żeby mieć spójną koncepcję jak wygląda Builder, wydzieliłem abstrakcję do Interfejsu, który każdy Builder musi implementować:

    public interface ISectionBuilder
    {
        string ViewName { get; }
        BaseViewModel CreateViewModel(IPublishedContent content);
        bool DeosApply(string documentAlias);
    }

 ViewName to Nazwa widoku (pliku cshtml) znajdującego się w folderze „Partials”, który ma zostać użyty do zbudowania sekcji.
Metoda DoesApply dostaje w parametrze alias noda aktualnie renderowanego i ma zwrócić czy ten builder się nada, czy też nie.
Ostatnia metoda jest odpowiedzialna za zbudowanie ViewModelu. Bardzo zależało mi na tym, by pozostawić ViewModele w postaci jak najczystszej (docelowo klasa z tylko i wyłącznie  właściwościami)

Dzięki StructureMap mogę zarejestrować wszystkie Buildery w registry:

     For().Use();
     For().Use();
     For().Use();
     For().Use();
     For().Use();
     For().Use();

W następnej kolejności stworzyłem klasę BuildersFactory, która w konstruktorze ma wstrzykiwaną listę interfejsów ISectionBuilder. Pod spodem IoC sprawdzi co zostało zarejestrowane jako implementacja ISectionBuilder i da mi wszystkie te klasy w liście. Dzięki temu, podczas renderowania danej sekcji Fabryka odpala metody DoesApply dla każdego buildera i daje wszystkie te, które potrafią obsłużyć dany node lub pierwszy Builder który się nada (w zależności od wywołanej metody). Sam Builder także posiada swój interfejs, który jest zarejestrowany podobnie jak SectionBuildery.

Jak do tej pory stworzyłem jeden kontroler, który będzie obsługiwał standardowe strony z Umbraco. Każdy Node typu Page będzie renderowany przez ten kontroler:

    public class PageController : RenderMvcController
    {
        private readonly IPageModelExtender _pageModelExtender;
        private readonly ISectionsProvider _sectionsProvider;

        public PageController(ISectionsProvider sectionsProvider, IPageModelExtender pageModelExtender)
        {
            _pageModelExtender = pageModelExtender;
            _sectionsProvider = sectionsProvider;
        }

        public override ActionResult Index(RenderModel model)
        {
            var allSections = model.Content.Children.ToList();
            var listOfSectionsToRender = _sectionsProvider.GetListOfSectionsToRender(allSections);
            var pageViewModel = new PageViewModel {Sections = listOfSectionsToRender};
            return View("Page", _pageModelExtender.ApplyLayoutToModel(pageViewModel, model.Content));
        }
    }

Zasada działania jest dość prosta. Podczas renderowania danego „Page-a”, brane są wszystkie jego dzieci (Nody będące piętro niżej w drzewku). Każde dziecko jest renderowane przez SectionBuilder, który potrafi obsłużyć dany alias. Na samym końcu, gdy mamy już listę ViewModeli oraz nazw widoków, by wyrenderować wewnątrz strony wszystkie sekcje, dokładane są header oraz footer wraz z ewentualnymi zmianami w meta tagach, gdy jest taka potrzeba.

Jak widać sama zasada działania jest prosta, czyli taka jak najbardziej lubię ;) Kolejnym dużym plusem stosowania IoC Contenera i wstrzykiwania zależności są znaczące ułatwienia przy testach jednostkowych. Dzięki takim bibliotekom jak Moq, możemy tworzyć „mocki” obiektów czyli takie wydmuszki, które mają np. zahardkodowaną wartość zwracaną z metod wstrzykniętych klas niezależnie od logiki w ciele tej metody. Dzięki temu możemy wyizolować testy, testować tylko i wyłącznie logikę danej klasy, nie przejmując się że coś pójdzie nie tak w jednej z klas używanej przez testowaną. Pewnie kiedyś szerzej opiszę koncepcję testów jednostkowych wykorzystujących zasadę odwróconej zależności w kodzie.

Uff… Jak do tej pory mój najdłuższy post, ale chciałem wyjaśnić sposób mojej implementacji J Blog nie jest na bieżąco z tym co aktualnie się dzieje w projekcie, jest trochę do tyłu. Obecnie nadal pracuję nad frontendem i rozbudową kolejnych bazowych sekcji w stronie. Mały screen na potwierdzenie, że coś się dzieje:



I to już wszystko na dziś, do następnego razu J

piątek, 10 marca 2017

Gulp

Miało być o IoC I Faktorce budującej sekcje, jednak właśnie skończyłem pracę nad “kompilatorem” do frontendu i to właśnie o Gulpie będzie dzisiejszy post.

Wspominałem wcześniej, że chcę budować frontend aplikacji poprzez jakiś kompilator. Po zrobieniu researchu stwierdziłem, że Gulp będzie dobrym wyborem. Czym zatem jest Gulp? Można powiedzieć, że jest to task runner. Idea jest prosta, tworzysz sobie task, podajesz pliki źródłowe. Podłączasz do taska pluginy, które zrobią coś z Twoimi wejściowymi plikami. Każdy z nich zostanie wywołany w kolejności, w której został dodany. Na końcu podajemy plik wyjściowy, w którym otrzymamy efekt działania pluginów na plikach wejściowych. Tylko tyle i aż tyle. Gulp ma bardzo rozbudowaną bazę pluginów. Do bardzo wielu różnych zastosowań.

Obecna ich lista znajduje się tu: http://gulpjs.com/plugins/

W moim przypadku, wykorzystuję Gulpa do:

  • Skompilowania stylów, które są w Sass-ie do css i jeśli jest to produkcyjny build także minifikację.  
  • Skompilowania skryptów które będą w ES6 na JavaScript, który rozumieją obecne przeglądarki za pomocą babela, w devowym buildzie dodanie source mapy dla ułatwienia debuggowania, a na produkcyjny minifikację.
  • Skopiowanie fontów do folderu z assetami (korzystam z font awesome) 


Przykładowy Task w Gulpie:

    gulp.task('sassprod', ['fonts'], function () {
    return gulp.src(scss.in) //pliki wejsciowe
        .pipe(sass(scss.sassOpts))  //skompiluj sassy
        .pipe(cssnano()) //minifikuj 
        .pipe(gulp.dest(scss.out)); //wyjsciowy plik
});

Jak widać, samo zrozumienie i używanie Gulpa jest proste. Zwłaszcza, jeśli ktoś ma jakieś doświadczenie np. w używaniu Power Shella lub Basha, w którym w podobny sposób możemy działać na plikach/obiektach. Problematyczne (przynajmniej dla mnie) jest jednak znalezienie wśród tych wszystkich pluginów te, które są potrzebne w projekcie. Spędziłem sporo czasu skanując sieć w poszukiwaniu różnych przykładów użycia Gulpa, aby znaleźć te pluginy, które mi się przydadzą. Czy znasz może jakieś ciekawe pluginy, które powinienem przetestować? Jeśli tak, podziel się tym w komentarzach, chętnie zerknę :).

Linki do stronek wyjaśniających jak działa Gulp i przykładowe użycia z których między innymi czerpałem wiedzę:

1. Rodzime podwórko


2. Po angielsku


To tyle na dziś, ja tymczasem wracam do rozwoju projektu, do następnego razu! :)

poniedziałek, 6 marca 2017

Dlaczego Umbraco?

Dziś post nieco bardziej techniczny. Wyjaśnię pokrótce wybór Umbraco oraz mojej modyfikacji.

Dlaczego Umbraco?

Od jakiegoś czasu mam przyjemność pracować z tym cms-em w biurze. Jest jednak kilka rzeczy, które zawsze chciałem zrobić nieco inaczej, z wykorzystaniem innych technik. Stąd zrodził się pomysł, by stworzyć bloga w oparciu o tą platformę. Mogę przetestować moje pomysły w praktyce. W Umbraco bardzo łatwo zarządza się zawartością strony z poziomu „Back Office”, a także pod względem implementacji, ten CMS pozostawia bardzo wiele swobody.  Nie chciałem wykorzystywać jakiegoś wielkiego kombajnu, który ma już wszystko, tylko stworzyć system „szyty na miarę”. Umbraco sprawdza się w tej kwestii bardzo dobrze.

Niestety Umbraco „out of the box” nie wspiera silnie typowanych widoków, więc jeśli lubimy porządek w kodzie i widoki pozbawione logiki biznesowej to trzeba coś z tym zrobić. Jest kilka różnych sposobów na to, by mieć silnie typowane widoki w umbraco. Moje rozwiązanie tego problemu jest następujące.

Każdy Document Type, może mieć przypisany Template, który będzie renderował widok. Najprościej jest stworzyć Template (w moim przypadku „Page”) i przypisać do określonej grupy Document typów.
Umbraco Template


Teraz wystarczy stworzyć Controller który dziedziczy po RenderMvcController i nazwać go [NazwaTemplatu]Contrller. Nadpisać należy metodę Index i za każdym razem gdy ten DocumentType będzie renderowany, Metoda Index będzie wywoływana.

    public class PageController : RenderMvcController
    {
        private readonly IPageModelExtender _pageModelExtender;
        private readonly ISectionsProvider _sectionsProvider;

        public PageController(ISectionsProvider sectionsProvider, IPageModelExtender pageModelExtender)
        {
            _pageModelExtender = pageModelExtender;
            _sectionsProvider = sectionsProvider;
        }

        public override ActionResult Index(RenderModel model)
        {
            var allSections = model.Content.Children.ToList();
            var listOfSectionsToRender = _sectionsProvider.GetListOfSectionsToRender(allSections);
            var pageViewModel = new PageViewModel {Sections = listOfSectionsToRender};
            return View("Page", _pageModelExtender.ApplyLayoutToModel(pageViewModel, model.Content));
        }
    }

Przy budowie strony, przechodzę przez wszystkie dzieci Tego Noda (konkretnych implementacji Document Typu).

Dla każdego z nich, odpalany jest odpowiedni SectionBuilder, którego odpowiedzialnością jest pobranie modelu umbraco i zwróceniu View Modelu silnie typowanego oraz wskazanie, który z widoków powinien zostać wykorzystany do zbudowania danej sekcji.
Interfejs ISectionBuilder:
    public interface ISectionBuilder
    {
        string ViewName { get; }
        BaseViewModel CreateViewModel(IPublishedContent content);
        bool DeosApply(string documentAlias);

    }
Przykładowy Builder:
    public class HeaderBuilder : ISectionBuilder
    {
        public string ViewName => "HeaderView";
        public BaseViewModel CreateViewModel(IPublishedContent content)
        {
            return new HeaderViewModel
            {
                TestString = content.GetPropertyValue("testMessage")
            };
        }

        public bool DeosApply(string documentAlias)
        {
            return documentAlias == DocumentTypes.Header;
        }
    }
Dzięki temu przypisuję do określonego DocTypu określony builder, a Factory zwraca mi odpowiedni Builder dla danej sekcji strony. Jest to możliwe między innymi dzięki IoC kontenerowi zastosowanemu w projekcie, jednak o tym i o budowie mojej Factory opowiem w następnym poście.
Do zobaczenia wkrótce :)

czwartek, 2 marca 2017

3,2,1... Hello World!


Zawartość bloga

Blog będzie swego rodzaju dokumentacją moich poczynań z projektem webdotnet i prawdopodobnie będę go kontynuował po jego zakończeniu. Dziś w skrócie opiszę projekt oraz kilka rzeczy porządkowych.

Założenia w blogu i projekcie

Blog będzie prowadzony w języku polskim, obecnie nie zamierzam pisać po polsku i/lub angielsku. Nie wiem jeszcze jak się to rozwinie w przyszłości.
Kod będzie pisany w języku angielskim wszelkie nazwy zmiennych, meto, klas, projektów, etc będą w języku angielskim.  Przez lata przyzwyczaiłem się już do tego no i chcę by mój kod był zrozumiały nie tylko dla ludzi władających językiem polskim :) Dlatego też wszystko, co znajdzie się na GitHubie, także będzie po angielsku.

O Projekcie

Projekt przyszedł mi do głowy już jakiś czas temu, zrobiłem nawet podstawy. Dodałem StructureMap-a, jako IoC contener dodałem "core”, jeśli chodzi o silnie typowane widoki i to, w jaki sposób są budowane View Modele. 

Struktura projektu:


Webdotnet.Umbraco - Jest jedynie pustym projektem webowym, jedyne, co będzie się tu zmieniać tu to widoki.

Webdotnet.Custom - Tu znajdują się wszystkie modyfikacje, które zrobiłem w umbraco np. buildery do silnie typowanych widoków, a także renderowanie całej strony w oparciu o template i to, co znajduje się w back office umbraco, szerzej o tym napiszę w następnym poście na blogu.

Webdotnet.Frontend - Jak sama nazwa wskazuje jest to frontend aplikacji. Jeszcze nie jestem pewny czego użyje, gulpa czy webpacka (a może jeszcze coś innego), ale tu będzie się znajdował frontend budowany przez jeden z compiler-ów. Style będą w sass-ie, kompilator na wyjściu będzie mi wyrzucał zminifikowane bądź nie (w zależności od tego czy na środowisko dev czy prod) style i skrypty. Chciałbym także w skryptach móc używać ES6, będę więc będę potrzebował Babela, bądź czegoś podobnego. 

Webdotnet.Test - Tu znajdują się wszystkie testy. W miarę możliwości będę ten projekt prowadził w metodologii TDD

Webdotnet.Db - Backup bazy danych by móc uruchomić projekt lokalnie i mieć wszystkie zmiany z umbraco

Kod projektu:

Na GitHubie jest dostępna instrukcja jak uruchomić projekt u siebie lokalnie. Zachęcam do pobrania, eksplorowania i komentowania samego projektu jak i jego kodu. Wszelkie sugestie mile widziane, może coś zrobiłabyś/zrobiłbyś inaczej. Tak? A dlaczego? Zachęcam do konstruktywnej krytyki. 

Co dalej?

Docelowo projekt webdotnet ma zastąpić mój blog na platformie blogger.
W następnym poście postaram się omówić jak działa obecnie projekt, natomiast możesz już sprawdzić go na własną rękę. Poddajmy testowi czytelność mojego kodu. Jeśli nie wymaga zbyt wiele wyjaśnień, to znaczy, ze jest ok :) Jeśli nie wiesz, jak co powinno się zachować, pamiętaj o przeczytaniu testów, bo one są główną "dokumentacją" projektu. 

Pozdrawiam serdecznie i zapraszam Kamil Hadas