Using Aurelia’s Dependency Injection Library In Non-Aurelia App, Part 1

If you are anything like me then you like to try to keep your code loosely coupled, even your JavaScript code.  The ES2015 module spec helped solve a lot of issues with dependency management in JavaScript apps, but it did not really do anything to prevent having code that is tightly coupled to the specific imports. When Aurelia was originally announced, one of the things that first caught my eye was that it included a dependency injection library that was designed to be standalone so you could use it even if you were not including the rest of the Aurelia framework.  Now that Aurelia has had some time to mature, I decided to see how exactly it might look to use the dependency injection library in a variety of non-Aurelia applications.

In this two-part blog series, I will unpack a few basics about the library itself, and then show how it might be used in three different apps: a vanilla JavaScript app, a React app, and then a React app that uses Redux for its state management.

The DI Library

Before we dive into how you would integrate the dependency injection library into your application, we first need to take a look at the how the library works.

If you want to use Aurelia’s dependency injection library, then I would suggest installing it from NPM with “npm install aurelia-dependency-injection”.  You’ll notice there are only two total dependencies that also get installed: aurelia-pal and aurelia-metadata. Aurelia-metadata is used to read and write metadata from your JavaScript functions, and aurelia-pal is a layer that abstracts away the differences between the browser and server so that your code will work across both environments.

Once you have installed the library, the concept is similar to the Unity dependency injection container for .NET.  You create one or more nested containers so each contains their own type registrations, and then types are resolved against a container with the ability to traverse up the parent container chain if desired.  When you register a type, you are able to specify how exactly it will be constructed, or if it is already an instance that should just be returned as-is.

Registration Types

There are three basic lifecycles that you can choose when you register something with the container, and then there are several advanced methods if you need more flexibility.  Let us consider the three lifecycle options first.

Standard Usage

When you want to register an object or an existing instance with the container, you should use the registerInstance method.  When the container resolves an instance, it will not attempt to construct a new one or manipulate it in any way.  The registered instance will simply be returned.

If you want to have your type be constructed every time that it is resolved from the container, then you want to use the registerTransient method.  When you register a transient you need to register the constructor function so that the container can create new instances every time that it is resolved.

You might have something that you want to be a singleton but it still needs to be constructed that first time.  You could either construct it yourself and register it as an instance, or register the constructor function using the registerSingleton method.  This behaves like the registerTransient function except that it will only construct the object the first time it is resolved, and then it will return that instance every other time.  When a singleton is registered, the container that it was registered with will hold on to a reference to that object to prevent it from getting garbage collected.  This ensures that you will always resolve to the exact same instance.  One thing to remember with singletons though is that they are only considered a singleton by a specific container.  Child containers or other containers are able to register their own versions with the same key, so if that happens, then you might get different instances depending on which container resolved it.  If you want a true application level singleton then you need to register it with the root container and not register that same key with any child containers.

If you attempt to resolve a type that does not exist the default behavior is to register the requested type as a singleton and then return it.  This behavior is configurable, though, so if you do not want it, then you should disable the autoregister feature.

Advanced Usage

Now that we have looked at the three basic use cases for registering with the container let us take a look at the more advanced approaches.  If you have a very specific use case that is not covered by the standard instance/transient/singleton resolvers then there are two other functions available to you to give the flexibility to achieve your goals.

If you need a custom lifetime other than singleton/instance/transient, you may register a custom handler with the container.  The handler is simply a function that takes the key, the container, and the underlying resolver and lets you return the object.

If you need a custom resolution approach, then you can register your own custom resolver with the registerResolver function.


import { Container } from 'aurelia-dependency-injection';

// create the root container using the default configuration
const rootContainer = new Container();
// makeGlobal() will take the current instance and set it on the static Container.instance property so that it is available from anywhere in your app
rootContainer.makeGlobal();

const appConstants = { name: 'DI App', author: 'Joel Peterson' };

function AjaxService() {
    return {
        makeCall: function() { ... }
    };
}

// registerInstance will always return the object that was registered
rootContainer.registerInstance('AppConstants', appConstants);

