Wednesday, December 29, 2010

OxenIoC: an IoC container for Objective C

Last year I've been working on two applications for IPhone with several views and core data entities, a lot of classes that really are hard to maintain. These projects were started on september of 2009 by other company. In 2010 we received this legacy and we are still adding features and new versions on the store.
I know that iPhone applications are not really big applications but we think that an IoC Container can help to do applications like these a little more maintainable. This is the reason because we decided make a proof of concept with an IoC container. Now we going to explain what we did.

The main concern is how we are going to specify the objects for the container. We took two approaches, the first one consist in specifying the objects from code and the second one in reading the context from XML.

Specifying context from code

For this approach we have the class IoCObjectDefinition wich can specify, a name, a class name, if it's singleton, if it's lazy and the references.

Here's an example:

- (IoCContainer *) buildContainerFromCode {
  IoCContainer *container = [[IoCContainer alloc] init];

  IoCObjectDefinition *serviceDefinition = [[IoCObjectDefinition alloc] init];
  serviceDefinition.name = @"theService";
  serviceDefinition.className = @"ExampleServiceImpl1";
  serviceDefinition.lazy = NO;
  [container addDefinition:serviceDefinition];
  [serviceDefinition release];

  IoCObjectDefinition *serviceExecutorDef = [[IoCObjectDefinition alloc] init];
  serviceExecutorDef.name = @"theExecutor";
  serviceExecutorDef.className = @"ServiceExecutorImpl1";

  // inject theService to serviceExecutor
  [serviceExecutorDef addPropertyReference:@"service" toObjectName:@"theService"];

  [container addDefinition:serviceExecutorDef];
  [serviceExecutorDef release];

  return [container autorelease];
}



Specifying references from code

Also you can specify the injection of objects in the class code. The macro called IoCContainerInject(property,objectName)


provides such functionality. Here's an example,

@implementation ServiceExecutorImpl2
  @synthesize service;

  //Inject theService object to service property
  IoCContainerInject(service, theService)

  - (void) executeService {
    [service execute];
  }
@end



Specifying objects from an XML

Also you can specify the same context by XML. Here's the example,

<contanier>  

  <object id="theService" class="ExampleServiceImpl2" lazy="false"/>  

  <object id="theExecutor" class="ServiceExecutorImpl1">
    <property name="service" ref="theService"/>  
  </object>

</contanier>




Getting objects from container

We have the class IoCContainer. This class have the method - (id) getObject: (NSString*) name;

Here's an example:

id<ServiceExecutor> executorFromCode = [containerFromCode getObject:@"theExecutor"];

Application example

We uploaded an app example in order to show these concepts.

This application has 3 contexts, one built from code other built from an XML and the last one built from code but inject the reference by the macro.

This app has 2 protocols,

  1. ExampleService with a method named execute.
  2. ServiceExecutor with a method named executeService. ServiceExecutors have an ExampleService.

There are 2 implementations for each of these protocols.


  • ExampleServiceImpl1 the execute method write in log Service Implementation 1.
  • ExampleServiceImpl2 the execute method write in log Service Implementation 2.
  • ServiceExecutorImpl1 is a class with a property of kind id.
  • ServiceExecutorImpl2 is a class with a property of kind id that specifies the injection of the object called "theService".

OxenIoCAppDelegate builds the 3 contexts wiring those objects in different ways, then it gets the 3 serviceExecutors and executes them.


What's next

We will try to find out how to reduce the code to write for adding objects to container. We think that conventions and default values could help.

Monday, December 20, 2010

CodePro AnalytiX first impression

I'm evaluating CodePro AnalytiX in order to use it in a project. We're currently using Checkstyle.

At first sight, it seems that CodePro AnalytiX is more strict and validates more topics. However, I'm just trying the default configuration.


  • It suggest you always overriding toString() method.
  • Checkstyle ignores the lack of Javadoc comment if the method has an @Override annotation. CodePro doesn't. Also, CodePro doesn't take in account the {@inheritDoc} Javadoc annotation, so you must specify all the method documentation (even for toString(), for example).
  • There is a validation for package names: they should start with a reverse domain name.
  • It suggest not using String literals. You can add an //$NON-NLS-1$ comment for Strings that are not internationalized.
  • Constants ending with digits (for example, TEXT_1) produces a warning.
  • The use of System.out is discouraged.
  • Checkstyle asked variable parameters to be final. CodePro suggest local variables to be final too.


However, the scope of CodePro goes beyond syntax checking. It also has metrics reports and code analisys (for example, detecting dead and duplicated code). So it could be compared with PMD and FindBugs too. But this, my friends, is is matter for another post :)

Sunday, December 5, 2010

Adding dependency injection to jMonkeyEngine with Google Guice

I'been playing for a while with jMonkeyEngine 3. I downloaded the SDK and tried the starter tutorial series. I recommend you reading these tutorials before reading this post.

The examples where created extending the SimpleApplication class, which provides many services as instance variables, such as instances of AssetManager, AppSettings, etc. All the examples were written in a single class. I wanted to split the functionality into smaller classes, so I needed to pass such references to other classes. A way to implement this in a generic way could be integrating Google Guice. I recommend you reading some basics about Guice too.

I built 3 annotations:
  • GuiNodeRef: for injecting a reference to guiNode instance.
  • AssetManagerRef: for injecting a reference to assetManager instance.
  • AppSettingsRef: for injecting a reference to appSettings instance.
A new base application class, GuiceApplication, will create and configure the injector:

public abstract class GuiceApplication extends SimpleApplication {

    private Injector injector;

    @Override
    public final void simpleInitApp() {
        /* building modules */
        Collection<module> modules = new LinkedList<module>();

        modules.add(new AbstractModule() {

            @Override
            protected void configure() {
                bind(AssetManager.class).annotatedWith(AssetManagerRef.class).toInstance(assetManager);
                bind(Node.class).annotatedWith(GuiNodeRef.class).toInstance(guiNode);
                bind(AppSettings.class).annotatedWith(AppSettingsRef.class).toInstance(settings);
            }
        });

        this.addApplicationModules(modules);

        this.injector = Guice.createInjector(modules);
        this.injector.injectMembers(this);

        this.guiceAppInit();
    }

    public abstract void guiceAppInit();

    protected void addApplicationModules(Collection<module> modules) {
    }
}

The simpleInitApp, which is inherited from SimpleApplication, creates the injector, configures it using a collection of modules, injects application members, and calls the abstract guiceAppInit method. A module that binds the three annotations mentioned before is provided by default, but you can add custom modules by overriding the addApplicationModules method. I took this idea from RoboGuice, which is  a framework that we are using at LeapFactor in order to integrate Guice into Android.

Now you can define injections in the application or in classes injected into the application. Injecting defined annotations would look like this:

@Inject
private @AssetManagerRef AssetManager assetManager;

@Inject
private @GuiNodeRef Node guiNode;

@Inject
private @AppSettingsRef AppSettings settings;
...


I tried it creating a simple Breakout-Arkanoid-like (without bricks :P) game. When I got my first computer in 1988, I started learning Sinclair Basic by writing a simple brick game. I called it Batty II, since I had a tape with (the excellent!) Batty game. This will be a remake, so I called Batty II too. You can download it here. I used the same guice-2.0-no_aop.jar that we used for Android at LeapFactor in order to avoid unnecessary dependencies.

Here you have some screenshots:


Mmmm, the physics engine makes the paddle rotate! This didn't happened with my CZ Spectrum+!


And finally, a friendly message indicating that the game is over: