IoC: Static Service Locator - canton7/Stylet GitHub Wiki
Caliburn.Micro came with a static service locator called IoC
. This let you access the IoC container from anywhere in your code, like this:
var vm = IoC.Get<MyDialogViewModel>();
this.windowManager.ShowDialog(vm);
Stylet doesn't include an equivalent, and with good reason: I don't want to encourage people to write such horrible code. The Service Locator pattern is frequently termed an anti-pattern. Every class now has a dependency on IoC
(instead of the actual classes it depends on), and you can't tell just by looking at the class's constructor what its dependencies are: you have to scour through the code for calls to IoC.Get
.
IoC
was also used internally within Caliburn.Micro to get around some poor design choices. These have been re-architected in Stylet, and so IoC
is no longer required internally.
If you really really need IoC
back (and it's a deal-breaker), then you can write your own very easily. First create this static IoC
class:
public static class IoC
{
public static Func<Type, string, object> GetInstance = (service, key) => { throw new InvalidOperationException("IoC is not initialized"); };
public static Func<Type, IEnumerable<object>> GetAllInstances = service => { throw new InvalidOperationException("IoC is not initialized"); };
public static Action<object> BuildUp = instance => { throw new InvalidOperationException("IoC is not initialized"); };
public static T Get<T>(string key = null)
{
return (T)GetInstance(typeof(T), key);
}
public static IEnumerable<T> GetAll<T>()
{
return GetAllInstances(typeof(T)).Cast<T>();
}
}
Then wire it into your bootstrapper like this:
protected override void Configure()
{
IoC.GetInstance = this.Container.Get;
IoC.GetAllInstances = this.Container.GetAll;
IoC.BuildUp = this.Container.BuildUp;
}