// create a nested Container
const childContainer = rootContainer.createChild();

// register a singleton with the child container
childContainer.registerSingleton(AjaxService);

Resolution

Now that we have considered how to use the container to register individual instances or objects, let us take a look at how types are resolved.

In my opinion, the real benefit of the Aurelia container comes when you use it to automatically resolve nested dependencies of your resolved type.  However, before it can resolve your nested dependencies you have to first tell the container what those dependencies are supposed to be.

The Aurelia dependency injection library also provides some decorators that can be used to add metadata to your constructor functions that will tell the container what dependencies need to be injected when resolving the type.  If you want to leverage the decorator functions as actual decorators then you will need to add the legacy Babel decorators plugin since Babel 6 does not support decorators at the moment, https://github.com/babel/babel/issues/2645.  However, my advice would be to use the decorator functions as plain functions so that you do not have to rely on experimental features.


import { inject } from 'aurelia-dependency-injection';

import MyDependency1 from './myDependency1';

import MyDependency2 from './myDependency2';

function MyConstructor(myDependency1, myDependency2) { ... }

inject(MyDependency1, MyDependency2)(MyConstructor);

export default MyConstructor;

In this example, the inject function adds metadata to the constructor function that indicates which dependencies need to be resolved and injected into the argument list for your constructor function.  It is important to keep in mind that the dependencies will be injected in the order that they were declared, so be sure to make your arguments list order align with your inject parameter list.

Some developers might decide that they do not want to have to manually register all of their types with the container and would rather have it automagically be wired up for them.  Aurelia does support this approach as well with the autoregister feature.  However, it is probably not going to be ideal to have everything be registered as singletons so Aurelia provides other decorators that you can use to explicitly declare how that type will be autoregistered.  Once you decorate your items as singletons or transients, then whenever they are resolved they will autoregister with that lifetime modifier and you can build up your app’s registrations on-demand.


import { singleton, transient } from 'aurelia-dependency-injection';

function MyType() { ... }

// by decorating this type as a singleton, if this is autoregistered it will instead be registered as a singleton instead of as an instance
// default is to autoregister in root container
singleton()(MyType);
// or you can allow it to be registered in the resolving container
singleton(true)(MyType);

// or you can specify that this is a transient type
transient()(MyType);

export default MyType;

Resolver Modifiers

Aurelia also provides a few different resolver modifiers that you can use to customize what actually gets injected into your constructor functions. For instance, maybe you do not want the container to autoregister the requested type if it does not exist and just return a null value instead, or maybe you want to return all of the registered types for a given key instead of just the highest priority type.  These resolver modifiers are used when you specify the dependencies for your given constructor function.


// this list is not exhaustive, so be sure to check out Aurelia's documentation for additional resolvers

import { Optional, Lazy, All, inject } from 'aurelia-dependency-injection';

function MyConstructor(optionalDep, lazyDep, allDeps) {

    // optional dependencies will be null if they did not exist
    if (optionalDep !== null) { ... }

    // lazy dependencies will return a function that will return the actual dependency
    this.actualLazyDep = lazyDep();

    // all will inject an array of registrations that match the given key
    allDeps.forEach((dep) => { ... });
}

inject(Optional.of(Dep1), Lazy.of(Dep2), All.of(Dep3))(MyConstructor);

export default MyConstructor;

Vanilla JavaScript

Now that we have talked about the basics of how to use Aurelia’s dependency injection library, the first type of application that I want to consider is a simple application written in vanilla JavaScript.  The full source code for this example app can be found at my Github repo, so I will just explain some of my choices and the reasons behind them.

I created a module that is responsible for returning the root container.  My personal preference is to be able to explicitly import the root container in my app instead of relying on the Container.instance static property being defined.

There are many different ways that you can create your UI with vanilla JavaScript and I opted to create a simple component structure where each component has a constructor, an init function, and a render function.  I decided to keep the init phase separate from the constructor so that the container can use the constructor solely for passing in dependencies.  There is a way in which you can supply additional parameters to the constructor but I decided it would be simpler to just have to init functions.  However you end up writing your UI layer, I would advise that you do it in such a way so that your constructor parameters are only the required dependencies, otherwise, you will have to do a more complicated container setup.

