July 31, 2008
@ 07:00 PM

I'm a big fan of "drop in" components which can add functionality to my applications as opposed to what is more commonly thought of as framework-level code which bakes in functionality. What do I mean by that? The common way of building in functionality into an application (usually via a framework) is to develop an class hierarchy, then inherit from those classes in your application as you build up functionality. A form class may have code which remember it's location and size when you close it, an edit box may add some spell checking ability, etc. If you inherit all your forms from these classes they suddenly have all this extra functionality and life is good. Then, as the framework is built you tend to end up with a number of interdependencies between components, which suddenly makes it more difficult to be able to use these components in other applications which don't include most of the framework libraries and inherit from the proper classes. On one level that's fine, since it allows for a fairly high level of functionlity and consistency. However, it requires a high level of "buy in" in order to use even the most basic aspects of the framework. In many cases you just can't use some cool combobox class from the framework in another application without requiring the full framework (and inheritance chain) to come along for the ride, which is a bit of a bummer. There are a huge number of applications written that can't easily be integrated with a framework (as most VFP developers think of them).

What if, instead, components had been built to be highly modular - drop in a small class library, add the control to your form and you're good to go. Until VFP 9 this was actually a bit hard to do - what if your control needed to respond to various form events? Everytime you dropped the control on a new form you suddenly have to do a lot of wiring up by adding code to the various events your control was interested in. Which leads back to the first style of development that just assumes you'll be using these components as a whole. However, in VFP 8 they introduced a set of commands to allow for event binding: BINDEVENT(), UNBINDEVENTS(), RAISEEVENT() and AEVENTS(). So what do these commands do and what do they give you? They give you a mechanism of listening for specific events that fire on an object and handling those events in your own code. You can do this without the "source" object even being aware you are listening to it's events.

A real example might help:

Let's suppose we want to add the ability to sort a column in a grid. The common way of doing that would be to create a subclass of a grid, add some code which does the sorting as methods on the grid, then require the developer to "hook up" the functionality during development so that this new functionality runs when a user double clicks on the row header. In effect, add code to every column's header and adding code to the DblClick() event. You'll even notice that even if we require you to use our new subclassed grid the functionality still isn't really just drop-in seamless. So how can event binding help here? Can it help us achieve both goals of not requiring any glue code and not requiring us to inherit from a specific grid control?

What I'd love to end up with is a control I can drop on a form, point it to some grid control and have the grid "magically" let you sort without requiring a lot of changes to existing code. So let's start from that premise and create a custom control. I'll add cGridEval property which can be filled in with a string which is EVAL'd at runtime to resolve a live object reference to our grid, ex. you can fill in something like "This.grdSample". That's the easy part, now how do we use event binding to let us do everything else?

I'm going to create a BindControl() method in my custom control and we'll first get our object reference to the grid:

loGrid = EVALULATE(This.cGridEval)

Every grid has a Columns collection that we can iterate through and each column has a Controls collection. If we take a look at the BaseClass property of the controls here we can determine which one is the Header column. At that point we can use BINDEVENT() to hook up the DblClick() event to us - when a user double clicks on this grid column the event will fire on the grid and we'll also get a notification that the event has fired.

FOR EACH loColumn IN loGrid.Columns
    FOR EACH loControl IN loColumn.Controls
        IF loControl.BaseClass = "Header"
           BINDEVENT(loControl, "DblClick", This, "Sort")
           EXIT
        ENDIF
    ENDFOR
ENDFOR

The BINDEVENT() function is where the real work happens. We pass the control we want to listen to as the first parameter, in this case the header. Then we pass (as a string) the name of the method we want to listen to, "DblClick". The third parameter is an object reference to the subscribing object (us), and the fourth is the method VFP should call on our object. You must make sure that the method you create on your subscriber accepts all of the same parameters as the event being fired. For example, if we hooked into the KeyPress event accepts two parameters, nKeyCode and nShiftAltCtrl - you have to accept the same parameters in your subscribing method. There is a fifth parameter which can be passed that we're not using which allows you to specify when your code is called - before or after the original control's method fires. DblClick doesn't pass in any parameters, so we're good. All we need to do is create a "Sort" method on our custom object.

