Download
ServicesDemo.rar [13 kb] – XNA GSE 1.0 Refresh Project (source only, the executable is pointless)
Description
Finally, here it is!
In my last blog post I said I’d be doing a sample of what’s explained in it, so service dependencies and service injection in components and other services, in an XNA context. It actually worked in my own game for many weeks, but I just found the time and motivation to finish up my sample.
Details about the sample structure after the jump.
All that’s been explained in the last post is valid. But here’s a couple of UML diagrams that show how it’s implemented in detail.
First, the helper classes : ServiceHelper and ServiceDependencyAttribute.
Then the components and services. A bit wide, sorry…
So let’s say MyComponent needs IMySimpleService to work, which it does. Here are the steps that are needed for this to work :
1. Make an entry point for the service injection, and associated local field.
IMySimpleService mySimpleService;
[ServiceDependency]
public IMySimpleService MySimpleService
{
set { mySimpleService = value; }
}
2. In the Game class’ Initialize method, load the service using the service helper, initialize it and then load the component also using the service helper.
protected override void Initialize()
{
ServiceHelper.AddService(new MySimpleService());
ServiceHelper.InitializeServices();
ServiceHelper.AddComponent(new MyComponent(this));
// ...
}
When the component’s Initialize method is called, the service is guaranteed to be injected. If not, the MissingServiceException is raised.
So that’s the basics… The code is well commented and shows most features of my system. Hope you like it!
Hi Zak,
Thanks for this sample and UML diagrams but I can’t see a development justification for such approach.
I mean, if you are to develop your own game components and services in a game, you will know which ones are present and which are not.
Or are you throwing this design for libraries development?
My intent is to make components pluggable, so that if you decide to unplug a component for debugging or feature removal, you don’t end up with strange errors and know exactly what’s wrong at initalization time.
Also the order in which you add the services and components does not matter with my approach, so you don’t have to worry about which service depends on which and find the right initialization sequence.
And finally I like the fact that I don’t have to do GetService<T> for each of my services, they’re injected automagically with my setters.
But yeah, the advantages aren’t that clear. The usual system works well, this does not add that much functionality, it just feels cleaner to me. A matter of preference I guess…