﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2021 (c) 2026</copyright><ttl>60</ttl><item><title>Hendry Luk commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>I think i might have decipher out how code-formatting works on your blog. So, second attempt:

	public class CargoProcessor : IEventProcessor
	{
		void IEventProcessor.Execute(IObservable&lt;object&gt; events)
		{
			events.OfType&lt;Cargo&gt;
			.Where(cargo =&gt; cargo.Delivery.Misdirected)
			.Subscribe(MisdirectedCargo);
			
			events.OfType&lt;Cargo&gt;
			.Where(cargo =&gt; cargo.Delivery.UnloadedAtDestination)
			.Subscribe(CaroArrived);
		}

		private void CaroArrived(Cargo cargo)
		{
			// handle event
		}

		private void MisdirectedCargo(Cargo cargo)
		{
			// handle event
		}
	}</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment21</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment21</guid><pubDate>Sat, 11 Feb 2012 03:49:34 GMT</pubDate></item><item><title>Ayende Rahien commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>Hendry,
I like the base class approach better, it allows me to remove the infrastructure concerns out.</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment20</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment20</guid><pubDate>Sat, 11 Feb 2012 03:49:07 GMT</pubDate></item><item><title>Hendry Luk commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>Wouldn't the behavior remain exactly the same if it is written as the following?

(I have a feeling the generic syntax is gonna get stripped by your blog)

public class CargoProcessor : IEventProcessor
{
    void IEventProcessor.Execute(IObservable&lt;object&gt; events)
    {
        events.OfType&lt;Cargo&gt;
		.Where(cargo =&gt; cargo.Delivery.Misdirected)
		.Subscribe(MisdirectedCargo);
		
		events.OfType&lt;Cargo&gt;
		.Where(cargo =&gt; cargo.Delivery.UnloadedAtDestination)
		.Subscribe(CaroArrived);
    }

    private void CaroArrived(Cargo cargo)
    {
        // handle event
    }

    private void MisdirectedCargo(Cargo cargo)
    {
        // handle event
    }
}

Wouldn't that do exactly the same thing? I just dont understand the purpose of all the moving components involved in the base-class.</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment19</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment19</guid><pubDate>Sat, 11 Feb 2012 03:46:50 GMT</pubDate></item><item><title>Ayende Rahien commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>Hendry,
how would you discover that? 
where would you put it?

This way, you split the event processing and the event submission. </description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment18</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment18</guid><pubDate>Sat, 11 Feb 2012 03:31:35 GMT</pubDate></item><item><title>Hendry Luk commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>Also, i dont understand the purpose of the base class here. Why dont you just write that cargo subsciption logic in the Execute method directly? Rather than doing it in the constructor, keeping the logic in the list to be executed later during Execute, etc, hence requiring a base class. It does not seem to add any value. This could have been a simple single-method interface implementation, no?</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment17</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment17</guid><pubDate>Sat, 11 Feb 2012 03:13:46 GMT</pubDate></item><item><title>Hendry Luk commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>Ayende, i think what steve meant was using the standard rx methods (Where, Subscribe, etc, which also includes grouping, joining, and so on). I.e. its not a random Where method that you write yourself</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment16</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment16</guid><pubDate>Sat, 11 Feb 2012 03:05:45 GMT</pubDate></item><item><title>Nick commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>I think the older version was much easier to read. I understood exactly what was going on the first time I read it. Whether or not that is the best long-term approach I don't know - "just sayin".</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment15</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment15</guid><pubDate>Fri, 10 Feb 2012 22:07:34 GMT</pubDate></item><item><title>Mike Bild commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>I like this idea. Hold your processor logic nearly your handler impl. My suggestion would be, change the handler return type to Unit instead of object. This solves ugly Null stuff.

you can simplify the processor to:

 public class EventsProcessor
    {
        private readonly Subject&lt;object&gt; _subject = new Subject&lt;object&gt;();
        protected void On&lt;T&gt;(Func&lt;IObservable&lt;T&gt;, IObservable&lt;Unit&gt;&gt; action)
        {
            action(_subject.OfType&lt;T&gt;())
                .Subscribe();
        }

        public void Execute(IObservable&lt;object&gt; observable)
        {
            observable
                .Multicast(_subject)
                .Connect();
        }
    }

...and I would rename Execute to Connect or StartProcessor.</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment14</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment14</guid><pubDate>Fri, 10 Feb 2012 21:07:41 GMT</pubDate></item><item><title>JarrettV commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>Ayende, can you contrast this approach with Domain Events?

http://www.udidahan.com/2009/06/14/domain-events-salvation/</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment13</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment13</guid><pubDate>Fri, 10 Feb 2012 20:22:18 GMT</pubDate></item><item><title>Ayende Rahien commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>Steve,
Now try to do that on a more complex statement. Maybe something that has a grouping, etc.

But that is basically the same idea, yes. I would drop the On() entirely and do something like:

Where(carge=&gt;cargo.Delivery.Misdireted)
 .Subscribe(MisdrectedCargo); 

Where(carge=&gt;cargo.Delivery.Late) 
  .Subscribe(LateCargo); 

