nuget_logo

Czasy gdy pisaliśmy ręcznie elementarne metody już dawno minęły. Dziś całkowicie naturalnym dla programistów jest wykorzystywanie gotowych bibliotek. Bo w sumie po co wymyślać koło na nowo jak mamy pakiety NuGet które działają „out of the box”?. Portal jest pełen bibliotek, zarówno najwyższej jakości jak i tych trochę gorszych…

Dziś zajmiemy się tymi które każdy programista .Net powinien (według mnie) znać. Dla starych wyjadaczy nie odkryje pewnie ameryki, ale myślę że dla naszych młodszych kolegów może to być bardzo wartościowa lista. Większość z nich wywodzi się z .Net Framework ale dziś dla ich rozwoju niezbędna jest też kompatybilność z Core/.Net 5.0+. Oczywiście nie chodzi o to by w każdym projekcie stosować je wszystkie, każdy ma swoje specyficzne zastosowanie. Części z nich możemy nigdy nie użyć ale warto wiedzieć o istnieniu i potencjalnym zastosowaniu wszystkich.

EntityFramework (Core)

W zestawieniu nie mogło zabraknąć króla .Netowych ORM’ów. Pierwotnie był dostarczany jako integralna część .NET Framework, od wersji 6 jest dostarczany niezależnie od frameworka. Aktualnie istnieje również niezależnie biblioteka Entity Framework Core, która do wersji 5.0 implementuje wersje .Net standard pozwalającą na użycie jej w .Net framework. Wersje 5.0 i wyżej działają tylko w .Net Core. Ponadto EF6.4 dzięki multi-targetingowi działa na .NET Core oraz .NET Framework (tylko Windows). Jak widać powyżej łatwo się w tym pogubić. Poniższa grafika pokazuje wsparcie dla poszczególnych rozwiązań:

biblioteki nuget

Należy jednak pamiętać że EF różni się od EF Core więc to że na Windows możemy użyć właściwie wszystkich wersji nie oznacza że ich możliwości będą identyczne (porównanie funkcji). Ja osobiście polecam wybierać (gdy nie potrzebujemy funkcji specyficznych dla „starego”) Entity Framework Core.

Automapper

Zakładając że wyciągnęliśmy już dane za pomocą EF/EF Core, teraz chcielibyśmy na nich pracować. Kolejnym krokiem będzie przepisanie danych do DTO. Koncept DTO jest namiętnie wykorzystywany przez programistów .Net (i nie tylko). Ręczne przepisywanie danych poszło w niepamięć już bardzo dawno temu. Przepisanie pól o tej samej nazwie może być załatwione zwykłą funcją. Po co ją jednak pisać jak można użyć dosłownie jednej linijki?

var configuration = new MapperConfiguration(cfg =>  
{ 
    cfg.CreateMap<Bar, BarDto>(); 
});

Automapper potrafi jednak o wiele więcej. Niestandardowe mapowanie propercji, blokowanie mapowania w określonych warunkach, czy automatyczne obsłużenie pustych wartości, nulli to tylko wierzchołek tego co dostajemy „z pudełka” w tej bibliotece.

var configuration = new MapperConfiguration(cfg =>  
{ 
    cfg.CreateMap<Bar, BarDto>() 
        .ForMember(dto => dto.Address, expression => expression.MapFrom(bar => bar.UserAddress))
		.ForMember(destination => destination.Value, opt => opt.NullSubstitute("Other Value")))
		.ForMember(dest => dest.baz, opt => opt.Condition(src => (src.baz >= 0)));; 
});

Swagger / Swashbuckle.AspNetCore

