fbpx
devstyle.pl - Blog dla każdego programisty
devstyle.pl - Blog dla każdego programisty
3 minut

Obsługa wyjątków w usługach WCF


08.12.2009

Projektanci WCF zostawili w swoim produkcie bardzo dużo półprzymkniętych furtek czekających tylko na odkrycie i wykorzystanie ich potencjału. Jednym z takich czarodziejskich otworów do przyjemnego, różowego, miękkiego wnętrza WCF jest infrastruktura Behaviors (więcej o, między innymi, nich, na przykład w artykule “Extending WCF with Custom Behaviors“). Z ich pomocą można osiągnąć baaardzo wiele, między innymi: w niesamowicie elegancki sposób zebrać w jednym miejscu wszystkie błędy wygenerowane przez naszą warstwę usług. Wystarczy zaimplementować interfejs IErrorHandler… i wsio! Ja połączyłem implementację dwóch interfejsów w jednej klasie tak, aby całą logikę odpowiedzialną za umieszczanie “łapacza wyjątków” zawrzeć obok siebie. I wygląda to tak:

  1:  public class ErrorHandlingBehavior : IServiceBehavior, IErrorHandler
  2:  {
  3:  	public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
  4:  	{
  5:  		var faultExc = new FaultException(error.Message);
  6:  		var messageFault = faultExc.CreateMessageFault();
  7:  		fault = Message.CreateMessage(version, messageFault, faultExc.Action);
  8:  	}
  9:  
 10:  	public bool HandleError(Exception error)
 11:  	{
 12:  		EventLog.WriteEntry("ProcentSampleWcfApp", error.ToString(), EventLogEntryType.Error);
 13:  		return false;
 14:  	}
 15:  
 16:  	public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
 17:  	{
 18:  	}
 19:  
 20:  	public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
 21:  	{
 22:  	}
 23:  
 24:  	public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
 25:  	{
 26:  		foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
 27:  		{
 28:  			channelDispatcher.ErrorHandlers.Add(this);
 29:  		}
 30:  	}
 31:  }

Dwie pierwsze metody odpowiedzialne są za czynności związane z wyjątkami. Pierwsza, ProvideFault(…),  ma za zadanie podmienić faktyczny wyjątek na strukturę, którą życzymy sobie wysłać do klienta. W tym przypadku jest to obudowanie odpowiednich informacji w wyjątek WCF, FaultException… a implementacja zerżnięta z książki “Programming WCF Services“. Metoda ta powinna być jak najbardziej wydajna, ponieważ wykonywana jest synchronicznie. Inaczej sprawa się przedstawia w przypadku drugiej dzidzi, HandleError(…). To maleństwo z kolei ma za zadanie zrobić z wyjątkiem COKOLWIEK, w domyśle: zalogować. W powyższej implementacji wrzucam informację o błędzie do event logu.

Pozostałe metody to (w większości pusta) implementacja interfejsu definiującego zachowanie usługi. O tym rozpisywać się nie będę, zainteresowani bez problemu znajdą szczegółowy opis możliwych do wykonania czynności w internecie.

Zaaplikowanie takiego mechanizmu do naszej usługi wygląda w kodzie tak:

  1:  host.Description.Behaviors.Add(new ErrorHandlingBehavior());
  2:  host.Open();

I… to tyle. Mamy również możliwość stworzenia własnego atrybutu o identycznej implementacji i aplikacji go bezpośrednio na klasę usługi, efekt będzie ten sam.

Na koniec wspomnieć należy o banalnej wręcz integracji EntLibowego bloku EHAB z WCF. Jeśli korzystasz z tego mechanizmu (serio?) to polecam zapoznanie się z artykułem “Shielding Exceptions at WCF Service Boundaries” na MSDN.

0 0 votes
Article Rating
2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Kurs Gita

Zaawansowany frontend

Szkolenie z Testów

Szkolenie z baz danych

Książka

Zobacz również