I also decided to allow for my components to track a reference to the specific container instance that resolved them.  This allows components to create a child container off of the specific container that resolved the current component and build a container tree.

However, one thing that I did discover with the deeply nested container hierarchies is that child dependencies resolve at the container that resolved the parent, and the resolution of child dependencies does not start back down at the original container.  For instance, consider this example.


// component A depends on component B

rootContainer.registerTransient(ComponentA);
rootContainer.registerTransient(ComponentB);

const childContainer = rootContainer.createChild();
childContainer.registerTransient(ComponentB);
const componentA = childContainer.get(ComponentA);

In this example, I would expect that since ComponentA does not exist in the child container that it would fall back to the root container to resolve.  However, when it sees that ComponentA depends on ComponentB and attempts to resolve ComponentB, I would expect it to start from childContainer since that is where the initial resolution happened.  Based on my experience, however, it seems like it starts at rootContainer since that is the container that actually resolved ComponentA.  This can cause issues if you attempt to override a previously registered item in a child container and that is a dependency of something that is only defined in the parent container.  In my example app, I ran across this and ended up re-registering the dependents of my overridden module in my child container so that the resolution would occur properly.

Conclusion

In this article, we discussed some of the basic functionality of Aurelia’s dependency injection library and how you might incorporate it into a vanilla JavaScript application.  In Part 2, we will look at how you might also wire up dependency injection into a plain React application as well as a React application that uses Redux for state management.

Coping with Device Rotation in Xamarin.Android

You think that you have your Android application in a state where you can demo it to your supervisor when you accidentally rotate your device and the app crashes. We have all been there before and the good news is that the fix is usually pretty simple even if it can sometimes take awhile to find.

This has always been an issue for Android developers, but I have found that, due to the unique interaction between your C# classes and the corresponding Java objects, it seems to be a little more sensitive with Xamarin.Android apps. In this post, we will discuss what happens when you rotate your device and cover the different techniques that you might choose to use to manage your application state through device rotations as well as the ramifications of each of them.

Configuration Changes

So, what happens when you rotate your device?  Your device’s orientation is considered to be a part of the configuration of your application and, by default, Android will restart your Activity whenever it detects a change to the configuration.  At first glance, this seems like a pretty heavy-handed approach to handling device rotations, but there is a reason behind it. To understand that reason, we need to go back and review a few basics about Android app development.

Android, and by extension Xamarin.Android, has a way for you to create resources that only apply for a particular configuration value. Resources can be added to a folder that is tied to a configuration value, and those resources will only be used if that configuration value exists in the current setup. This is seen most often with drawables when you see the various drawable-mdpi or other drawable-*dpi folders so that you can provide images that are scaled appropriately for the resolution of the device. The Android system will choose the proper drawable folder and fall back to the base drawable folder at runtime whenever a given image is requested. This system of coupling resources to a given configuration goes beyond drawables to include all of the resource types, so layouts, strings, values, colors, etc. These can all be restricted using the same configuration qualifiers.

Device orientation is one of those configuration values that can be used to conditionally load different resources through the use of the “*-port” or “*-land” qualifiers.  Though, this means there could potentially be different resources used when viewing the app in landscape mode than in portrait mode, and that needs to be accounted for when the device rotates.  The Android team decided that restarting the Activity would be the best way to handle this so the resources could be reloaded with the new configuration values when the Activity restarts.

That might all sound fine, except that it can cause problems if you have not correctly accounted for this behavior in your code.  There are several approaches that you can take to deal with this, although the simplest approaches can also be the most restrictive to your app.

Prevent Orientation Changes

The first approach is also going to be the easiest to handle, but it is the most limiting, because it involves telling Android that your Activity only supports a single orientation. You can do this by setting the ScreenOrientation property of the ActivityAttribute on your Activity class to the orientation that you want to force your Activity to use.

