Invest in people before investing in tools

Il blog di Matteo Baglini
posts - 118, comments - 95, trackbacks - 697

[Spring.NET #29] Spring.Core, Loosely Coupled Event Wiring

Grazie al motore di IoC, Spring.NET offre la funzionalità di Loosely Coupled Event Wiring, vale a dire la possibilità di scatenare ed intercettare eventi senza un legame diretto fra il publisher ed il subscriber. Il meccanismo avviene grazie ad un Registry mantenuto da Spring.NET, dentro al quale il publisher registra i propri aventi, rendendoli pubblici, a questo punto il subscriber potrà "dire" a Spring.NET quale eventi sottoscrivere. Passiamo subito ad un esempio pratico, creiamo una ConsoleApplication ed aggiungiamo la reference a Spring.Core.dll. Procediamo con l'oggetto publisher, come prima cosa aggiungiamo una classe CustomEventArgs, la quale sarà utilizzata nell'evento scatenato dalla classe EventPublisher:

   1: using System;
   2:  
   3: namespace SpringSeries.Core.EventWiring
   4: {
   5:     public class CustomEventArgs : EventArgs
   6:     {
   7:         private string _eventMessage;
   8:  
   9:         public CustomEventArgs(string eventMessage)
  10:         {
  11:             _eventMessage = eventMessage;
  12:         }
  13:  
  14:         public string EventMessage
  15:         {
  16:             get { return _eventMessage; }
  17:         }
  18:     }
  19: }

dopo creiamo la classe EventPublisher, la quale espone l'evento SimpleEvent:

   1: using System;
   2:  
   3: namespace SpringSeries.Core.EventWiring
   4: {
   5:     public delegate void SimpleEvent(object sender, CustomEventArgs args);
   6:  
   7:     public class EventPublisher
   8:     {
   9:         private string _publisherName;
  10:  
  11:         public event SimpleEvent _simpleEvent;
  12:  
  13:         public EventPublisher()
  14:         {
  15:         }
  16:  
  17:         public string PublisherName
  18:         {
  19:             get { return _publisherName; }
  20:             set { _publisherName = value; }
  21:         }
  22:  
  23:         public void RaiseSimpleEvent()
  24:         {
  25:             if (_simpleEvent != null)
  26:                 _simpleEvent(this, new CustomEventArgs("SimpleEvent raised from " + _publisherName));
  27:         }
  28:     }
  29: }

Fatto il publisher passiamo alla creazione della classe che farà da subscriber, EventSubscriber. Questa classe deve avere un metodo con la stessa firma dell'evento che vuote intercettare:

   1: using System;
   2:  
   3: namespace SpringSeries.Core.EventWiring
   4: {
   5:     public class EventSubscriber
   6:     {
   7:         private bool _eventHandled = false;
   8:  
   9:         public EventSubscriber()
  10:         {
  11:         }
  12:  
  13:         public void HandleSimpleEvent(object sender, CustomEventArgs args)
  14:         {
  15:             Console.WriteLine("Handled SimpleEvent event with args: " + args.EventMessage);
  16:             _eventHandled = true;
  17:         }
  18:  
  19:         public bool EventHandled
  20:         {
  21:             get { return _eventHandled; }
  22:         }
  23:     }
  24: }

Configuriamo il publisher ed il subscriber all'interno del file di configurazione:

<objects xmlns="http://www.springframework.net">
  <object name="MyEventPublisher" 
          type="SpringSeries.Core.EventWiring.EventPublisher, 21.EventWiring" 
          singleton="false">
    <property name="PublisherName" value="Matteo event publisher" />
  </object>
  <object name="MyEventSubscriber" 
          type="SpringSeries.Core.EventWiring.EventSubscriber, 21.EventWiring" 
          singleton="false" />
</objects>

Nel corpo del metodo Main registriamo l'evento SimpleEvent della classe EventPublisher in maniera programmatica, grazie al metodo PublishEvents dell' ApplicationContext. Creaiamo due istanze di EventSubscriber e registriamo solo la prima come subscriber. La sottoscrizione avviene grazie al metodo Subscribe dell' ApplicationContext.

   1: using System;
   2: using Spring.Context;
   3: using Spring.Context.Support;
   4:  
   5: namespace SpringSeries.Core.EventWiring
   6: {
   7:     public sealed class Program
   8:     {
   9:         [STAThread]
  10:         public static void Main()
  11:         {
  12:  
  13:             IApplicationContext _ctx = ContextRegistry.GetContext();
  14:  
  15:             EventPublisher _publisher = (EventPublisher)_ctx.GetObject("MyEventPublisher");
  16:             // registro nel context gli eventi dell'oggetto EventPublisher
  17:             _ctx.PublishEvents(_publisher);
  18:  
  19:             EventSubscriber _subscriber1 = (EventSubscriber)_ctx.GetObject("MyEventSubscriber");
  20:             EventSubscriber _subscriber2 = (EventSubscriber)_ctx.GetObject("MyEventSubscriber");
  21:             // registro nel context che il subscriber1 sottoscrive gli eventi dell'oggetto EventPublisher
  22:             _ctx.Subscribe(_subscriber1, typeof(EventPublisher));
  23:  
  24:             Console.WriteLine("Publisher name: " + _publisher.PublisherName);
  25:             
  26:             Console.WriteLine("Subscriber 1 Event Handled: " + _subscriber1.EventHandled);
  27:             Console.WriteLine("Subscriber 2 Event Handled: " + _subscriber2.EventHandled);
  28:  
  29:             // raises a publisher event...
  30:             _publisher.RaiseSimpleEvent();
  31:  
  32:             Console.WriteLine("Subscriber 1 Event Handled: " + _subscriber1.EventHandled);
  33:             Console.WriteLine("Subscriber 2 Event Handled: " + _subscriber2.EventHandled);
  34:  
  35:             Console.Read();
  36:         }
  37:     }
  38: }
Technorati Tag:

Print | posted on domenica 9 marzo 2008 14:40 | Filed Under [ .NET OpenSource Spring.NET ]

Powered by:
Powered By Subtext Powered By ASP.NET