Skip to content
Antony Male edited this page Nov 28, 2014 · 1 revision

So far I've been saying that StyletIoC holds a mapping of service -> implementation type(s).

That's actually a little lie. In fact, the mapping is [service, key] -> implementation type(s), where key is an arbitrary string which you supply.

This concept of keys allows you to have, say, two implementations of IVehicle, but things requiring an IVehicle can specify, indirectly, which implementation they're after.

There are many ways to specify this key, both when you create the registration, and when you request an instance of a service from StyletIoC.

Specifying The Key Associated With A Type

Keys can be specified in a few ways.

You can specify the key to be associated with a type by using the [Inject(Key = "mykey")] attribute on the type itself, for example:

[Inject(Key = "old")]
class OldBanger : IVehicle { ... }

You can also specify it when binding the type, using the WithKey method. This overrides the key from the attribute, if any:

builder.Bind<IVehicle>().To<HotHatchback>().WithKey("new");
builder.Bind<IVehicle>().To(container => new OldBanger()).WithKey("old");

Retrieving A Type Using Its Key

All of the different injection methods methods support specifying the key to use when deciding which type to inject.

When fetching instances directory using IContainer.Get, you can pass the key to use:

ioc.Get<IVehicle>("old");

When using constructor injection, you can specify the key use using the [Inject(Key = "key") attribute:

class CarOwner
{
   // IVehicle will be a HotHatchback, as that was registered with the key "new"
   public CarOwner([Inject(Key = "new") IVehicle vehicle) { ... }
}

Similarly, you can use the [Inject(Key = "key")] syntax when using property injection:

class CarOwner
{
   [Inject(Key = "old")]
   public IVehicle Vehicle { get; set; }
}

Keys and Collections

You can also use keys with services that have more than one implementation, for example:

builder.Bind<IVehicle>().To<HotHatchback>().WithKey("new");
builder.Bind<IVehicle>().To<Roadster>().WithKey("new");
builder.Bind<IVehicle>().To<OldBanger>().WithKey("old");

// Then...

class NewCarGarage
{
   public NewCarGarage([Inject("new")] IEnumerable<IVehicle> vehicles) { ... }
}

class OldCarGarage
{
   public OldCarGarage([Inject("old")] IEnumerable<IVehicle> vehicles { ... }
}

/// Or...

var newVehicles = ioc.GetAll<IVehicle>("new");
Clone this wiki locally