Projektowanie, Programowanie, Codzienność – BeniaminZaborski.com

29 Lipiec 2009

Ugryźć Spring.NET – (Cz.6) Serwisy

Filed under: Ugryźć Spring.Net — Tags: , , , , — Beniamin Zaborski @ 19:58

Współczesne systemy informatyczne to systemy rozproszone, które komunikują się ze sobą na wiele różnych sposobów. U podstaw takiej komunikacji leżą interfejsy, za pomocą których systemy będą się ze sobą komunikować. Interfejsy odgrywają tu rolę fasad i to właśnie je określamy mianem serwisów. Ta część serii będzie traktować właśnie o możliwościach jakie daje nam Spring.NET w kwestii serwisów. O samym wzorcu projektowym Service Layer Martin Fowler pisze tutaj: http://martinfowler.com/eaaCatalog/serviceLayer.html.

W świecie .NET mamy do dyspozycji kilka różnych technologii pozwalających budować i publikować nam serwisy jak: .NET Remoting, WebServices, Enterprise Services czy wreszcie WCF.

Na etapie projektu aplikacji często nie wiemy lub nie chcemy się zajmować takimi konkretami jak technologia, której użyjemy do budowy naszych serwisów. Na tym etapie podchodzimy do serwisów w sposób bardziej abstrakcyjny. Jednak przychodzi moment, gdy musimy się zdecydować na któreś z rozwiązań. Załóżmy, że w pierwszej kolejności wybieramy .NET Remoting, ale po dłuższym zastanowieniu stwierdzamy jednak, że nasze serwisy będą wystawione na świat w postaci WebService i hostowane na serwerze IIS. Taka zmiana wymagać będzie od nas pewnego nakładu pracy i często wprowadza lekkie zamieszanie. A co gdyby tylko na poziomie konfiguracji określać jaką technologią nasze serwisy mają być hostowane? Brzmi świetnie!!!
Tu z pomocą przychodzi Spring.NET, a właściwie cały mechanizm eksporterów serwisów w Spring.NET.
Spring.NET wprowadza kolejną warstwę abstrakcji – eksportera serwisu. Obsługuje wszystkie wymienione wcześniej technologie eksportowania serwisów. Cała konfiguracja, która pozwoli nam wyeksportować serwis jest zupełnie banalna.

Zacznijmy od zdefiniowania dosłownie interfejsu naszego serwisu IAbonenciService.


public interface IAbonenciService
{
  IList<AbonentDTO> PobierzListeAbonentow();
}

Mamy bardzo prosty interfejs serwisu tylko z jedną metodą, teraz czas na jego implementację.


public class AbonenciService : IAbonenciService
{
  #region DAOs

  private AbonentDAO abonentDAO;
  public AbonentDAO AbonentDAO
  {
    get { return abonentDAO; }
    set {abonentDAO = value; }
  }

  #endregion DAOs

  public IList<AbonentDTO> PobierzListeAbonentow()
  {
    IList<AbonentDTO> listaAbonentow = new List<AbonentDTO>();
    foreach(Abonent abonent in AbonentDAO.PobierzListeAbonentow())
      listaAbonentow.Add(AbonentConverter.ToAbonentDTO(abonent));
    return listaAbonentow;
  }
}

Przedstawiłem prostą implementację serwisu, odwołująca się do obiektu DAO jak i obiektu konwertera. Oczywiście instancje obu tych obiektów możemy sobie wstrzyknąć poprzez kontener IoC Springa.

Dodać należy, że dobrym rozwiązaniem będzie umieszczenie interfejsu serwisu w osobnym assembly, np. BeezDev.ExampleSpringApp.Model.Interface, a implementacji w osobnym, np. BeezDev.ExampleSpringApp.Model. Dzięki temu aplikacja klienta będzie posiadała jawną referencję tylko do assembly z interfejsem, a nie implementacją serwisu.

