Continous Code Retreat

Byliście kiedyś na CodeRetreat? Bardzo fajna impreza, której ideą jest pisanie kodu  w możliwe najlepszy sposób. Na koniec dnia nie trzeba dostarczyć produktu, przede wszystkim trzeba poznać nowe sposoby na rozwiązywanie tego samego problemu. Oczywiście w trakcie trwania imprezy, żeby nie było za nudno, mistrz ceremonii rzuca pod nogi kolejne kłody: krótkie metody, brak ifów, brak czegoś innego, itp-itd, fajna sprawa która powoduje, że uczestnik ciągle poszukuje, a przez to poznaje nowe różne rozwiązania. Często okazuje się, że ograniczenia które były wprowadzana, wymuszały chwilę rozmyślenia jak napisać kawałek kodu inaczej, a to powodowało dużo lepszy kod. Do czego zmierzam? Otóż po pierwsze primo, już za nie długo odbędzie się kolejna już edycja Global Day of Coderetreat we Wrocławiu, po drugie primo: takie ograniczenia z code retreat można wprowadzić sobie w życie także w pracy w normalnym projekcie. Otóż na każde rozpoczęcie sprintu lub tygodnia, można ustalić reguły: np. w tym tygodniu decydujemy się, że metody nie mogą przekroczyć np. siedmiu linijek, albo nie używamy typów prostych, wersja dla profesjonalnych graczy: nie używamy if’ów, etc. Dlaczego? W ten oto prosty sposób, możemy nie jako wymusić na swoich kolegach pisanie lepszego kodu, nie trzeba im wtedy mówić, o SOLID, czy dobrych praktykach, czy czymś innym, po prostu ustalacie wspólnie, że to i tamto i przez tydzień macie taką “grę”, potem retrospekcja i nowe reguły, nowe doświadczenia, nowy tydzień i nowe reguły i znowu retrospekcja – aż wszyscy zrozumieją jak pisać dobrze. Tym sposobem i sprint przyjemniejszy i kod lepszy. Takie moje luźne myśli na kolejny tydzień.

.net developers days – myśli zebrane

Tym razem udałem się do warszawy na konferencje .net developers days i zrobiłem sobie słit focie ze Scottem – yey! yey! yey! 
Wiem, mam zamknięte oczy (smuteczek) Ale! Ze Scottem!!! Mam jeszcze jedno, ale tak niewyraźne, że nie uwierzycie że to ja.
A teraz część z myśli, które zebrałem słuchając różnych wykładów i rozmyślając też o różnych rzeczach podczas słuchania:
Nie mieszać klas które służą do czystego przechowywania danych oraz tych, które na nich operują. Powinno to ułatwić skalowalność systemu, utrzymanie systemu, jest też spora szansa na to że system stanie się mniej stanowy, a przez to mniej awaryjny.

