Execution events hookup

@ikeough @pboyer @Steell PTAL

This PR adds events to the NodeServices library that are triggered immediately before and after each execution. This is functionality that has been requested by several integration targets now in ZT libraries, rather than having to subclass the app to get at the hooks to do so.

There are a couple of issues I'm requesting your thoughts on:

1. This uses a static library that globally handles events - it's not clear how otherwise a ZT library would get a handle to the Dynamo Graph that is executing. I think we may need to put in a DynamoNodeServices that knows more about Dynamo. I don't want to have NodeServices burden every library that uses it with a reference to Dynamo, and ofc we need to get the arrows pointing right to avoid circular reference problems.

2. The use of a single global event causes problems if there are multiple home workspaces in the AppDomain. I know we're trying to avoid introducing any more of these problems. My inclination is to say that we need an identity for the workspaces. We can't use an instance reference because of the requirement that NodeServices does not reference Dynamo. The easiest way out of this would be to give the workspaces an ID, so we can fire the events knowing which they're coming form. I expect we'll see similar needs in the VMDataBridge project. We will need a way to notify the VM execution what URI it's executing from so it can link it up to the IDs.

3. The events aren't threadsafe under addition/removal of the event hooks. This seems to be a general problem with the event dispatch mechanism in our libraries. I think this problem will become more serious when we have multiple workspaces so someone unhooking an event as execution is completing becomes a more realistic scenario. For now I don't think this is a major issue.

Thoughts?

Thanks for looking,

Luke