At this point, when a user double clicks on a header in a hooked up grid, our Sort event fires. Great - now how do we figure out which header was clicked on? Here's where the AEVENTS() function comes into play - it fills an array with information about the object that triggered the event. We can use this information to get a reference to the actual header the user double clicked on. From there, we can determine which column in the grid to sort.

AEVENTS(laEvent, 0)

This gives us a 3 column array, laEvent:

laEvent[1] - An object reference to the header that was clicked
laEvent[2] - The event that was fired
laEvent[3] - The event type (how the event was raised).

In our case we're really only interested in laEvent[1]. Once we have our header reference we can get the column's control source like this:

loHeader = laEvent[1]
loColumn = loHeader.Parent
lcControlSource = ALLTRIM(loColumn.ControlSource)

All that's left is for us to build up a way of creating temporarily indexes and maintaining a list of which indexes have been created (and whether we're current ascending or descending). One thing that is kind of nice is that since we now have a reference to the column header, we can also do things like add some graphical image to the sorted column to make it easy for the user to see which column has been sorted and in which direction.

You'll notice that I didn't cover the UNBINDEVENTS() and RAISEEVENT() functions. UNBINDEVENTS does just what you'd expect - it unhooks an event handler so that it no longer receives the bound event. RAISEVENT() lets you "fire" an event (both things like custom events and events on native VFP objects). I don't have a nice example of this so I'll leave that for some other time.

You can download the finished control below.

Links:

http://www.rcs-solutions.com/Download.ashx?File=rcsGridSort.zip
 

Categories: VFP

July 12, 2008
@ 10:34 AM

I mentioned Dependency Injection / Inversion of Control (DI/IoC) recently and I really didn't explain what it is, why you might want to use this particular pattern, and why on earth you'd need a framework for it. It's a fancy name for a fairly simple concept. Instead of creating objects inside of your classes, you let the calling code "inject" the necessary instances into your code. It's probably easiest to see this in some code. I'm going to show both C# and VFP code, since I don't want you to get the idea that this is a .NET-only type thing.
 

   1 public class SampleDependency

   2 {

   3    public string SayHello()

   4    {

   5       return "Hello";

   6    }

   7 }

   8 

   9 public class Sample

   10 {

   11    protected SampleDependency m_depend;

   12 

   13    public SampleDependency Depend

   14    {

   15       set { this.m_depend = value; }

   16    }

   17 

   18    public Sample(SampleDependency depend)

   19    {

   20       m_depend = depend;

   21    }

   22 }

 

      Sample sample = new Sample(new SampleDependency());

 

VFP Version
DEFINE CLASS SampleDependency AS Session 
   FUNCTION SayHello() 
      RETURN "Hello" 
   ENDFUNC 
ENDDEFINE 

DEFINE CLASS Sample AS Session 
   oDepend = NULL 
   FUNCTION Init(toDepend) 
      This.oDepend = toDepend 
   ENDFUNC 
ENDDEFINE 

loSample = CREATEOBJECT("Sample", CREATEOBJECT("SampleDependency"))
 

Notice that in both cases, we are passing in the instance we want the class to use instead of letting the class create the instance itself. That's all DI/IoC is. Honest, that's it. This is DI via a constructor (you can also do it via a property setting instead; notice in the sample C# code I created a write-only property which could hold the reference).

So the next obvious question is, why? What's wrong with just creating the object inside of the class?

One thing DI gives you is the ability to easily swap in different objects. In the C# example, we probably would change the parameter from a specific type to an interface. Now any class which implements that interface can be injected into this class. In VFP, since it's not strongly typed, you can just pass in whatever instance you'd like (it's up to you to make sure it doesn't blow up at runtime by accessing some method or property which isn't on the passed in object). My initial thought after seeing this was, well, can't I just use an abstract factory pattern instead? In an abstract factory you delegate object creation to a "object factory" - usually passing in a name or calling a method which returns the actual instance you'd like to use. This sounds like almost the same thing.

An abstract factory does let you do that, but it doesn't let you easily do something the DI/IoC pattern does: test your objects. Let's suppose you want to write a test for a class which uses another class to send out an e-mail. You aren't really trying to test sending an e-mail - that's just one of the things the class you're testing happens to do during some process. In fact, you really don't want to send out an e-mail; we don't want to spam our users. If you happen to use the abstract factory pattern, you would need to modify it to create your dummy/stub/mock object for sending an e-mail (in VFP that's most likely by editing a record in a table, but the idea is the same), then test the object in question. If you used the DI/IoC pattern the only thing you need to do is pass in your dummy/stub/mock object. No other modifications are necessary.

