Introducing Saitama

In the previous post I talked about the decision to explore a framework that would continue to allow our West Monroe teams to use the features we like from MVVMCross, namely dependency injection.  However, as a team we have come to realize that MVVMCross has limits with more complicated and UX intensive applications that cannot be overcome without significant effort.  Over the past week, I have been working on a framework that would satisfy our needs as a team.  It now has a name: Saitama.

Goals

I am a big believer in IoC and its role in modern software development.  I have had the chance to use it with many different frameworks throughout the course of my career.  My current favorite is AutoFac but previous to that I enjoyed using Ninject.  I am sure other developers have their favorites as well so I wanted to make the framework IoC framework agnostic, use whatever you like.

Obviously there are some popular frameworks so I tried to implement those as best as I could, but I left it open if someone has a favorite framework they want to use.  You can even extend to other platforms, although, right now, I am only supporting Android and iOS.

The Core

At the core of the framework (Saitama.Core) are two items: the abstract class InjectionContainerResolverBase and the interface IInjectionContainer.  Each serves a specific purpose and facilitates injection within the application by registering specific Injectable Base Types with the chosen IoC framework.

The process of IoC is extremely simple.  Register a bunch of dependencies, usually marked with interfaces and then, when creating a “base” type look for properties (or constructor arguments) matching those types and provide instances held within the container for those arguments/properties. Thus, when a developer is operating in their dervied class(es) they can be assured that dependencies are fulfilled.

Identifying these “base types” is the job of the resolver and while the core process is platform agnostic, the conventions used to “find” the base types differ platform to platform, this is why derivations should use one of the “platform” base classes (Saitama.Core.Platforms).

Once these registrations are made, the resolver returns an instance implementing IInjectionContainer which is used for injection throughout the rest of the app.

Bootstrapping

While this all sounds good, it is useless unless we have a means to kick off this registration process.  For that we look to the specific bootstrap class on each supported platform (UIApplicationDelegate on Apple and Application on Android).  Because we know the OS will call into methods on these classes before anything else, they are ideal places to start.  For now, we will focus on the iOS side.

The absolute first point at which the user can take control of their app in iOS is with WillFinishLaunching, our base class SaitamaApplicationDelegate (in Saitama.Apple) overrides this method and takes a few actions:

  1. It asks the derivation for its instance of InjectionContainerResolverBase. The responsibility here is for the developer to return a container (or some intermediary which can create a container) that has all dependencies registered with the exception of the base types
  2. The Resolver registers all base types by scanning a provided assembly (entry on iOS, executing on Android) for types matching a certain convention (the convention can be overridden). For each type found, the resolver will register it against the container
  3. The IInjectionContainer is extracted from the resolver and stored in an internal static property (more on this later). This contains the knowledge of how the fulfill dependencies on base types
  4. The injection container fulfills all dependencies on the bootstrap class. This allows the developer to begin working with the dependencies as soon as possible

It is at this point that our application starts up and we define our first view.  For iOS, I have created an abstract class to serve as the base for all ViewController types (Saitama.Apple).  This inheritance is crucial for Saitama.  Without it, the framework will not know how to resolve dependencies on base types, such as View Controller.  Here is an example of a View Controller for the Test App.

    public partial class HomeViewController : SaitamaViewController
    {
        public INumberService NumberService { get; private set; }

        public HomeViewController() : base("HomeViewController", null)
        {
        }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // Perform any additional setup after loading the view, typically from a nib.
            var alertView = new UIAlertView("Generated Number", string.Format("Your number is: {0}", NumberService.GetNumber()),
                                null, "Ok", null);
            alertView.Show();
        }
    }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

As you can see, this code is no different than what you would normally write.  In this case, I am using a Xib based approach, but the storyboard approach is also covered.

Prebuilt Containers

As it normally is, the hardest part is usually creating the IoC container to use for injection, at least that was always my experience with ASP .NET MVC.  To that end, I intend to supply container modules for both Android and iOS implemented using AutoFac and Ninject for both.  My hope is that it will be enough to show others how they might write their own.

Future Plans

The current codebase is still being built, with heavy focus on Android, confident that I will get through it soon.  Next steps after that will be to clean up the source code and GitHub repo.  Then, I will package it with Nuget and send it out into the world.

The Code

https://github.com/xximjasonxx/Saitama

Please let me know if you have any feedback.  I am always interested in how I can make this better.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s