Etc.</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment12</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment12</guid><pubDate>Fri, 10 Feb 2012 14:27:59 GMT</pubDate></item><item><title>Steve Wagner commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>On&lt;Cargo&gt;()
  .Where(carge=&gt;cargo.Delivery.Misdireted)
  .Subscribe(MisdrectedCargo);

Wouldnt this be better? This would remove the ugly return Null and seems to be more clear in what happens.</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment11</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment11</guid><pubDate>Fri, 10 Feb 2012 14:23:45 GMT</pubDate></item><item><title>Omer Mor commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>Using the Rx approach you also gain elegant options for filtering (based on time like sampling and throttling, or based on data like you use did), projections (e.g turning a cargo event stream into an invoice event stream), and more.
The LINQ model is a perfect fit for event processing.</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment10</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment10</guid><pubDate>Fri, 10 Feb 2012 14:07:16 GMT</pubDate></item><item><title>Ayende Rahien commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>Bil,
Nothing prevents you from having multiple event processors. In fact, you would probably have them.
The only difference is that you would put related stuff nearby, to make it easier to follow and maintain.</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment9</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment9</guid><pubDate>Fri, 10 Feb 2012 14:04:50 GMT</pubDate></item><item><title>Frank Quednau commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>@bil, nothing is looped here, it is more comparable to event subscription, with a new cargo instance being the event.</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment8</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment8</guid><pubDate>Fri, 10 Feb 2012 13:54:15 GMT</pubDate></item><item><title>Bil Simser commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>Okay, ignoring the LINQ performance (not sure why my LINQ statements are crap but that's another issue) I can see the clarity in the refactoring now. 

I'm not familiar with the reactive extensions but it almost looks like a more simplified version of Udi Dahan's domain event pattern (http://www.udidahan.com/2009/06/14/domain-events-salvation/). Nice. 

My only question is would CargoProcessor handle any kind of processing or when do you decide to split the system and come up with something that doesn't result in 10 On&lt;Cargo&gt; statements.</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment7</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment7</guid><pubDate>Fri, 10 Feb 2012 13:48:16 GMT</pubDate></item><item><title>Ayende Rahien commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>Bil,
30,000 items is nothing. And Linq isn't slow. It is basically method calls, so there is nothing there to _be_ slow.
The linq approach is the same exact thing as the previous one, sure, that is the point. It is a refactoring, after all.
What we are doing it trying to get to better code. And I think this is clearer and more maintainable over the long run</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment6</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment6</guid><pubDate>Fri, 10 Feb 2012 13:31:09 GMT</pubDate></item><item><title>Bil Simser commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>Hmm. I really don't like the CargoProcessor. Two problems. First, LINQ can be slow(ish) sometimes. On a simple select I don't think there's an issue here (grouping can be craptastic). However (and I'm no expert here) isn't CargoProcessor looping through cargos twice? What if this was a real-world shipping app and I was going through 30,000 items in my warehouse? 

I prefer the delegation in previous posts where the determination was done as the individual entity came in then got farmed out to a separate class. 

The other problem that's staring me in the face is that if I go back to the original code that started this thread, it does:

if(Cargo.Delivery.Misdirected) { ... }

if(Cargo.Delivery.Arrived) { ... }

Here in the CargoProcessor we're doing the same thing are we not?

On&lt;Cargo&gt;( misdirected ... }

On&lt;Cargo&gt;( arrived ... }

Or am I missing something?</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment5</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment5</guid><pubDate>Fri, 10 Feb 2012 13:13:51 GMT</pubDate></item><item><title>Colin Bull commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>IMHO OO is often used (incorrectly) to express algorithms by implementing behaviours on objects and augmenting that behaviour via hierarchies. This leads to either 

overly generic interfaces with non intentional names like 'Handle' or 'Execute'

or

a complete forest of interfaces to represent each individual class of business operations

I dont think that either of these solutions are acceptable from a maintenance or readability POV. 

Really the algorithm is separate from the Data and often amounts to a handful of common operations over that particular data structure. This is why LINQ is so powerful, and what ayende has exploited with the above solution.
</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment4</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment4</guid><pubDate>Fri, 10 Feb 2012 12:49:36 GMT</pubDate></item><item><title>cocowalla commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>Yikes, maybe it's just me, but this seems convoluted and far less clear than the other solutions... like using a sledgehammer to crack a nut!</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment3</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment3</guid><pubDate>Fri, 10 Feb 2012 10:48:12 GMT</pubDate></item><item><title>Duke commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>Well this looks debuggable ;)</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment2</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment2</guid><pubDate>Fri, 10 Feb 2012 09:54:09 GMT</pubDate></item><item><title>Scooletz commented on Limit your abstractions: Application Events&amp;ndash;event processing and RX</title><description>I don't like this tooling. The previous proposal, with a simple interface with one method Handle was much clearer. There was no derivation, only implementation of one interface which is well known (for instance in NServiceBus - IMessageHandler).
Here, you are obliged to use RX, derive from some class (yes, I know it's small but). IMHO, the previous solution was nicer.</description><link>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment1</link><guid>http://ayende.com/154049/limit-your-abstractions-application-events-event-processing-and-rx#comment1</guid><pubDate>Fri, 10 Feb 2012 09:41:13 GMT</pubDate></item></channel></rss>