OK, so this all looks simple enough. Why would you need a framework for the above?! One of the biggest reasons - less typing. You'll notice that in order to use any of these objects you may have to pass in a bunch of other dependency objects (which themselves may have other dependencies). For a complex set of objects that could really suck. A DI framework does that for you along with the benefits of an abstract factory, all rolled up into one. In your code you call the DI framework and tell it to get you an instance of a class - it figures out what objects need to be passed in for you so you don't need to do it. In your tests, you can instanciate the objects directly and pass in your stub/dummy/mock objects instead.

Links:

http://weblogs.asp.net/rosherove/archive/2007/09/16/mocks-and-stubs-the-difference-is-in-the-flow-of-information.aspx
http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx


 
Categories: .NET | Software | VFP

July 11, 2008
@ 08:42 PM

I just ran across this and it's a welcome option - you can add "(loband)" to any of the MSDN documentation links on the website and it will serve up a much faster version of the docs. For example,

Instead of:

http://msdn.microsoft.com/en-us/library/cc707819.aspx

Try:

http://msdn.microsoft.com/en-us/library/cc707819(loband).aspx

There is also an option at the top of the page once you've selected this option to persist the low bandwidth view, so all of the pages come up like this by default. I appreciate the treeview when I'm just poking around, but sometimes the site is just painful to navigate to since it takes a bit to render them.


 
Categories: MSDN

July 6, 2008
@ 12:24 PM

I attended a Day of Dot Net event in Lansing a few week back. If you're not familiar with them, they are free mini-conferences (one day) about, not surprisingly, .NET.

I had originally planned on driving out to it Saturday morning, but then Jenn pointed out I'd have to get up really early to get there around 8am. I already work in Farmington, which is 45 minutes to 1 hour from home (and 45 minutes to 1 hour closer to Lansing) and would end up being a really long day for me. So I ended up just staying at a hotel in Lansing Friday night. That turned out to be a great idea. Note to self: the Best Western in Lansing feels and smells like a 80's style bowling alley.

When I got to the hotel, I had some time to look up directions to the college where it was being held. It was only a few miles away, so I decided to not bother to drive over there on Friday night (which is what I would normally have done). In the morning I followed the directions Google Maps had given and found myself in a church parking lot (hmm..."Day of Dot Net and Evangelical Revival??"). I checked the map a few times and it looked OK, and I was exactly where it said I should be. I think that was about the point where I starting cursing out Google maps. I had left all my information about the conference in the trunk so I had to get out of the car to get at it. I happened to notice that the road I was on looked like it actually continued around the side of the church (imagine a light bulb going off above my head: "hey...maybe...."). I jumped back in the car and drove around the parking lot and sure enough, the trees suddenly cleared on my left hand side where the college was hiding. I noticed another car stop right about where I stopped, so it wasn't just me being dense (honest!). Note to organizers - great event, but a small sign would have been appreciated.

When I got into the building (which also wasn't marked, so I still wasn't entirely sure I was at the right entrance), I was surprised at how few people were there - that kind of surprised me since I wasn't able to make it to the last DoDN because it had filled up. It turns out that as the morning wore on the sessions really started to fill up.

The sessions were an hour long - which is REALLY short; they flew by. The sessions all seemed to run a few minutes long which pushed into the next session running a bit longer. The lunch break helped to reset everything.