Lubicie pisać dokumentację? To raczej pytanie retoryczne 🙂 Ja też nie lubię. A co powiecie na paczkę która zrobi to za was w kilka minut i dodatkowo poda w przystępny kolorowy interaktywny sposób? Do tego właśnie służy Swagger. Jest to biblioteka którą od dawna wykorzystujemy w .Net Framework. Zresztą nie tylko tam, również inne technologie chętnie korzystają z dobrodziejstw Swaggera i OpenAPI. Jeżeli piszesz API to wystarczy dodać do niej Swaggera skonfigurować w kilka minut i gotowe. Teraz dokumentacja będzie pisała się sama, no prawie 🙂 Jeżeli projekt w którym potrzebujesz takiego rozwiązania pisany jest w .Net Core lub .Net 5.0+ to żaden problem. Wtedy szukaj paczki o nazwie Swashbuckle.AspNetCore. To jest dokładnie to samo. Pamiętaj tylko żeby nie wystawiać niezabezpieczonego Swaggera na produkcji!

RestSharp

RestSharp to klient HTTP. Nie jest to niezwykle przełomowa lub odkrywcza biblioteka. Sam dotnet posiada wbudowaną bibliotekę klienta HTTP. Dla mnie jednak jest ona toporna i nieintuicyjna, natomiast RestSharp to taki klient HTTP na sterydach 😀 Przyjazny prosty i intuicyjny. Poniżej przedstawiam przykładowy kod RestSharp:

var client = new RestClient("https://localhost:5003/"); 

var request = new RestRequest("Account/SignUp", DataFormat.Json); 
request.AddJsonBody(new SignUpViewModel() { Email = "test@gmail.com" }); 
SignUpResponse response = await client.PostAsync<SignUpResponse>(request); 
Console.WriteLine($"response = {response.Token}");

A poniżej to samo „zwykłym” klientem:

var data = new SignUpViewModel() { Email = "test@gmail.com" }; 
var client = new HttpClient(); 
var dataAsString = JsonConvert.SerializeObject(data); 
var content = new StringContent(dataAsString, Encoding.UTF8, "application/json"); 
var respone = await client.PostAsync("https://localhost:5003/Account/SignUp", content); 
var resultStr = await respone.Content.ReadAsStringAsync(); 
var result = JsonConvert.DeserializeObject<SignUpResponse>(resultStr); 
Console.WriteLine($"response = {result.Token}");

Sami oceńcie czy warto. Warto zaznaczyć że podstawowa wersja biblioteki nie posiada żadnych zależności więc nie ma żadnych problemów z kompatybilnością czy konfliktami.

Polly

Kolejna biblioteka pomaga w komunikacji z zewnętrznymi serwisami. Najczęściej wykorzystujemy ją do ponawiania połączenia gdy te się nie powiedzie, choć to tylko ułamek jej możliwości. Jej działanie opiera się na trzech krokach:
1. Przechwycenie wyjątku jaki chcemy obsłużyć.
2. Określenie akcji jaka ma się zadziać (Retry/Circuit-breaker/Timeout/itp.)
3. Uruchomienie metody dla której ma być zastosowana reguła.
Poniżej bardzo prosta metoda którą chcielibyśmy ponowić maksymalnie 3 razy w razie niepowodzenia. Dodatkowo konfiguracja zakłada że ponowienia odbędą się po 20 sek. następnie po 30, a ostatnie po 50 sekundach.

var client = new WebClient();
 return Policy
 .Handle<WebException>()
 .WaitAndRetry(new[]
 {
 TimeSpan.FromSeconds(20),
 TimeSpan.FromSeconds(30),
 TimeSpan.FromSeconds(50)
 }, (ex, timeSpan, retryCount, context) =>
 {
 _logger.Error(ex, $"Error - retrying (count: {retryCount}, timeSpan: {timeSpan})");
 })
 .Execute(() => client.DownloadSomeStuff(url));

Myślę że kod nie jest zbyt skomplikowany, prawda? Warto dodać że Polly jest w pełni darmowa, wspiera .Net Framework i .Net Core. Biblioteka jest członkiem .Net Foundation co gwarantuje że będzie utrzymywana w przyszłości.

Dapper

Dapper to kolejny ORM w zestawieniu. Jest to lekka alternatywa dla EF/EF Core. EF jest bardzo fajnym rozwiązaniem jednak czasami bywa problematyczny. W określonych sytuacjach potrafi pobierać bardzo dużo zbędnych danych do pamięci. Kolejną bolączką może być jakość tworzonych zapytań, szczególnie przy wielokrotnym include. Sam wielokrotnie „znalazłem” SQL mający więcej niż dwa tysiące linii wygenerowany przez Entity Framework. Na powyższe problemy wybawieniem ma być Dapper. W przypadku Dappera to Ty sam piszesz zapytanie, odpowiedzialność Dappera ogranicza się tylko do mapowania pomiędzy zapytaniami i obiektami w kodzie.

using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools())) 
{ 
      var users = connection.Query("SELECT TOP 10 * FROM Users").ToList();      
      FiddleHelper.WriteTable(users); 
}

W przypadku odczytu mapuje zwrócone wartości na obiekty, odpowiada też za wstawianie wartości z C# do zapytania. To oczywiście zapewnia doskonałą wydajność. Żeby nie było tak różowo to jest też druga strona medalu: jeżeli piszemy zapytania ręcznie to tracimy możliwość wykorzystania LINQ a co za tym idzie łatwiej o błąd. Przez to że Dapper jest odczuwalnie „lżejszy” od Entity Framework jego wydajność jest dużo lepsza. Jest wiele benchmarków potwierdzających jego wydajność np. Dapper vs Entity Framework vs ADO.NET, w każdym z nich jest niewiele wolniejszy od czystego ADO.NET.

Dodatkowym atutem jest to że możemy wykorzystywać oba pakiety Nuget jednocześnie, tj. tam gdzie chcemy mieć całą otoczkę i stanowość użyjmy EF, tam gdzie najważniejszy jest performance użyjmy dappera.

Newtonsoft.Json / Json.NET

JSON czyli JavaScript Object Notation to nieodłączna część pracy każdego programisty nie tylko DotNetowego. Jest oczywiście wiele bibliotek pozwalających na serializację/deserializację obiektów jednak moim zdaniem to ta jest najprostsza w użyciu przy zachowaniu największych możliwości. Najprawdopodobniej to jest powodem tego że często jest najczęściej pobieraną biblioteką na nuget.org. Bibliteka jest stosunkowo lekka, nie posiada zależności poza wczesnym .Net standardem, współpracuje zarówno z frameworkiem jak również z Core/Standard. Użycie jest bardzo proste:

Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Sizes = new string[] { "Small" };

string json = JsonConvert.SerializeObject(product);
// {
//   "Name": "Apple",
//   "Expiry": "2008-12-28T00:00:00",
//   "Sizes": [
//     "Small"
//   ]
// }

deserializacja:

string json = @"{
  'Name': 'Bad Boys',
  'ReleaseDate': '1995-4-7T00:00:00',
  'Genres': [
    'Action',
    'Comedy'
  ]
}";

Movie m = JsonConvert.DeserializeObject<Movie>(json);

string name = m.Name;
// Bad Boys

Podsumowanie

Moim zdaniem powinieneś znać powyższe pakiety Nuget w celu komfortowego programowania w .Net. Jak pisałem na początku nie znaczy to oczywiście że trzeba ich wszystkich używać, ale warto o nich wiedzieć. Pakiety Nuget są extra rozwiązaniem ale oczywiście trzeba zachować umiar w ich stosowaniu, ja osobiście nie wyobrażam sobie żeby zrobić projekt w którym nie użyje żadnego z powyższych. A jaki jest Twój ulubiony pakiet?

Linki:

Porównanie EF i EF core

O autorze

Niepoprawny optymista. 100 pomysłów na sekundę, wielbiciel nowych technologii, nie tylko z rodziny .Net. Często nosi przy sobie jabłko, takie nadgryzione... ;)

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Możesz używać znaczników języka HTML i ich atrybutów: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.

Zamknij