Cannot activate/resolve INavigationQueryService - using .Children()

Hi,

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

public static IServiceCollection AddWebServices(this IServiceCollection services, IConfiguration configuration)
  {
      services.AddScoped<IMyService, MyService>();
      return services;
  }
}

this is referenced in my Umbraco/Web Program.cs

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

builder.CreateUmbracoBuilder()
    .AddBackOffice()
    .AddWebsite()
    .AddDeliveryApi()
    .AddComposers()
    .Build();

builder.Services.AddCommonServices(builder.Configuration);
builder.Services.AddWebServices(builder.Configuration);

I have tried changing the ordering of this, but it makes no difference.

I figure I am missing something obvious here.

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 :slight_smile:

Thanks @LuukPeters – I should’ve mentioned I did that as a previous approach whilst trying to get this to work.

public class WebServicesComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        builder.Services.Configure<AppSettings>(builder.Config);
        builder.Services.AddScoped<IMyService, MyService>();
    }
}

I then call AddComposers inside of Program.cs:

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

builder.CreateUmbracoBuilder()
    .AddBackOffice()
    .AddWebsite()
    .AddComposers()
    .Build();

builder.Services.AddCommonServices(builder.Configuration);

I have tried AddCommonServices above .CreateUmbracoBuilder() as well.

Your AddCommonServices should also be in the composer, then it will probably work.

  1. It fails before builder.Services.AddCommonServices(builder.Configuration)
  2. I’ve tried it with it commented out as it’s not needed for my test scenario here.
  3. 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.