A few notes to the various presenters:

  • The bottom 1/3 of the screen really isn't visible if you're sitting in the back of the room. I was sitting in the second row and couldn't read some of it.
  • White text on a black background might be easier on your eyes for development, but it's impossible to read when it's projected up on a screen. I'd suggest sticking with black text on a white background.
  • Don't try to wing demo's. Only a few people can successfully pull that off - you're probably not one of them.

I actually ran into a few people I knew - one was someone from the local VFP user group, the other was a old-VFP developer that I haven't seen in a few years. That was a nice surprise. Overall, I was impressed by the number of people who attended, considering you're basically giving up a weekend day to attend. It's nice to see that some people actually care about getting better as developers (either that or they, like me, needed a few new shirts for their wardrobe).

One session happened to stand out in my mind - a session about Dependency Injection / Inversion of Control (specifically, the Windsor framework) by Jay Wren. Well organized, hit every question I had about DI/IoC. Honestly, I didn't "get" DI/IoC before this session; yeah, I understood what it was, but not really why on earth I might need a framework for it. It is actually an elegant way of solving a particular development problem, giving you the benefits of a factory pattern and the flexibility of DI, without getting in your way (at least that's what my notes say). I had the "a ha!" moment, then promptly lost it in one of the other sessions. I'm sure it will come to me at some point, although at this point I'm getting a bit nervous ;-)

At the end of the conference, they ended up giving away of ton of stuff. Just not to me. Oh well, maybe next time.

Overall, I definitely attend another one - a big thanks to the organizers and presenters and sponsors, I know it's a lot of work to put something like this on - it was appreciated. Just try to make sure you've got some soft drinks (Coke, Mt. Dew, etc.) available in the morning next time around <g>. It's hard for some of us to get moving in the morning without some caffeine (for us non-coffee drinkers). Sure I feel all healthy from the orange juice I ended up drinking, but it didn't help much to put a spring in my step.

Links

http://www.dayofdotnet.org/Lansing/2008/
http://jrwren.wrenfam.com/blog/


 
Categories: .NET | Conference

I've been working on an application which relies heavily on WCF to communicate. I have a very simple interface (contract) that the server supports to connect and disconnect: it exposes the methods Register() and Unregister(). When the client starts up and connects, it calls the Register() method, passing in some identification info. I save this information in a List<T> so that it can be used by the server to provide callbacks. When the client disconnects, it calls Unregister() which then removes the client from the collection.

That works well enough, right up until a client abruptly disconnects (ex. a connection error, network line goes down, etc.) Then suddenly I end up with a reference to a disconnected client on the server. If I attempt to use this connection to send a message back to the client an exception is thrown (which still works OK). It would be nice to know immediately as soon as a client disconnects.

If you are using TCP (full duplex) as the communication channel, you can do this pretty easily - note: this doesn't work for some of the other communication modes, like HTTP duplex. For those, you might have to rely on the various timeout settings in the .config file.

Here's what that ends up looking like (I happen to be taking advantage of LINQ here, but you can easily adjust that code if you're using an older vesion of the framework):

  203 private void IServer.Register(string systemName)

  204 {

  205     IClientCallback remoteMachine = OperationContext.Current.GetCallbackChannel<IClientCallback>();

  206     // Hook up events to let us know if the client disconnects w/o telling us.

  207     OperationContext.Current.Channel.Faulted += new EventHandler(ClientFaulted);

  208     OperationContext.Current.Channel.Closed += new EventHandler(ClientClosed);

  209 

  210     // Get object reference to figure out the IP address of the connected client

  211     MessageProperties prop = OperationContext.Current.IncomingMessageProperties;

  212     RemoteEndpointMessageProperty endpoint = prop[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;

  213 

  214     // (threading/locking code removed)

  215 

  216     client = m_callbackList.Find(c => c.SystemName == systemName);

  217     if (client == null)

  218     {

  219         // It's not already on our list, add it

  220         m_callbackList.Add(new RegisteredClient(systemName, endpoint.Address, remoteMachine));

  221     }

  222 }

 

When the client disconnects, the ClientFaulted/ClientClosed events will be fired. Honestly, at this point, the Unregister method isn't really needed, assuming you follow the same disconnection process in both cases.
 
Categories: WCF