Skip to main content

Basic usage

This section is about the basics of Stashbox's API. It will give you a good starting point for more advanced topics described in the following sections. Stashbox provides several methods that enable registering services, and we'll go through the most common scenarios with code examples.

Default registration

Stashbox allows registration operations via the Register() methods.

During registration, the container checks whether the service type is assignable from the implementation type and if not, the container throws an exception.

Also, when the implementation is not resolvable, the container throws the same exception.

The example registers DbBackup to be returned when IJob is requested.

container.Register<IJob, DbBackup>();
IJob job = container.Resolve<IJob>();
// throws an exception because ConsoleLogger doesn't implement IJob.
container.Register<IJob, ConsoleLogger>();
// throws an exception because IJob is not a valid implementation.
container.Register<IJob, IJob>();

You can register a service to itself without specifying a service type, only the implementation (self registration).

In this case, the given implementation is considered the service type and must be used to request the service (DbBackup in the example).

container.Register<DbBackup>();
DbBackup backup = container.Resolve<DbBackup>();

The container's API is fluent, which means you can chain the calls on its methods after each other.

var job = container.Register<IJob, DbBackup>()
.Register<ILogger, ConsoleLogger>()
.Resolve<IJob>();

Named registration

The example shows how you can bind more implementations to a service type using names for identification.

The same name must be used to resolve the named service.

note

The name is an object type.

container.Register<IJob, DbBackup>("DbBackup");
container.Register<IJob, StorageCleanup>("StorageCleanup");
IJob cleanup = container.Resolve<IJob>("StorageCleanup");

You can also get each service that share the same name by requesting an IEnumerable<> or using the ResolveAll() method with the name parameter.

container.Register<IJob, DbBackup>("StorageJobs");
container.Register<IJob, StorageCleanup>("StorageJobs");
container.Register<IJob, AnotherJob>();
// jobs will be [DbBackup, StorageCleanup].
IEnumerable<IJob> jobs = container.Resolve<IEnumerable<IJob>>("StorageJobs");

Instance registration

With instance registration, you can provide an already created external instance to use when the given service type is requested.

Stashbox automatically handles the disposal of the registered instances, but you can turn this feature off with the withoutDisposalTracking parameter.

When an IJob is requested, the container will always return the external instance.

var job = new DbBackup();
container.RegisterInstance<IJob>(job);

// resolvedJob and job are the same.
IJob resolvedJob = container.Resolve<IJob>();

The instance registration API allows the batched registration of different instances.

container.RegisterInstances<IJob>(new DbBackup(), new StorageCleanup());
IEnumerable<IJob> jobs = container.ResolveAll<IJob>();

Re-mapping

With re-map, you can bind new implementations to a service type and delete old registrations in one action.

caution

When there are multiple registrations mapped to a service type, .ReMap() will replace all of them with the given implementation type. If you want to replace only one specific service, use the .ReplaceExisting() configuration option.

container.Register<IJob, DbBackup>();
container.ReMap<IJob, StorageCleanup>();
// jobs contain all two jobs
IEnumerable<IJob> jobs = container.ResolveAll<IJob>();

container.ReMap<IJob, SlackMessageSender>();
// jobs contains only the SlackMessageSender
jobs = container.ResolveAll<IJob>();

Wiring up

Wiring up is similar to Instance registration except that the container will perform property/field injection (if configured so and applicable) on the registered instance during resolution.

container.WireUp<IJob>(new DbBackup());
IJob job = container.Resolve<IJob>();

Lifetime shortcuts

A service's lifetime indicates how long its instance will live and which re-using policy should be applied when it gets injected.

This example shows how you can use the registration API's shortcuts for lifetimes. These are just sugars, and there are more ways explained in the lifetimes section.

info

The DefaultLifetime is configurable.

When no lifetime is specified, the service will use the container's DefaultLifetime, which is Transient by default.

container.Register<IJob, DbBackup>();
IJob job = container.Resolve<IJob>();