» 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

~22d ago

joreg: END OF SHOUTBOX! As this page has is now legacy, it will no longer feature new content. For latest news, see: http://vvvv.org

~1mth ago

joreg: vvvvTv S0204 is out: Custom Widgets with Dear ImGui: https://youtube.com/live/nrXfpn5V9h0

~1mth ago

joreg: New user registration is currently disabled as we're moving to a new login provider: https://visualprogramming.net/blog/2024/reclaiming-vvvv.org/

~2mth ago

joreg: vvvvTv S02E03 is out: Logging: https://youtube.com/live/OpUrJjTXBxM

~2mth ago

~2mth ago

joreg: Follow TobyK on his Advent of Code: https://www.twitch.tv/tobyklight

~2mth ago

joreg: vvvvTv S02E02 is out: Saving & Loading UI State: https://www.youtube.com/live/GJQGVxA1pIQ

~2mth ago

joreg: We now have a presence on LinkedIn: https://www.linkedin.com/company/vvvv-group

~2mth ago

joreg: vvvvTv S02E01 is out: Buttons & Sliders with Dear ImGui: https://www.youtube.com/live/PuuTilbqd9w

~2mth ago

joreg: vvvvTv S02E00 is out: Sensors & Servos with Arduino: https://visualprogramming.net/blog/2024/vvvvtv-is-back-with-season-2/