Can't register services with LightInject in Umbraco - The non-generic method 'Composition.Register(Type, Lifetime)' cannot be used with type arguments
We've generally used Autofac as our go to dependency injection container in Umbraco but we like to keep projects as lean as possible so wanted to start using LightInject for Umbraco V8 projects but hit a silly error this morning which took a while to track down.
Nearly all the documentation online suggests you simply implement IUserComposer as follows and Umbraco will pick it up and all will be good in the world:
public class SomeComposer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Register<ISomeService, SomeService>();
}
}
The thing snag that caught us out though was although we had included Umbraco.Core.Composing for IUserComposer and that gave us access to composition.Register, it was complaining
The non-generic method 'Composition.Register(Type, Lifetime)' cannot be used with type arguments
When using the interfaces in the controllers we were then getting:
Server Error in '/' Application.
Missing public constructor for Type: xxx
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: Missing public constructor for Type: xxx
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[InvalidOperationException: Missing public constructor for Type: xxx]
LightInject.MostResolvableConstructorSelector.Execute(Type implementingType) in C:\projects\lightinject\src\LightInject\LightInject.cs:5561
LightInject.TypeConstructionInfoBuilder.Execute(Registration registration) in C:\projects\lightinject\src\LightInject\LightInject.cs:5719
System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory) +72
LightInject.ConstructionInfoProvider.GetConstructionInfo(Registration registration) in C:\projects\lightinject\src\LightInject\LightInject.cs:5779
LightInject.ServiceContainer.EmitNewInstance(ServiceRegistration serviceRegistration, IEmitter emitter) in C:\projects\lightinject\src\LightInject\LightInject.cs:4026
LightInject.ServiceContainer.EmitNewInstanceWithDecorators(ServiceRegistration serviceRegistration, IEmitter emitter) in C:\projects\lightinject\src\LightInject\LightInject.cs:3929
LightInject.<>c__DisplayClass197_0.b__0(IEmitter methodSkeleton) in C:\projects\lightinject\src\LightInject\LightInject.cs:4646
LightInject.<>c__DisplayClass153_0.b__0(IEmitter ms) in C:\projects\lightinject\src\LightInject\LightInject.cs:3856
LightInject.<>c__DisplayClass153_0.b__0(IEmitter ms) in C:\projects\lightinject\src\LightInject\LightInject.cs:3856
LightInject.ServiceContainer.EmitConstructorDependency(IEmitter emitter, Dependency dependency) in C:\projects\lightinject\src\LightInject\LightInject.cs:4158
The fix was stupidly simple; we had missed our the Umbraco.Core namespace. So for those of you hitting the same error, you'll probably benefit from a code sample with namespaces:
using Umbraco.Core;
using Umbraco.Core.Composing;
public class SomeComposer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Register<ISomeService, SomeService>();
}
}