Artykuł

freeimages.com freeimages.com
sie 14 2016
0

DependencyService w Xamarin.Forms

Xamarin.Forms to rozwiązanie multiplatformowe, dlatego też musi ono posiadać narzędzia, które ułatwiają development na kilka różnych systemów jednocześnie. We wcześniejszych tekstach poruszyłem już kilka zagadnień z tego zakresu, a były to m.in.:

Twórcy Xamarina przygotowali jednak znacznie większą paletę rozwiązań z których możemy skorzystać na co dzień. Do tych najważniejszych oprócz powyższych, zaliczyłbym jeszcze:

  • Wbudowany w system mechanizm DependencyService
  • Efekty
  • Statyczną klasę Device

W kolejnych wpisach postaram się nadrobić zaległości w tym temacie. Dziś zacznę od wbudowanej w Xamarin.Forms klasy DependencyService.

DepdendencyService

Xamarin.Forms pozwala na współdzielenie sporej ilości kodu pomiędzy poszczególnymi systemami, ale mimo tego wciąż będą się zdarzać sytuacje, w których będziemy musieli napisać usługi pod dedykowane systemy. W pewnych specyficznych sytuacjach można by użyć w tym celu projektu typu shared i dyrektyw preprocessora. Ale bądźmy szczerzy - takie rozwiązanie jest skrajnie brzydkie, a poza tym z góry powstrzymuje nas przed modularnością w jakiekolwiek postaci. Takie rozwiązanie może sprawdzić się w prostych, jednorazowych projektach.

Na szczęście Xamarin out-of-the-box oferuje znacznie lepsze wyjście, a jest nim namiastka IoC wprowadzona w postaci klasy DependencyService. Zastosowanie tego mechanizmu w przypadku Xamarin.Forms jest niezwykle proste i sprowadza się do:

  • Utworzenia interfejsu w części wspólnej
  • Utworzenia klas implementujących ten interfejs w projektach dla poszczególnych systemów
  • Udekorowania wspomnianych wyżej klas odpowiednim atrybutem

W praktyce jest to bardzo łatwe, co też postaram się zademonstrować w prostym przykładzie.

Przykład praktyczny

Przykład będzie bardzo krótki. Zaczniemy od utworzenia w części wspólnej naszej solucji, prostego interfejsu:

public interface IMessengerService
{
	string GetString();
}

Zawierać on będzie tylko jedną metodę, która będzie zwracać prosty string - inny w zależności od systemu. W rzeczywistości takie założenie moglibyśmy zrealizować na kilka różnych sposobów, ale możemy sobie teraz wyobrazić, że nasz interfejs jest dużo bardziej złożony..

W kolejnym kroku musimy utworzyć konkretne implementacje. Poniżej przykładowy kod serwisu dla Androida:

using Xamarin.Forms;

[assembly: Dependency(typeof(DroidMessengerService))]
namespace DependencyServiceTest.Droid
{
	public class DroidMessengerService : IMessengerService
	{
		public string GetString()
		{
			return "Komunikat z serwisu dla Androida!";
		}
	}
}

Sama implementacja nie powinna nastręczać problemów ze zrozumieniem;) Esencją w tym przypadku jest atrybut przypięty do namespace'a, który pozwala na zarejestrowanie naszej usługi w Xamarinie. Xamarin automatycznie wykrywa dla jakiego interfejsu jest ona przypisana. Serwisy dla pozostałych systemów możemy utworzyć w analogiczny sposób.

Użycie takiego zarejestrowanego serwisu jest równie łatwe. Wystarczy w dowolnym miejscu w części wspólnej wywołać kod zbliżony do tego poniżej:

var msgService = DependencyService.Get<IMessengerService>();
string str = msgService.GetString();

Uwaga na linkowanie

Przy wykorzystywaniu konstrukcji operujących na atrybutach w Xamarinie, trzeba upewnić się, że określona klasa na pewno zostanie zlinkowana. Dlatego też warto sprawdzić ustawienia linkera - najlepiej jest w tym przypadku użyć opcji Link SDK Assemblies. Opcjonalnie można pokusić się również o użycie atrybutu Preserve.

Alternatywy

W przypadku rozwiniętych projektów, prawdopodobnie lepiej będzie skorzystać z bardziej złożonych bibliotek. Osobiście używam Autofaca, który zapewnia znacznie lepszą kontrolę w kwestii czasu życia obiektów. W jednym z kolejnych wpisów postaram zaprezentować się jej zastosowanie w kontekście Xamarina.

Podoba Ci się ten wpis? Powiedz o tym innym!

Send to Kindle

Komentarze

blog comments powered by Disqus