Dzięki stworzeniu swojej własnej biblioteki można nie tylko wesprzeć społeczność open source, ale również nauczyć się wielu przydatnych rzeczy. Co ważne, gdy już projekt będzie gotowy jest duża szansa, że znajdą się ludzie chętni do pomocy w rozwoju!
Zanim zaczniemy kodować musimy najpierw znaleźć API, do którego chcielibyśmy napisać bibliotekę. Może to być jakieś narzędzie, z którego korzystamy, żeby biblioteka również służyła nam.
A co jeśli nie mamy takiego API? Mogę polecić kilka dobrze udokumentowanych API
Jednak te API mają już swoje biblioteki w C#. Zamiast tego proponuje jedno z tych zabawnych API, które jeszcze czekają na swoje biblioteki:
Jeśli ciągle brakuje inspiracji, to polecam zerknąć na jeszcze więcej publicznych API.
Zróbmy najpierw repozytorium na GitHub dla naszego projektu. Wystarczy, że wejdziemy na stronę GitHuba (oczywiście musimy mieć konto), klikniemy + i New repository
Otworzy się przed nami formularz, w którym należy uzupełnić pola::
.gitignore
- automatycznie generuje nam plik .gitignore
. Zalecam wybrać opcje “Visual Studio”, która doda domyślne katalogi z C# i Visual Studio.Wystarczy kliknąć Create repository i gotowe!
Czas sklonować nasze repozytorium przy użyciu ulubionego klienta gita. Link można znaleźć na stronie projektu w tym miejscu.
Lub użyć konsoli
git clone https://github.com/Morasiu/CatFacts.Net.git
Jeśli ciągle masz problem z tworzeniem lub klonowaniem projektu zerknij na pomoc GitHub.
Teraz stwórzmy projekt naszej biblioteki. Najłatwiej użyć do tego Visual Studio i wybrać “Biblioteka klas (.NET Standard)”:
Ewentualnie można to zrobić za pomocą konsoli:
dotnet new sln -n CatFacts.Net
dotnet new classlib -n CatFacts.Net
Dzięki temu, że projekt jest przeznaczony na .Net Standard będzie można go używać w każdym innym projekcie. Niezależnie czy to .Net Core, .Net Framework czy Xamarin itp.
Następnie musimy wybrać bibliotekę do łączenia się z API. Zajmie się ona niskopoziomowymi rzeczami i znacznie przyśpieszy proces tworzenia. W C# mamy kilka wiodących narzędzi do tego:
W tym przykładzie użyjemy RestSharp, ale zachęcam do wybrania narzędzia, które najbardziej Wam pasuje.
Aby dodać RestSharp do projektu możemy znowu posłużyć się Visual Studio:
Alternatywnie możemy użyć konsoli do tego:
dotnet add package RestSharp
Projekt gotowy, czas rozpocząć tworzenie!
Na początku sprawdźmy jakie endpointy musimy zrobić, żeby nasza biblioteka miała sens. Skorzystamy z przykładu Cat facts API.
Jak widać są dwie listy endpointów, /facts
i /users
.
Nie trzeba wspierać wszystkich endpointów. Wystarczy, że na początek będziemy wspierać tylko te główne.
Zacznijmy od napisania naszej głównej klasy CatFactsClient
.
using RestSharp;
namespace CatFacts.Net {
public class CatFactsClient {
private RestClient _restClient;
public CatFactsClient() {
_restClient = new RestClient("https://cat-fact.herokuapp.com");
}
}
}
Jak widać jest to dość prosta klasa. Stworzyliśmy podstawę do naszego klient. W środku jest nasz wewnętrzny REST klient którego będziemy używać do wysyłania zapytań do API.
Jeśli API, którego używamy ma wiele endpointów i nasz klient robi się rozdęty możemy podzielić go na tzw. Partial classes.
W końcu czas na napisanie pierwszej metody do API, które wybraliśmy. Głównym wykorzystaniem Cats Facts API jest uzyskiwanie losowych faktów o kotach, więc zacznijmy od napisania metody do endpointu GET /facts/random
. Ten endpoint zwraca listę modeli Facts, więc musimy zrobić odpowiednik modelu w klasie C#. W dokumentacji widzimy, że model Fact wygląda tak:
Jego odpowiednik w klasie C# powinien wyglądać tak:
namespace CatFacts.Net.Models {
public class Fact {
[JsonProperty("_id")]
public string Id { get; set; }
[JsonProperty("__v")]
public int? V { get; set; }
public string User { get; set; }
public string Text { get; set; }
public DateTime? UpdatedAt { get; set; }
public DateTime? SendDate { get; set; }
public bool? Deleted { get; set; }
public Source? Source { get; set; }
public bool? Used { get; set; }
public string Type { get; set; }
}
public enum Source {
User,
Api
}
}
Możemy też skopiować opis każdego pola z dokumentacji i dodać je w ten sposób w komentarzach XML.
/// <summary>
/// Unique ID for the Fact
/// </summary>
[JsonProperty("_id")]
public string Id { get; set; }
Dzięki temu nikt nie będzie się zastanawiał czym jest każde pole.
W końcu czas napisać metodę do klasy CatFactsClient
. Jak widzimy endpoint zwraca listę faktów, więc również to powinna zwracać nasza metoda.
public List<Fact> GetRandomFacts() {
}
Wysłanie zapytania przy użyciu RestSharp jest bardzo proste. Wystarczy kilka linijek.
public List<Fact> GetRandomFacts() {
var request = new RestRequest("/facts/random");
var facts = _restClient.Get<List<Fact>>(request);
return facts.Data;
}
Dobrą praktyką w C# przy robienie metod, które łączą się z zewnętrznymi usługami (np. Baza danych, API itp.) jako asynchroniczne. Dzięki czemu nie będą blokować wątków UI w aplikacjach graficznych np. WPF. Szybkie przerobienie na metody na asynchroniczną wygląda tak:
public Task<List<Fact>> GetRandomFactsAsync() {
var request = new RestRequest("/facts/random");
var facts = _restClient.GetAsync<List<Fact>>(request);
return facts;
}
Jak widać nie zmieniło się dużo.
Task<>
Async
_restClient.Get
na _restClient.GetAsync
I nasza implementacja w wersji podstawowej jest gotowa. Ale w dokumentacji widzimy, że można jeszcze dodać query parameters.
Nowa wersja ze wsparciem parametrów wygląda tak:
public Task<List<Fact>> GetRandomFactsAsync(int amount = 1, params string[] animalTypes) {
var request = new RestRequest("/facts/random");
request.AddQueryParameter("amount", amount.ToString());
request.AddQueryParameter("animal_type", string.Join(",", animalTypes));
var facts = _restClient.GetAsync<List<Fact>>(request);
return facts;
}
I gotowe. Tylko skąd wiemy, że to w ogóle działa? Najlepiej sprawdzić to poprzez napisanie testów.
Każdy dobry projekt powinien mieć testy. W dzisiejszych czasach mamy do wyboru wiele świetnych frameworków do testów np. xUnit, NUnit. Dla przykłady wybierzmy tutaj NUnit.
Zacznijmy od stworzenia nowego projektu testowego. Kolejny raz możemy użyć do tego Visual Studio. Najpierw wybieramy Add -> New Project...
I następnie wybieramy NUnit Test Project
Nazwijmy go CatFacts.Net.Tests.
Jeszcze tylko dodajmy referencje do naszego głównego projektu. Klikamy na Add -> Project References.
Zaznaczamy checkbox przy CatFacts.Net, klikamy Ok i gotowe!
Gdy zerkniemy teraz do naszego projektu testowego naszym oczom ukaże się czysta klasa testowa. Po drobnych zmianach i usunięciu niepotrzebnych rzeczy powinniśmy mieć taką czystą klasę:
using NUnit.Framework;
namespace CatFacts.Net.Tests {
public class CatFactsClientTests {
[Test]
public void Test1() {
Assert.Pass();
}
}
}
Nazwijmy nasz test nieco lepiej niż Test1. Jest wiele konwencji nazywania testów. Osobiście preferuję:
NazwaMetody_WarunkiLubDane_ShouldCoPowinnaZrobić
Więc zgodnie z tą konwencją test powinien nazywać się:
[Test]
public void GetRandomFactsAsync_WithoutQueryParameters_ShouldReturnFactsList() {
}
Nie należy się przejmować długimi nazwami. Lepiej, żeby nazwa była długa, niż żeby zawierała za mało informacji.
W końcu możemy napisać nasz test. W najprostszej formie będzie wyglądać tak:
[Test]
public async Task GetRandomFactsAsync_WithoutQueryParameters_ShouldReturnFactsList() {
// Arrange
var client = new CatFactsClient();
// Act
var facts = await client.GetRandomFactsAsync();
// Assert
Assert.NotNull(facts);
}
Znaczące zmiany tutaj to:
async
I nasz pierwszy uproszczony test jest gotowy!
W końcu nadszedł czas udostępnienia naszego pakietu. Zacznijmy od zmiany wersji we Właściwościach projektu. Można je znaleźć tutaj.
Klikamy prawy przyciskiem myszy na projekt, a następnie na Properties. Ukaże nam się nowe okno. Należy tam przejść do Package.
Następnie należy tam zmienić kilka rzeczy
Oczywiście na końcu zapisać zmiany!
Projekt gotowy. Czas na build. Najpierw zmieńmy konfiguracje z Debug na Release
Teraz czas zrobić paczkę NuGet. Wystarczy w menu kontekstowym (po kliknięciu prawym przyciskiem myszy na projekt) wybrać opcje Pack.
Naszą paczkę znajdziemy w KatalogProjektu/bin/Release. Powinna być nazwana NazwaProjektu.0.1.0.nupkg. W moim przypadku to CatFacts.Net.0.1.0.nupkg.
Tylko co teraz zrobić z taką paczką?
Udało nam się stworzyć działającą bibliotekę i wrzucić ją GitHub oraz NuGet. Co teraz? Zachęcam do pochwalenia się nią na różnych platformach. Np.
Dzięki temu ktoś skorzysta z naszej paczki, a może nawet pomoże ją rozwijać. Możemy też poprosić innych programistów o swoje opinie o naszym kodzie co pozwoli nam zostać jeszcze lepszymi programistami!
PS: Cały przykładowy projekt CatFacts.Net można zobaczyć tutaj. A jeśli chcesz zobaczyć nieco bardziej rozbudowany przykład to zapraszam do zerknięcia do mojej autorskiej biblioteki tutaj.