I came across this thread whilst battling a similar issue. Specifically, the upgrade to 8.6.1 (from 8.5.5) caused a boot error due to compositions.
For future Googlers:
Umbraco.Core.Exceptions.BootFailedException: Boot failed.
---> System.InvalidOperationException: Unable to resolve type: Umbraco.Core.Composing.ComponentCollection, service name:
---> System.InvalidOperationException: Unable to resolve type: MyCustomComponent, service name:
---> System.InvalidOperationException: Unresolved dependency [Target Type: MyCustomComponent], [Parameter: myCustomService( ImyCustomService)], [Requested dependency: ServiceType:ImyCustomService, ServiceName:] at LightInject.ServiceContainer.GetEmitMethodForDependency(Dependency dependency)
My error was that one composer class could not resolve the type of another custom class (service). This thread helped me realise that during composition it is necessary to boot things in the right order so that dependent types are added in the right sequence. I must have been lucky before that!
Come to think of it I actually have a similar structure set up for a spell check index in Examine, which looks like this:
public class SpellCheckIndexComponent : IComponent
{
private readonly IExamineManager _examineManager;
private readonly SpellCheckIndexCreator _SpellCheckIndexCreator;
public SpellCheckIndexComponent(IExamineManager examineManager, SpellCheckIndexCreator spellCheckIndexCreator)
{
_examineManager = examineManager;
_SpellCheckIndexCreator = spellCheckIndexCreator;
}
public void Initialize()
{
foreach (var index in _SpellCheckIndexCreator.Create())
{
_examineManager.AddIndex(index);
}
}
public void Terminate() { }
}
And the SpellCheckIndexCreator:
public class SpellCheckIndexCreator: LuceneIndexCreator
{
private readonly IProfilingLogger _profilingLogger;
private readonly ILocalizationService _localizationService;
private readonly IPublicAccessService _publicAccessService;
// Since Umbraco 8 has dependency injection out of the box, we can use it to inject
// the different services that we need.
public SpellCheckIndexCreator(IProfilingLogger profilingLogger,
ILocalizationService localizationService,
IPublicAccessService publicAccessService)
{
_profilingLogger = profilingLogger;
_localizationService = localizationService;
_publicAccessService = publicAccessService;
}
//is this where we actually create the index?
//how do we populate it?
public override IEnumerable<IIndex> Create()
{
var index = new UmbracoContentIndex("SpellCheckIndex",
CreateFileSystemLuceneDirectory("SpellCheckIndex"),
new FieldDefinitionCollection(new FieldDefinition("word", FieldDefinitionTypes.FullText)),
new SpellCheckAnalyzer(Lucene.Net.Util.Version.LUCENE_30),
_profilingLogger,
_localizationService,
// We can use the ContentValueSetValidator to set up rules for the content we
// want to have indexed.
new ContentValueSetValidator(true, true, _publicAccessService));
return new[] { index };
}
}
They're registered like this:
[RuntimeLevel(MinLevel =RuntimeLevel.Run)]
public class RegisterIndexesComposer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Components().Append<SpellCheckIndexComponent>();
composition.Components().Append<ExamineEventComponent>();
composition.RegisterUnique<SpellCheckIndexValueSetBuilder>();
composition.Register<SpellCheckIndexPopulator>(Lifetime.Singleton);
composition.RegisterUnique<SpellCheckIndexCreator>();
}
}
The only difference I can see is that I'm directly registering the class rather than an implementation of an Interface - could you try that? :)
The problem is not your SiteService, it is the injecting of IPublishedContentQuery into your service, and then using the Service in a location where an UmbracoContext is not guaranteed to exist, eg in a component.
There is some really detailed information on this page in the docs:
Thank you all. This really helped me. Ran into using IPublishedContentQuery by examples on our.umbraco. But didn't realize it couldn't be used in constructor of my own service. Now it's working all like I intended to, thanks.
How to get custom service injected into custom component?
Hi,
At the moment I am rewriting a lot of code.
I created a SiteService, like in all of the examples on the Umbraco site. Like this:
It is registered this way:
I can easily inject this into my Surface controllers, this works fine just by adding ISiteService in constructor of controller.
By now my problem.. I've also created a component:
I can't get this to work. As soon as I add ISiteService to the constructor it leads to a BootFailed Exception:
What should I do to make it possible to inject my custom service into my custom component? Can anyone please help me with this one?
Thanks in advance!
Remko
Have you tried putting both of the compositions in the same function to make sure they're done in the right order?
E.g.
Just to make sure that they're registered in the correct order?
I came across this thread whilst battling a similar issue. Specifically, the upgrade to 8.6.1 (from 8.5.5) caused a boot error due to compositions.
For future Googlers:
My error was that one composer class could not resolve the type of another custom class (service). This thread helped me realise that during composition it is necessary to boot things in the right order so that dependent types are added in the right sequence. I must have been lucky before that!
Adding a [ComposeAfter] attribute to reference the dependent service was enough to fix the issue. There is some pretty decent documentation here: https://our.umbraco.com/documentation/Implementation/Composing/#attributes
Yes, when I simply add the SiteService in same Composer, before adding ShoppingApplicationComponent, I get the same Exception.
Come to think of it I actually have a similar structure set up for a spell check index in Examine, which looks like this:
And the SpellCheckIndexCreator:
They're registered like this:
The only difference I can see is that I'm directly registering the class rather than an implementation of an Interface - could you try that? :)
Hi Remko
The problem is not your SiteService, it is the injecting of IPublishedContentQuery into your service, and then using the Service in a location where an UmbracoContext is not guaranteed to exist, eg in a component.
There is some really detailed information on this page in the docs:
https://our.umbraco.com/Documentation/Implementation/Services/#implementing-the-service
where you can access the cache using the UmbracoContextFactory... and this will avoid your boot errors.
regards
Marc
Comment author was deleted
If you need an example check out https://github.com/skttl/Our.Umbraco.FullTextSearch
Thank you all. This really helped me. Ran into using IPublishedContentQuery by examples on our.umbraco. But didn't realize it couldn't be used in constructor of my own service. Now it's working all like I intended to, thanks.
is working on a reply...