With Umbraco 8 looming and the choice of LightInject as the dependency resolver certain it would be great to see a comprehensive set of documentation containing instructions to setup the resolver for Umbraco 7.
In the interim would someone write a set of instructions covering the standard requirements plus any quirks for backoffice controllers etc that seem to rear their heads with other dependency injectors. Maybe that could then be used to update the documentation.
I've already seen the code sample here but I would like to see something more complete.
We've been using LightInject with 7 at Crumpled for a spell and it's been working perfectly. Just yesterday I submitted a How-to article to Skrift for next month's issue so if you can hold out for that, it should do the trick,
We're working with LightInject lately, basically from the same reasons why you're looking for more knowledge.
Basically our setup is as usual IoC implementation for Umbraco, so we're registering our container in the Umbraco event ApplicationStarted in our dedicated EventHandler class extending ApplicationEventHandler class.
Our Bootstrapper class holds some placeholders which are filled during the project growth. We've tried to also optimize it e.g. registering all the basic classes for all interfaces based on the naming convention (simply removing "I" from the beginning of the class name). It's all possible.
My basic class looks like this:
public class IoCBootstrapper
{
public static void IoCSetup()
{
var container = new ServiceContainer();
RegisterCoreUmbracoServices(container);
RegisterSimpleServices(container);
RegisterComplexServices(container);
RegisterAssembliesServices(container);
container.RegisterControllers(Assembly.GetExecutingAssembly());
container.RegisterApiControllers(Assembly.GetExecutingAssembly());
container.EnableMvc();
container.EnablePerWebRequestScope();
container.EnableWebApi(GlobalConfiguration.Configuration);
var resolver = new LightInjectWebApiDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
DependencyResolver.SetResolver(new LightInjectMvcDependencyResolver(container));
}
private static void RegisterCoreUmbracoServices(IServiceRegistry container)
{
container.Register(factory => UmbracoContext.Current).RegisterInstance(new PerScopeLifetime());
container.Register(factory => new UmbracoHelper(UmbracoContext.Current)).RegisterInstance(new PerScopeLifetime());
container.Register(factory => ApplicationContext.Current.Services.DataTypeService).RegisterInstance(new PerScopeLifetime());
}
private static void RegisterSimpleServices(IServiceRegistry container)
{
container.Register<IFileSystem, FileSystem>();
container.Register<IHttpContext, HttpContextWrapper>();
...
}
private static void RegisterAssembliesServices(IServiceRegistry container)
{
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var controllerTypes = assembly.GetTypes().Where(t => !t.IsAbstract && typeof(IHttpController).IsAssignableFrom(t));
foreach (var controllerType in controllerTypes)
{
container.Register(controllerType, new PerRequestLifeTime());
}
}
}
private static void RegisterComplexServices(IServiceRegistry container)
{
...
}
}
The most confusing thing when it comes to using LightInject for me personally was the lifetime declaration. PerRequestLifetime for example don't mean exactly what it says and it's safer to use PerScopeLifetime as it's in our case for some of the Umbraco internals when they are required to be used in the code where they are not injected as properties from Umbraco directly.
The only problem which we haven't touched / fixed yet - is related with Umbraco Cloud and conflict with LightInject dependencies / versions numbers. I'm planning to investigate and back to it soon, so maybe Emma's post will cover anything around it to help me and save some of my time :)
If you'll find anything bad / better / different how to deal with it and use more efficient - feel free to ping me here!
That's really interesting! It's very similar to what we have (spoiler alert - I don't address the issue with Umbraco Cloud, sorry!).
Read the piece about the PerRequestLifetime/PerScopeLifetime and can see why you went down that road. It really is different to what it seems. Can I just ask though, why you decided to specifically use LifetimeScope with CoreUmbracoServices? Did you need a shorter lifetime on those?
@Emma - regarding those scopes, as it's for Singletons (or items depending on them) I wanted to keep it registered as short as it's possible to not work on the same object for the whole time.
Basically it was related with the Common Pitfails article and we've been experiencing some issues with it at a very beginning, so it was a next iteration of changes and it stayed this way. If anyone can confirm it can live the other lifetime - I'm eager to adopt and change it to better implementation :)
So... in the above example, the UmbracoHelper which relies on an UmbracoContext which relies on an HttpContext will now be statically assigned to a variable, which means that these particular request scoped objects are now bound to an Application scope lifetime and will never go away. This could mean that under certain circumstances that an entire Umbraco cache copy is stuck in memory, or that the Security property of the context will be accessed by multiple threads but this now contains the security information for a user for another request!
@Dave - those conficts are related with different versions of library used + multiple registrations as we've been registering every library present in the bin folder. I need to go back and play with it more to remember exact issue. Right now it wasn't required.
LightInject instructions for Umbraco 7
Hi all,
With Umbraco 8 looming and the choice of LightInject as the dependency resolver certain it would be great to see a comprehensive set of documentation containing instructions to setup the resolver for Umbraco 7.
In the interim would someone write a set of instructions covering the standard requirements plus any quirks for backoffice controllers etc that seem to rear their heads with other dependency injectors. Maybe that could then be used to update the documentation.
I've already seen the code sample here but I would like to see something more complete.
Cheers
James
Hiya James,
We've been using LightInject with 7 at Crumpled for a spell and it's been working perfectly. Just yesterday I submitted a How-to article to Skrift for next month's issue so if you can hold out for that, it should do the trick,
Em
Hey Emma,
This is most excellent news!
I look forward to reading this muchly :)
Cheers!
James
Wow, great! Can't wait to compare it with our experiences as well.
We're working with LightInject lately, basically from the same reasons why you're looking for more knowledge.
Basically our setup is as usual IoC implementation for Umbraco, so we're registering our container in the Umbraco event ApplicationStarted in our dedicated EventHandler class extending ApplicationEventHandler class.
Our Bootstrapper class holds some placeholders which are filled during the project growth. We've tried to also optimize it e.g. registering all the basic classes for all interfaces based on the naming convention (simply removing "I" from the beginning of the class name). It's all possible.
My basic class looks like this:
The most confusing thing when it comes to using LightInject for me personally was the lifetime declaration. PerRequestLifetime for example don't mean exactly what it says and it's safer to use PerScopeLifetime as it's in our case for some of the Umbraco internals when they are required to be used in the code where they are not injected as properties from Umbraco directly.
I've discovered about this confusion here: https://github.com/seesharper/LightInject/issues/131.
All the rest is pretty straight forward and works just as expected! Project has a nice Wiki: https://github.com/seesharper/LightInject/wiki/Getting-started and a lot of edge cases is covered in lot of the publications.
The only problem which we haven't touched / fixed yet - is related with Umbraco Cloud and conflict with LightInject dependencies / versions numbers. I'm planning to investigate and back to it soon, so maybe Emma's post will cover anything around it to help me and save some of my time :)
If you'll find anything bad / better / different how to deal with it and use more efficient - feel free to ping me here!
Cheers!
Hi Marcin,
That's really interesting! It's very similar to what we have (spoiler alert - I don't address the issue with Umbraco Cloud, sorry!).
Read the piece about the PerRequestLifetime/PerScopeLifetime and can see why you went down that road. It really is different to what it seems. Can I just ask though, why you decided to specifically use LifetimeScope with CoreUmbracoServices? Did you need a shorter lifetime on those?
Emma
What issue do you have on Umbraco Cloud and Light Inject ? I know autofac works there without any issue
Just realised I didn't respond, sorry!
@Emma - regarding those scopes, as it's for Singletons (or items depending on them) I wanted to keep it registered as short as it's possible to not work on the same object for the whole time.
Basically it was related with the Common Pitfails article and we've been experiencing some issues with it at a very beginning, so it was a next iteration of changes and it stayed this way. If anyone can confirm it can live the other lifetime - I'm eager to adopt and change it to better implementation :)
@Dave - those conficts are related with different versions of library used + multiple registrations as we've been registering every library present in the bin folder. I need to go back and play with it more to remember exact issue. Right now it wasn't required.
Cheers, Marcin
Just as a follow up, Emma just had her article on using LightInject in Umbraco released via Skrift
http://skrift.io/articles/archive/the-hows-and-whys-of-using-lightinject-as-a-container-for-ioc/
Thanks Nik!
is working on a reply...