Value objects z DDD to fajna sprawa, nawet jeśli nie korzysta się z pełnego dobrodziejstwa które oferuje ddd, to warto wprowadzić przynajmniej część. Duża zaletą jest to że string który może się kryć z User.Firstname oraz User.Address i który normalnie możemy ze sobą porównać, nagle stanie się nie porównywalny ponieważ stringa ukryjemy w klasie UserAddress, a stringa odpowiedzialnego za Firstname ukryjemy w klasie UserFirstname i pomimo tego że w środku są to stringi, to dla kompilatora będą to dwie zupełnie inne typy, przez co nie da się ich ze sobą porównać. Dodatkową zaletą jest to, że podczas definiowania parametrów metody, czytelniej będzie czytać foo(UserFirstname name, UserAddress address){…} niż foo(string name, string address){…}
Dostając projekt, wymagania, nowego klienta, etc możemy się wkurzać na wiele rzeczy,  naprawdę wiele. Ale warto sobie zdać posiedzieć przez chwilę i pomyśleć. Znaleźć wszystkie rzeczy, które są dla nas/was/mnie denerwujące, następnie podzielić je na dwie grupy: 1-mogę to zmienić, 2- nie mogę tego zmienić. I teraz wszystkie dwójeczki lądują w kuble, skoro nie można tego zmienić, to się trzeba przyzwyczaić. A wszystkie 1 lądują na naszej tapecie i robimy tak, żeby było lepiej. Do dwójeczek nigdy nie wracamy i godzimy się z losem jaki nas/was/mnie spotkał. Podobną myśl powiedział mi kiedyś znajomy, nie przejmuj się rzeczami na które nie masz wpływu – świetnie działa.
Wszyscy jesteśmy ludźmi i musimy się pogodzić z tym, że czasem coś nam nie wyjdzie – musimy się z tym pogodzić. Nie warto zakładać, że wszystko co robimy skończy się spektakularnym sukcesem i nie każdy z nas skończy tak jak Marek Zuckerberg czy inne Grycanki. Czasem słońce, czasem deszcze – takie jest życie. 
Jeśli prowadzicie retrospekcje, gdzie programiści mogą się spotkać i porozmawiać o tym co się udało, co było dobre, co się sprawdza, ale i to co się nie udało, co złe, co się nie sprawdza (patrz punkt poprzedni). To samo dotyczy menadżerów projektu, oni także mają swoje przemyślenia (tak tak, oni też myślą). Jeśli macie takie spotkania, to może warto aby podzielić się decyzjami, przemyśleniami, ustaleniami, próbami, sukcesami i porażkami z resztą ludzi którzy z wami pracują w firmie. W ten sposób, może udało by się ustrzec przed najczęstszymi błędami, może decyzje które podejmujecie na nowy sprint okażą się nie najlepsze, ponieważ inny zespół już próbował, a może dostaniecie wskazówki na co warto zwrócić uwagę próbując nowego rozwiązania. Dzielenie się wiedzą jest sexi!
Input w obiekcie na poziomie konstruktora – ? Co ja miałem na myśli? Walidacja? Zagadka – stawiam że tak. Jak sobie przypomnę to dopiszę.
Breakstorming – fajna pomysł nie tylko dla testerów. Pracujecie w zespole? Spotkajcie się od czasu do czasu, ale nie za rzadko i zróbcie sobie code review, gdzie główną ideą jest zepsucie kodu innego kolegi; na zasadzie: pacz Stefan, jak wyślę takie parametry i wystąpi taki warunek, to twój serwis rzuca wyjątkiem. Można wymyślać najbardziej złośliwe ścieżki, najmniej prawdopodobne do spełnienia, etc. Chodzi o możliwie najefektywniejsze wysadzenie jeźdźca z siodła
Aplikacje webowe powinny być w stanie “zadziałać” bez połączenia z serwerem. Tak! Chodzi oczywiście o aplikację którą mamy już u nas, lub o taką która zaciąga statyczne html plus javascript, natomiast mięsko kryje się gdzieś głęboko na serwerach. Wtedy zamiast rzucania magicznymi kodami błędów, użytkownik powinien być w przyjazny sposób poinformowany, że nie da rady teraz wykonać tego trudnego zadania. Ale może popatrzeć na nasz spinner czy coś, który mówi: wiemy że nie działa i walczymy, próbuj dalej.
Nie ładować konfiguracji podczas wykonywania kodu – już spieszę ze szczegółami. Chodzi o przypadek, gdy ustawienia miałby być ładowane przez samą metodę podczas wykonywania kodu. Czyli mogłoby dojść do sytuacji, że metoda foo(“jarek”, “wrocław”){…} raz wykona logikę_1 a raz wykona logikę_2, ponieważ pomiędzy poszczególnymi wywołaniami metod, plik z konfiguracją został zmieniony i teraz zachowuję się inaczej. Prowadzi to do niespójności w aplikacji. Konfiguracja powinna być zaczytana raz na początku działania aplikacji i tyle. Aby zmienić ustawienia, należy wykonać restart aplikacji.
Dlannybecon – nie mam pojęcia co napisałem na kartce ^.^
Robiąc sobie zdjęcie ze Scottem :):):):) patrz na górze, doszły mnie słuchy, że przygotowywane są learniing box dla nowego asp i mvc na poziomie novice, regular, master – i powinny być oficjalnie dostępne w styczniu 2016 roku. Mają umożliwić samokształcenie jak i przygotowanie sesji dla innych ludzi. Wersje novice są chyba na mva. Nie szukałem więc nie posiadam linka.
Klasycznie czekam na komentarze lub nie zgody z moim rozumowaniem. Chętnie przyznam się do błędu jeśli taki popełniłem.
ps.
Poznałem fajny podcast:

Konferencja DevDay – moje złote myśli wyniesione

Byłem na DevDay2015!
Prezentacje były i można oglądać, albo będzie można wkrótce. Część ludzi spotkała się z ogromną ilością swoich fanów, inni leczyli kaca, inni słuchali i starali się coś z tego wyciągnąć. Jako że nie zapiłem, to starałem się coś mądrego usłyszeć, poniżej materiał zebrany i w mojej interpretacji:

Decyzje które podejmujesz podczas wybierania frameworka, biblioteki, pracownika, czy czegokolwiek innego powinieneś przemyśleć pod kątem, nie tylko rozwiązania, które przyniesie, a raczej odpowiedzialności, jaka zostanie na ciebie zrzucona. To nie wszystko, gdy znajdziesz rozwiązanie idealnie pasuje do twojego problemu, znajdź inne narzędzie które też rozwiąże ten problem i porównaj zady i walety obu. Upewnij się że ciężar wybranego przez ciebie rozwiązania jest akceptowalny. Jeśli chcesz być dobrym strategiem, architektem, rekruterem, pomyśl jakie problemy sprawi świeżo wybierana technologia i znajdź kolejne rozwiązanie tego problemu – uwaga na rekurencję.
TL;DR; decyzje które podejmujesz to nie tylko rozwiązanie, ale przede wszystkim konsekwencje

Każdy kod który tworzysz, nie zależnie czy jest to metoda, klasa,  projekt, czy wszystko powinien być tak duży/mały aby rozwiązywał jeden i tylko jeden problem. Wiadomo SRP i takie. Ale jest jeszcze jedno spostrzeżenie: ten mały kod rozwiąże twój problem i fajnie, ale jeśli coś będzie z nim nie tak, wtedy kod psuć tylko tą jedną małą rzecz – nic więcej. SRP FTW! Ma ktoś taki tatuaż?
TL;DR; mały kod, małe projekty, małe serwisu. Jeśli będzie fakup, to rozwali tylko małą część twojej aplikacji lub systemu.

Wunderlist taka rozbudowana aplikacja todo – architektura opiera się o kilka(naście) technologi, każda klasa jest osobnym serwisem, komunikacja po http/rest. Rozwiązanie daje mega skalowalność, łatwo jest serwisy aktualizować, zmienić i wszystko. Całkiem interesujące podejście do całkiem sporego projektu. Bardzo mnie kusi bliższe poznanie jak to się robi, jak się z tym żyje i pracuje. Sama idea do mnie bardzo przemawia.

Poza tym, pogadałem i napiłem się piwa ze takie osobnikami jak Chris Heilmann,Scott Allen czy Chad Fowler – co też daje fajne wrażenia, że takie ważne osoby też piją piwo i też są ludźmi – kto by pomyślał. Oprócz nich poznałem kilka nowych osób, czy też dopoznałem innych.

Lubię hackatony

