» Pattern.Service Locator
This site relies heavily on Javascript. You should enable it if you want the full experience. Learn more.

Pattern.Service Locator

acl(admin devvvv vvvvgroup)

Service provider

A key requirement in the development of vvvv45 was to write the various software components in a way that they are loosely coupled. It should be possible to use components written for 45 in the future 50 version of vvvv and the other way round, things written for 50 should be useable in 45.
In order to do that it is mandatory to introduce abstraction layers. An abstraction layer is basically a set of interfaces which describe what methods are needed or exposed by a component.
A good example for such a component is a tree viewer:
Once an input element is set to the viewer, all the viewer wants to know about this particular input element is if it has children and how to display it. The former is done by an interface called ITreeContentProvider with the method GetChildren(object) and the latter is done by an interface called ILabelProvider with methods like GetText(object) and GetImage(object).
The introduction of that abstraction made the tree viewer completely independent of the data it displays. It can work with any input element as long as there's an provider which knows how to deal with a specific element.
But what if those specific elements come from several different components? Like plugins who want to contribute to the viewer.
Here's where the service locator pattern comes into play.

Service locator pattern

A service locator is basically one central object which provides methods to register types and type mappings (RegisterType, RegisterInstance) and methods to retrieve objects of a required type (Resolve).
In our example with the tree viewer displaying elements coming from several different components, we'd set up a service locator and give each component access to it, so it has the possibility to register the services it provides (in our case type mappings from ITreeContentProvider to some content provider for element FooBar). We'd further write a content and label provider for our viewer, which simply asks the service locator for a concrete implementation of ITreeContentProvider and element FooBar and delegates the call to that conrete provider. For example the GetText method of our provider would look something like this:

string GetText(object element) {

  var labelProvider = serviceLocator.Resolve<ILabelProvider>(element);
  return labelProvider.GetText(element);

}

A more in depth explanation of the service locator pattern can be found here: http://martinfowler.com/articles/injection.html#UsingAServiceLocator

Unity

There're several different service locators available for .NET. One of them is Unity which we use in vvvv.
Note: In Unity the service locator is called a container (IUnityConatiner).

An IUnityContainer is a little more than a simple service locator. It's more like super factory, which can be extendend and configured in various ways. It allows to plug into the service creation and destruction process via extensions. That way it's possible to do some fancy stuff, like method interception (for example to do logging), lifetime management (should an object be created on every resolve call or only once per thread) and the creation of container hierachies, which are useful to override the service resolution in some circumstances.

A very good documentation on unity is available here: http://msdn.microsoft.com/en-us/library/ff663144.aspx

Event hub

The viewer needs to be updated if the data model changes. This is done through events in the ITreeContentProvider (ContentChanged) and ILabelProvider (LabelChanged). But how do the content and label providers get notified by the data model? One solution would be, that they would subscribe to model objects once they see them first, provided every model object implements the same interface, so the provider knows how to subscribe.
Problem: each provider would have to implement that logic about subscribung and unsubscribing to the objects it deals with.
Another approach is to use the container together with an event hub. Each time a model object is created, a container extension can go through the events provided by the created object and subscribe the event hub to events it knows about. After that step is done, the event hub is one central object, which can be used to retrieve all different kind of events.
The providers only need access to the event hub to get notified about underlying changes in the data model.
Access to the event hub could for example easily be given through the service locator (the unity container in our case):

var eventHub = unityContainer.Resolve<IEventHub>();

A more in depth explanation on this topic can be found here:
http://kentb.blogspot.com/2008/03/event-hub.html

anonymous user login

Shoutbox

~5d ago

~8d ago

joreg: The Winter Season of vvvv workshops is now over but all recordings are still available for purchase: https://thenodeinstitute.org/ws23-vvvv-intermediates/

~14d ago

schlonzo: Love the new drag and drop functionality for links in latest previews!

~22d ago

joreg: Workshop on 29 02: Create Sequencers and Precise Clock Based Tools. Signup here: https://thenodeinstitute.org/courses/ws23-vvvv-08-create-sequencers-and-precise-clock-based-tools-in-vvvv-gamma/

~29d ago

joreg: Workshop on 22 02: Unlocking Shader Artistry: A Journey through ‘The Book of Shaders’ with FUSE. Signup here: https://thenodeinstitute.org/courses/ws23-vvvv-12-book-of-shaders/

~1mth ago

joreg: Talk and Workshop on February 15 & 16 in Frankfurt: https://visualprogramming.net/blog/vvvv-at-node-code-frankfurt/

~1mth ago

woei: @Joanie_AntiVJ: think so, looks doable

~1mth ago

xd_nitro: Anyone remember who increased projector brightness by removing some components that product the color?

~1mth ago

Joanie_AntiVJ: This looks super interesting (vectors over network) would anyone here know how to implement this in beta? https://github.com/madmappersoftware/Ponk