Using the new .Children overload in v15 (the old method being marked as obsolete), the build process can never activate INavigationQueryService:
AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: MyApp.IMyService Lifetime: Scoped ImplementationType: MyApp.MyService': Unable to resolve service for type 'Umbraco.Cms.Core.Services.Navigation.INavigationQueryService' while attempting to activate MyApp.MyService'.)
The recommended approach to replace the obsolete .Children is to use the overload accepting INavigationQueryService and IPublishedStatusFilteringService:
public class MyService(IUmbracoContextAccessor umbracoContextAccessor,
INavigationQueryService navigationQueryService,
IPublishedStatusFilteringService publishedStatusFilteringService) : IMyService
{
public IEnumerable<MyType> GetData()
{
if (umbracoContextAccessor?.TryGetUmbracoContext(out var umbracoContext) != true)
{
return [];
}
var myData = umbracoContext?.Content.GetById("someGuid");
return myData.Children(navigationQueryService, publishedStatusFilteringService).OfType<TechCategory>();
}
}
Why can this not resolve?
For detail, MyService : IMyService is defined in a class library
You should really use a composer to add your own services. Then you can be certain that Umbraco services are loaded. Otherwise you run into the issue you are facing
It fails before builder.Services.AddCommonServices(builder.Configuration)
I’ve tried it with it commented out as it’s not needed for my test scenario here.
If it didn’t fail, I can’t shouldn’t really use an Umbraco composer there as AddCommonServices comes from a Core project which doesn’t and can’t rely/reference anything Umbraco specific.
Just giving this a slight bump, if anyone knows a solution. I can’t see anything in the docs. It’s not a deal breaker right now given the old way still works, but I’d like to figure it out going foward.
Hi @UmbracoMonkey I’ve had luck in using IDocumentNavigationQueryService within injection and setting it to the INavigationQueryService like so: _navigationQueryService = documentNavigationQueryService;
Any workarounds on this og did you solve it?
Im upgrading to Umbraco 17 and need a way to use .AncestorOrSelf, .Root .Children ect.
All of these are now required to use the INavigationQueryService or IPublishedStatusFilteringService. However I cannot inject/resolve them.
Also tried with using a Composer.
You can use the IDocumentNavigationQueryService to get ids of children, ancestors, root, etc. and can then use the cache to fetch the full nodes when that is required.
A quick example:
using var context = _umbracoContextFactory.EnsureUmbracoContext();
if (_documentNavigationQueryService.TryGetRootKeys(out var rootKeys))
{
var rootNode = await context.UmbracoContext.Content.GetByIdAsync(rootKeys.FirstOrDefault());
}