[Activity(ScreenOrientation = ScreenOrientation.Portrait)]
public class MyActivity : Activity
{
}

This approach has some obvious drawbacks, but if it works for your UX needs then it will be a simple way to ensure that an orientation change will not affect your application.

However, it is important to keep in mind that orientation changes are not the only configuration changes that might occur and cause your Activity to restart. For instance, a user can change their font/text size, which will also trigger your Activity to restart. So suppressing an orientation change is not a complete fix for any issues that your app would experience with restarting the Activity.

Manually Handling Configuration Changes

The second approach is a much more manual approach. It is possible to tell your app that you want to manually handle configuration changes in your code instead of restarting the Activity. To implement this approach you need to override the OnConfigurationChanged method in your Activity and manually process the new configuration object to do whatever needs to be done and then subscribe to specific configuration changes. Again, just like preventing an orientation change, this is as simple as tweaking your ActivityAttribute to specify which configuration changes will trigger calls to your method.

[Activity(ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
public class MyActivity : Activity
{
    public override void OnConfigurationChanged(Configuration newConfig)
    {
        base.OnConfigurationChanged(newConfig);

        // perform actions to update your UI
    }
}

You might have noticed that I included the ScreenSize configuration change in my attribute. The reason is since API 13 (Honeycomb) the screen size also changes with the orientation, so you need to subscribe to both changes in order to keep your Activity from restarting.

This source code example will indeed prevent the configuration change from restarting your Activity, but it will not change which resources were used. If you were originally in portrait mode, then you would still be using your portrait resources even though you are now in landscape mode. If you want to also update your resources, then you will need to manually inflate the new resources and replace the old resources with them. However, since the Activity is not being restarted, that means the lifecycle events (OnCreate, OnResume etc.) are not executing, so any code that obtains references to views in your layout, or initializes values in your layout, will need to be performed again for your newly inflated views.

This can quickly become a lot of work if your UI is anything other than trivial and it is going to be prone to breaking if you forget a step or something changes in the future. As a result of that, I cannot recommend this approach unless your app does not utilizing orientation based resource overrides that would require inflation.

Retaining your Fragment Instance

If you are making use of fragments in your app, then they are also destroyed and recreated along with your Activity when a configuration change occurs. If your Activity class itself is just a thin wrapper around different fragments that actually contain most of your application state, then maybe it will be enough for you to persist your fragments and let the Activity still recreate itself. Like the previous examples, this is very simple to do since you just have to make one method call on your fragment to let Android know that the instance needs to be saved.

// from activity
var fragment = new MyFragment();
fragment.RetainInstance = true;

// OR in fragment
public override void OnCreate(Bundle bundle)
{
    RetainInstance = true;
}

Android will save the instance of your fragment and when it rebuilds your Activity it will reuse that fragment instance instead of creating a new one. This sounds pretty good, but if your fragment makes use of any resources that are orientation specific then you run into the exact same problem that you have with manually managing the orientation change. You will still need to inflate your new resources and initialize them manually, so other than saving your member variables for you this approach does not gain you a lot.

However, one place where this technique can be very useful is if you have some objects that may not serialize/deserialize well. As long as those objects do not retain references to the Context/Activity, such as other views or drawables, you can add those objects to a dummy fragment and retain that fragment. The fragment itself should just be a thin fragment that does not do anything else, and since there is no resource inflation happening in it you do not have to worry about reinflating anything.

Save and Restore your Application State

The Android designers knew that destroying and recreating the Activity was going to cause problems so they provided a mechanism for developers to save their state and then restore it after recreation.

Both the Activity and Fragment classes have a SaveInstanceState method that receives a Bundle where you can store serializable data. This method is called just prior to those objects being destroyed so the class states are still valid. You can use this bundle to store member variables from your class, or data that was retrieved and you do not want to have to retrieve it again, or anything else that is serializable.

protected override void OnSaveInstanceState(Bundle outState)
{
	base.OnSaveInstanceState(outState);

	outState.PutBoolean("someBoolean", someBoolean);
        outState.PutInt("someInt", someInt);

        // assume someObject is of type List<SomeModel>
        // I like to use Newtonsoft.Json to serialize to strings and back
        outState.PutString("someModels", JsonConvert.SerializeObject(someModels));
}

Activity classes have a RestoreInstanceState method that receives the Bundle containing the saved state and it has a chance to repopulate the class’s members with their data, although the same bundle is also passed to OnCreate so you could put your restore logic there as well depending on your need. RestoreInstanceState is called after OnStart, so if you need to initialize views before the Activity is started then you will want to use OnCreate. Keep in mind that the bundle in OnCreate can be null if the Activity is being launched so you will need to perform a null check.

protected override void OnCreate(Bundle savedInstanceState)
{
        base.OnCreate(savedInstanceState);

        // you must do a null check before referencing it here
        if (savedInstanceState != null)
        {
            someBoolean = savedInstanceState.GetBoolean("someBoolean", false);
            someInt = savedInstanceState.GetInt("someInt", 0);

            someModels = (IList<SomeModel>)JsonConvert.DeserializeObject<IList<SomeModel>>(savedInstanceState.GetString("someModels", null));
        }
}

protected override void OnRestoreInstanceState(Bundle savedInstanceState)
{
        base.OnRestoreInstanceState(savedInstanceState);

        // this method is only called when restoring state, so no need to do a null check
        someBoolean = savedInstanceState.GetBoolean("someBoolean", false);
        someInt = savedInstanceState.GetInt("someInt", 0);

        someModels = (IList<SomeModel>)JsonConvert.DeserializeObject<IList<SomeModel>>(savedInstanceState.GetString("someModels", null));
}

Fragments are a little different in that there are multiple methods that receive the Bundle with the saved state so you can restore your state in any of them. Generally speaking I would recommend using the OnActivityCreated method to restore your state since this happens prior to the UI views in your Fragment getting restored. If you needed to restore your state after the UI views being updated then you can use the OnViewStateRestored method.

public override void OnActivityCreated(Bundle savedInstanceState)
{
	base.OnActivityCreated(savedInstanceState);

	// load the data from the saved cache if it exists
	if (savedInstanceState != null)
	{
		someModels = (IList<SomeModel>)JsonConvert.DeserializeObject<IList<SomeModel>>(savedInstanceState.GetString("someModels", null));
	}
}

Android does not want you to have to do all of the work so it will automatically save the state of all views in your UI with IDs for you. Pieces of information like your scroll location are also saved and restored with the views in between OnActivityCreated and OnViewStateRestored, so if you want your scroll location to be correct then you will need to populate new adapters with your saved data and attach them to your lists in OnActivityCreated so that the scroll size is correct before Android sets the location.

One other piece that you will need to keep in mind is that Android will also attempt to restore your fragments and the back stack in the fragment manager. However, if your Activity keeps a reference to any of the fragments within it, you will need to save that fragment identifier so that Android can restore it with the correct instance. Fortunately they provide an easy way to do that.

protected override void OnSaveInstanceState(Bundle outState)
{
	base.OnSaveInstanceState(outState);

        // I am using the SupportFragmentManager here since I am using AppCompat with the support libraries.  This should also work with FragmentManager if you are not using AppCompat
        SupportFragmentManager.PutFragment(outState, "currentFragment", currentFragment);
}

protected override void OnRestoreInstanceState(Bundle savedInstanceState)
{
        currentFragment = SupportFragmentManager.GetFragment(savedInstanceState, "currentFragment") as MyFragment;
}

It might seem like a lot of work to save and restore your state, but all you really need to do is save off your Activity and Fragment’s instance variables and restore them at the appropriate moments. Most of the issues that I run into deal with forgetting to save/restore variables that I have added.

How does this affect async/await?

One other thing that you will need to keep in mind is that you will need to manage your async/await Tasks. You should try to implement your Tasks so that they can be cancelled if needed. If you have a pending Task when your Activity restarts, when the Task completes it will try to resume the original location which no longer exists. Ideally you should cancel any pending Tasks when the Activity or Fragment is stopped, or come up with an approach where the Task is running in some class instance that is not destroyed with the Activity.

Conclusion

As a developer, it can be annoying work to properly maintain your application’s state. If your application has a relatively simple UI that does not involve resource overrides, then you are probably going to be safe ignoring orientation changes. However, if your requirements change in the future, then that decision could give you a headache. This is one of those cases where it is probably easier to implement it properly from the beginning rather than ignoring it and refactoring it later once it has become an issue.

I hope that this article has helped you come to a better understanding of Android configuration changes and how you can take steps to make sure that your app is going to work properly when it is rotated.

A Dive into SystemJS – Production Considerations

Previously we have looked at the basic configuration of SystemJS and what happens when you attempt to load modules. What we have covered so far is good enough for a development system, but things are different when you try to push your code to production and performance is much more important. It might be fine for a development system to make XHR requests for each individual script file, but that is not ideal for most production systems. This article will attempt to evaluate the production setup that is needed to attain good performance. [Read more…]

A Dive into SystemJS – Loading and Translating

In the last article we took a look at some of the basic configuration options of SystemJS and also the high level workflow of what happens when you attempt to import a module. This article is going to walk through what happens from when a script has been fetched by the browser until a module instance is returned, as well as provide some information on creating plugins for SystemJS. [Read more…]

A Dive into SystemJS – Part 1

The ECMA2015 module syntax for JavaScript was a much needed addition to the language. For years now the JavaScript community has tried to make up for the lack of a standard module format with several competing formats: AMD, CommonJS, and then UMD which tried to wrap both of the others. The introduction of an official module syntax, details of which can be found at the MDN imports documentation page, means that there is going to be a new module loader required to load the new format. Unfortunately the ECMA2015 specification ended up not including a module loader, but there is a proposal with the WhatWG team to add a module loader to the browser. SystemJS is a module loader built on top of the original ES6 module loader polyfill and soon to be the polyfill for the WhatWG module loader. This series of articles is going to take a deep dive into SystemJS and see what all it has to offer. [Read more…]

Working with the HTML Selection API

The HTML Selection API gives developers the ability to access highlighted text within the browser and perform some DOM and text manipulation on the selected text. These useful features are available now in any modern browser as well as legacy browsers back to IE9. While there are more complex things that can be done with this API this blog article will hopefully illustrate some possible uses of the API and give you an idea of how to start using some of these features.
[Read more…]

Sencha Touch

Mobile applications are everywhere these days and the number of development frameworks geared towards mobile audiences is growing as well. This can make it difficult for us developers who have to spend valuable training time learning one or more of these frameworks in order to be able to do our jobs. Sencha Touch is one of these frameworks and it allows a developer to code in HTML, CSS, and Javascript, and then package up the application to run on different mobile devices. This article is intended to provide a general feel for what Sencha Touch is and what it does.
[Read more…]

Garbage Collection and the Finalizer

One aspect of modern web development that sometimes seems to be taken for granted is memory management. While you might not need to create a custom boot disk anymore in order to run your application on a modern machine, it is still important to understand how your memory allocations are cleaned up. Two of the main components to cleaning up memory allocation are the garbage collector and the finalizer.
[Read more…]

Common Pitfalls with IDisposable and the Using Statement

Memory management with .NET is generally simpler than it is in languages like C++ where the developer has to explicitly handle memory usage.  Microsoft added a garbage collector to the .NET framework to clean up objects and memory usage from managed code when it was no longer needed.  However, since the garbage collector does not deal with resource allocation due to unmanaged code, such as COM object interaction or calls to external unmanaged assemblies, the IDisposable pattern was introduced to provide developers a way to ensure that those unmanaged resources were properly handled.  Any class that deals with unmanaged code is supposed to implement the IDisposable interface and provide a Dispose() method that explicitly cleans up the memory usage from any unmanaged code.  Probably the most common way that developers dispose of these objects is through the using statement.
[Read more…]