13 czerwca byłem na kolejnym. Art of code – świetna impreza, gdzie temat przewodnim była sztuka. Razem z zespołem Marcel, Michał, Łukasz stworzyliśmy aplikację która przy pomocy wolframa rozpoznawała zdjęcia, które jej wysłaliśmy, zwracała nam listę słów opisujących obraz. Następnie szukaliśmy synonimów. Aby następnie odegrać dźwięki na podstawie zwróconych słów. Chcieliśmy stworzyć nastrój do obrazu.
Kod dostępny jest na githubie:
https://github.com/jstadnicki/HearTheImage
Wszystko szlo pięknie do momentu, gdy trzeba było uruchomić aplikację. Okazało się że BASS, bibliotek do dźwięków którą chcieliśmy zaprząc do grania, odmówiła posłuszeństwa. Dosłownie minuty przed oddaniem projektów – świnia! Media player to nie chciał grać, musieliśmy więc rzucić ręcznik.
Suma sumarum, świetna impreza, świetni ludzie, świetna organizacja – gorący klimat (to jedyny minus). Jeśli będzie kolejna edycja, na pewno się zapisze.
Przy okazji, za dwa tygodnie organizujemy własny, trochę mniejszy niż ten, ale równie gorąco zapraszam, więcej informacji pod linkiem:
http://www.meetup.com/PGS-Software-Talks/events/223148590/
http://softwaretalks.pl/events/event/dev-qa-hackathon/

Autofac update – dynamiczna zmiana implementacji

Wiadomo, że każdy projekcie są testy. W części z nich są testy jednostkowe, w innych są testy integracyjne, w innych testy programistyczne – programista klika i jak działa to działa, a w jeszcze innych test na produkcji u klienta razem z milionami użytkowników. Generalnie każdy jakieś test ma. Wiadomo jak jest w projektach komercyjnych, klient chce aplikację działająca, wykonaną z najnowszymi i najlepszymi technikami, najlepiej napisaną przez juniorów, bez testerów i PM – tak najczęściej planowany jest budżet na aplikacje. Programiści czasem potrafią spełnić część tych wymagań i udaje się nam stworzyć aplikację, która jest stabilna (najczęściej), wygląda przyzwoicie, została napisana tak, że można ją rozwijać – generalnie klient jest zadowolony, a przynajmniej nie pieni się i jest w stanie zaakceptować produkt.
Dzieje się tak, ponieważ Ci programiści dzielnie przeklikują swoje wytwory, piszą możliwie dobry kod, przy kiepskich wymaganiach czy ich braku. Czasem gdy trzeba wyklikać to samo tysiąc razy, człowiek robi się leniwy, albo nie uważny i czy tego chcemy czy nie nie jesteśmy w stanie wyklikać wszystkich przypadków. Najczęściej gdy projekt jest już sporych rozmiarów, posiada skomplikowaną logikę lub wiele alternatywnych do siebie ścieżek. 
W moim przypadku naszą słabą stroną były problemy w wydajnością. Na developerskich maszynach, gdzie testowaliśmy, mieliśmy po kilka kont użytkownika, kilka, kilkadziesiąt, lub trochę ponad setkę wpisów. Generowanie danych za każdym razem gdy baza się zmieni i trzeba było ją odtwarzać od zera nie należało do przyjemnych rzeczy, nie mieliśmy migracji, więc drop a potem create. Testy selenium pojawiły się później, ale też zajmowały wieczność.
Zmierzam do tego, że łatwo byłe tego uniknąć, generując sobie masę testowych danych. Jak tego dokonać? O tym właśnie dzisiaj, odrobina kodu się także pojawi a wszystko dostępne będzie na githubie. Jak zawsze minister zdrowia ostrzega, przykłady mogą być przejaskrawione, a rozwiązanie może się okazać przydatne tylko dla mnie.
Przykładowym problememe do rozwiązania jest prosta aplikacja, która umożliwia założenie konta, zalogowanie się, oraz dodanie jakiegoś prostego wpisu tekstowego, który jest widoczny dla wszystkich. Coś jak blog, czy czat czy lista ogłoszeń, to nie jest do końca ważne.
Zacznijmy od struktury aplikacji:
Dla prostoty wszystko co potrzebne umieściłem w jednym kontrolerze. A zwinięte foldery nie mają żadnego wpływu na treść edukacyjną tego posta.
Ok, to zaczynamy. Rejestracja nowego użytkownika wygląda tak:

   1:  [HttpGet]
   2:  public ActionResult Register()
   3:  {
   4:      var viewmodel = new RegisterViewModel();
   5:      return this.View("Register", viewmodel);
   6:  }
   7:   
   8:  [HttpPost]
   9:  public ActionResult Register(RegisterDto dto)
  10:  {
  11:      this.accountService.Register(dto);
  12:      return this.RedirectToAction("Index");
  13:  }
I ostatecznie prosty serwis:

   1:  public void Register(RegisterDto dto)
   2:  {
   3:      WebSecurity.CreateUserAndAccount(
   4:          dto.Email,
   5:          dto.Password);
   6:  }
Jak widać korzystam z SimpleMembershipProvider. Klasa dto do rejestracji też jest książkowo prosta:

   1:  public class RegisterDto
   2:  {
   3:      public string Email { get; set; }
   4:      public string Password { get; set; }
   5:  }
Tak więc, aby założyć konto wystarczy wpisać dwa stringi i ciach, konto dostępne. Oczywiście gdy będzie trzeba to powtórzyć wiele razy, zacznie się to robić męczące i nudne. Dlatego leniwi programiści mogą wymyślić sobie coś takiego:

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: Consolas, “Courier New”, Courier, Monospace;
background-color: #ffffff;
/*white-space: pre;*/
}

.csharpcode pre { margin: 0em; }

.csharpcode .rem { color: #008000; }

.csharpcode .kwrd { color: #0000ff; }

.csharpcode .str { color: #a31515; }

.csharpcode .op { color: #0000c0; }

.csharpcode .preproc { color: #cc6633; }

.csharpcode .asp { background-color: #ffff00; }

.csharpcode .html { color: #800000; }

.csharpcode .attr { color: #ff0000; }

.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}

.csharpcode .lnum { color: #606060; }

   1:  [HttpGet]
   2:  public ActionResult NewUsers()
   3:  {
   4:      this.testService.CreateNewUsers();
   5:      return this.RedirectToAction("Index");
   6:  }
Gdzie serwis został zaimplementowany w taki sposób:

   1:  public void CreateNewUsers()
   2:  {
   3:      var dto = new RegisterDto
   4:      {
   5:          Email = Faker.InternetFaker.Email() + Faker.NumberFaker.Number(),
   6:          Password = Faker.NumberFaker.Number(1000000000, 2000000000).ToString()
   7:      };
   8:      this.accountService.Register(dto);
   9:  }
Fakera opisałem w poprzednim poście. Warto zwrócić uwagę, że test serwis korzysta z account service. Dwie ważne rzeczy: każdy wie, że zależności powinny iść tylko w pionie, nigdy w poziomie – istnieje ryzyko zależności cyklicznych; jest to serwis testowy, wiec korzysta z normalnego przepływu danych, nie robi nic na skróty, nie oszukuje, także ułatwia nam tworzenie użytkowników, a jednocześnie testuje działające już serwisy.
Jak do tej pory jeszcze nie ma wielkiego szału, ale się powoli rozkręcam. Kolejny etap to wpis w aplikacji, kontroler wygląda tak:

   1:  [HttpGet]
   2:  [Authorize]
   3:  public ActionResult NewBlogPost()
   4:  {
   5:      var viewmodel = new BlogPostViewModel();
   6:      return this.View("NewBlogPost", viewmodel);
   7:  }
   8:   
   9:  [Authorize]
  10:  [HttpPost]
  11:  public ActionResult NewBlogPost(NewBlogPostDto dto)
  12:  {
  13:      this.postingService.NewBlogPost(dto);
  14:      return this.RedirectToAction("Index");
  15:  }
Kod nie powinien niczym zaskakiwać, GET i POST, oraz wymagane wcześniejsze zalogowanie się użytkownika. Warstwa implementująca:

   1:  public void NewBlogPost(NewBlogPostDto dto)
   2:  {
   3:      var userId = this.accountService.GetCurrentLoggedUserId();
   4:      var model = new BlogPost(userId, dto.Text, DateTime.Now);
   5:      this.database.BlogPosts.Add(model);
   6:      this.database.SaveChanges();
   7:  }
Dto dla nowego wpisu jest niebiańsko prosta:

   1:  public class NewBlogPostDto
   2:  {
   3:      public string Text { get; set; }
   4:  }
Ale wróćmy do serwisu, w serwisie korzystając z SMP (single membership provider) pobieramy aktualne ID użytkownika. Może nie bezpośrednio z SMP, ale prostego wrapperka nad SMP. W momencie implementacji postawiłem na opcje zaciągania danych o użytkowniku z SMP.
Sam wrapper wcześniej pokazany częściowo, teraz w calej okazałości:

   1:  class WebSecurityAccountService : IAccountService
   2:  {
   3:      public void Logout()
   4:      {
   5:          WebSecurity.Logout();
   6:      }
   7:   
   8:      public bool Login(LoginDto dto)
   9:      {
  10:          var result = WebSecurity.Login(dto.Email, dto.Password);
  11:          return result;
  12:      }
  13:   
  14:      public void Register(RegisterDto dto)
  15:      {
  16:          WebSecurity.CreateUserAndAccount(
  17:              dto.Email,
  18:              dto.Password);
  19:      }
  20:   
  21:      public int GetCurrentLoggedUserId()
  22:      {
  23:          return WebSecurity.CurrentUserId;
  24:      }   
  25:  }
No dobra, fajny pomysł, informacje o użytkowniku zawsze pobierane z serwera, wydaje się bezpieczne i w ogóle. Ale teraz dochodzimy znowu do momentu, gdy chciałbym napisać kawałek kodu który pozwoli mi jednym kliknięciem utworzyć nowy wpis. Najlepiej za każdym razem z losowym tekstem (tutaj Faker daje radę) ale jeszcze z losowego istniejącego konta. W tym momencie na chwilę zrobiło się trudno, ale skoro mamy IAccountService i z niego pobieramy informacje o użytkowniku, czemu tego nie wykorzystać, wystarczy go tylko podmienić na inny, mój, i losować z niego użytkowników:

   1:  [HttpGet]
   2:  public ActionResult NewPosts()
   3:  {
   4:      this.testService.CreateNewPosts();
   5:      return this.RedirectToAction("Index");
   6:  }
Potem:

   1:  public void CreateNewPosts()
   2:  {
   3:      var users = this.database.Users.ToList();
   4:      var random = users.ElementAt(Faker.NumberFaker.Number(users.Count - 1));
   5:      var dto = new NewBlogPostDto
   6:      {
   7:          Text = Faker.TextFaker.Sentences(3)
   8:      };
   9:   
  10:      SpecialAccountService.CurrentLoggedUserId = random.Id;
  11:   
  12:      this.postingService.NewBlogPost(dto);
  13:  }
Docieramy powoli do mięska. Z bazy danych wyciągamy wszystko użytkowników, losujemy jednego i zapamiętujemy. Następnie linijka 10 dzięki SpecialAccountService ustawia Id “aktualnie” zalogowanego użytkownika, a następnie zwróci to Id, gdy ktoś będzie pytać o aktualnie zalogowanego użytkownika. Na końcu znowu, wykorzystujemy wcześniej napisany serwis, który zachowuje się normalnie i jest dodatkowo testowany przez nasze generowanie testowych danych. Dlaczego SpecialAccountService działa tak soczyście?

   1:  public class SpecialAccountService : IAccountService
   2:  {
   3:      private readonly WebSecurityAccountService realAccountService;
   4:   
   5:      public SpecialAccountService()
   6:      {
   7:          this.realAccountService = new WebSecurityAccountService();
   8:      }
   9:   
  10:      public void Logout()
  11:      {
  12:          this.realAccountService.Logout();
  13:      }
  14:   
  15:      public bool Login(LoginDto dto)
  16:      {
  17:          return this.realAccountService.Login(dto);
  18:      }
  19:   
  20:      public void Register(RegisterDto dto)
  21:      {
  22:          this.realAccountService.Register(dto);
  23:      }
  24:   
  25:      static public int CurrentLoggedUserId { get; set; }
  26:   
  27:      public int GetCurrentLoggedUserId()
  28:      {
  29:          return CurrentLoggedUserId;
  30:      }
  31:  }
Klasa ta implementuje IAccountService i jest ona używana w zarejestrowana w autofacu. Natomiast gdy jest potrzeba prawdziwej rejestracji użytkownika, całą robotę deleguje do prawdziwego serwisu. Dzięki temu można rejestrować,logować czy wylogować użytkownika. A bajer z aktualnym użytkownikiem ułatwia nam tworzenie losowych wpisów dla losowych użytkowników.
Wiadomo, że na produkcje nie powinno się wypuszczać takiego kodu, dlatego normalnie trzeba by przygotować odpowiednią konfigurację IOC gdzie IAccountService będzie implementowany przez WebSecurityAccountService, a na potrzeby developerki wystarczy SpecialAccountService – można tak zrobić. Można też poprosić autofaca, aby zmienił swoje dotychczasowe zachowanie i nadpisać wcześniejsze reguły:

   1:  public class HijackService : IHijackService
   2:  {
   3:      public void RestoreIOC()
   4:      {
   5:          var builder = new ContainerBuilder();
   6:          builder.RegisterType<WebSecurityAccountService>().As<IAccountService>();
   7:          builder.Update(ApplicationIocContainer.Container);
   8:      }
   9:   
  10:      public void HijackIOC()
  11:      {
  12:          var builder = new ContainerBuilder();
  13:          builder.RegisterType<SpecialAccountService>().As<IAccountService>().SingleInstance();
  14:          builder.Update(ApplicationIocContainer.Container);
  15:      }
  16:   
  17:      public IOCStatus GetStatus()
  18:      {
  19:          var isHijacked = ApplicationIocContainer.Container.Resolve<IAccountService>() is SpecialAccountService;
  20:          return isHijacked ? IOCStatus.Hijacked : IOCStatus.Normal;
  21:      }
  22:  }
Od tej pory możemy dynamicznie rejestrować swoje klasy, które ułatwią nam udawanie kogoś kim nie jesteśmy, a po skończonej generacji danych przywrócić aplikację do oryginalnego stanu i zacząć właściwe testowanie. Największą gwiazdą tego postu jest metoda Update z IOC, która umożliwia aktualizację powiązać interfejsu z klasą implementującą bez potrzeby zmiany konfiguracji, bez potrzeby restartu aplikacji, żeby autofac skonfigurował się od nowa, etc.
A dzięki temu wszystkie możemy stworzyć sobie taki prosty interfejs aplikacji:
Gdzie istnieje możliwość normalnego działa z aplikacją, ale gdy zajdzie potrzeba, można na chwilę pożyczyć kontener, wygenerować sobie niezwykle szybko sporo danych, i ponownie jednym kliknięciem przywrócić normalny stan aplikacji. Tutaj tworzę tylko jednego użytkownika i jeden wpis, ale kto bogatemu zabronić tworzyć ich tysiące?
Uwagi, pomysły chętnie przyjmę.
Kod dostępny jest na bitbucket: https://bitbucket.org/jstadnicki/jstadnicki-blog
Zaczynam od jednego, z czasem gdy będzie więcej dużych wpisów, kolejne rzeczy związane z blogiem będę wrzucane tam.
Milej niedzieli!