Spróbujmy opublikować nasz serwis poprzez .NET Remoting. Nie będę opisywał szczegółów samej technologii .NET Remoting, bo moim celem jest pokazanie jedynie integracji Spring.NET z .NET Remoting. W sprawie konfiguracji kanałów, portów, aktywacji obiektów (SAO, SAO Singleton, CAO) odsyłam do dokumentacji.

Na pierwszy ogień konfiguracja po stronie serwera. Załóżmy, że nasz serwis hostujemy w zwykłej aplikacji .NET uruchamianej w postaci usługi Windows. Konfiguracja Spring.NET wyglądać będzie następująco:


<object id=”abonentDAO” type=”BeezDev.ExampleSpringApp.Model.AbonentDAO, BeezDev.ExampleSpringApp.Model”>
</object>

<object id=”abonenciService” type=”BeezDev.ExampleSpringApp.Model.AbonenciService, BeezDev.ExampleSpringApp.Model”>
  <property name=”AbonentDAO” value=”abonentDAO” />
</object>

<object name=”saoSingletonAbonenciService ” type=”Spring.Remoting.SaoExporter, Spring.Services”>
  <property name=”TargetName” value=” abonenciService” />
  <property name=”ServiceName” value=”AbonenciService” />
</object>

Co widzimy? Na początek wspomniany wcześniej obiekt typu DAO, dalej definicja serwisu i wstrzyknięcie instancji obiektu DAO. Najciekawsze na koniec – eksport serwisu poprzez .NET Remoting jako SAO Singleton. Właściwość TargetName wskazuje na definicję serwisu, a ServiceName określa nazwę pod jaką będzie widoczny nasz serwis.

To prawie wszystko! Prawie bo reszta to już tylko konfiguracja .NET Remoting, tj.


<system.runtime.remoting>
  <application>
    <channels>
      <channel ref=”tcp” port=”8008″ />
    </channels>
  </application>
</system.runtime.remoting>

Po stronie aplikacji klienta konfiguracja jest równie prosta:


<object id=”abonenciService” type=”Spring.Remoting.SaoFactoryObject, Spring.Services”>
  <property name=”ServiceInterface” value=”BeezDev.ExampleSpringApp.Model.IAbonenciService, BeezDev.ExampleSpringApp.Model.Interface” />
  <property name=”ServiceUrl” value=”tcp://localhost:8008/AbonenciService” />
</object>

Pobranie naszego serwisu po url-u, gdzie protokół (tcp) i port (8008) zdefiniowaliśmy w konfiguracji Remotingu po stronie serwera oczywiście. Nazwa serwisu w url to ta którą podaliśmy w ServiceName.

Konfiguracja .NET Remoting po stronie klienta:


<system.runtime.remoting>
  <application>
    <channels>
      <channel ref=”tcp”/>
    </channels>
  </application>
</system.runtime.remoting>

Oto cała konfiguracja, teraz możemy pobrać po stronie klienta instancję serwisu, przy założeniu że aplikacja serwera hostująca nasz serwis jest uruchomiona.


IApplicationContext ctx = ContextRegistry.GetContext();
IAbonenciService abonenciService = (IAbonenciService)ctx.GetObject(„abonenciService”);
IList<AbonentDTO> listaAbonentow = abonenciService.PobierzListeAbonentow();

To wszystko i działa! Jeśli zdecydujemy opublikować nasz serwis za pomocą innej technologii praktycznie wszystkie zmiany jakich musimy dokonać ograniczą się do zmian exportera w plikach konfiguracyjnych. Po szczegóły związane z serwisami w Spring.NET odsyłam tradycyjnie do dokumentacji projektu.

Dodaj komentarz »

Brak komentarzy.

RSS feed for comments on this post. TrackBack URI

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Log Out / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Log Out / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Log Out / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Log Out / Zmień )

Connecting to %s

Stwórz darmową stronę albo bloga na WordPress.com.

%d bloggers like this: