asp.net-coredependency-injectionsimple-injectortus

GetRequiredService from within Configure


I'm trying to access one of my services from within the Configure call within Startup.cs in aspnet core. I'm doing the following however I get the following error "No service for type 'UserService' has been registered." Now I know it is registered because I can use it in a controller so I'm just doing something wrong when it comes to using it here. Please can someone point me in the right direction. I'm happy with taking a different approach to setting up Tus if there's a better way of achieving what I want.

      var userService = app.ApplicationServices.GetRequiredService<UserService>();
      userService.UpdateProfileImage(file.Id);

The below is where I'm wanting to use

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{

... Other stuff here...

  app.InitializeSimpleInjector(container, Configuration);

  container.Verify();


  app.UseTus(httpContext =>
  {

    var restaurantEndpoint = "/restaurant/images";
    var userEndpoint = "/account/images";
    var endPoint = "/blank/images";

    if (httpContext.Request.Path.StartsWithSegments(new PathString(restaurantEndpoint)))
    {
      endPoint = restaurantEndpoint;
    }

    if (httpContext.Request.Path.StartsWithSegments(new PathString(userEndpoint)))
    {
      endPoint = userEndpoint;
    }

    return new BranchTusConfiguration
    {
      Store = new TusDiskStore(@"C:\tusfiles\"),
      UrlPath = endPoint,
      Events = new Events
      {
        OnBeforeCreateAsync = ctx =>
        {
          return Task.CompletedTask;
        },

        OnCreateCompleteAsync = ctx =>
        {
          return Task.CompletedTask;
        },

        OnFileCompleteAsync = async ctx =>
        {
          var file = await ( (ITusReadableStore)ctx.Store ).GetFileAsync(ctx.FileId, ctx.CancellationToken);

          var userService = app.ApplicationServices.GetRequiredService<UserService>();
          userService.UpdateProfileImage(file.Id);
        }
      }
    };

  });

... More stuff here...

};

My end goal is to move this to an IApplicationBuilder extension to clean up my startup.cs but that shouldn't affect anything if it's working from within startup.cs

Edit: Add to show the registration of the userService. There is a whole lot of other stuff being registered and cross wired in the InitializeSimpleInjector method which I've left out. can add it all if need be..

 public static void InitializeSimpleInjector(this IApplicationBuilder app, Container container, IConfigurationRoot configuration)
{

  // Add application presentation components:
  container.RegisterMvcControllers(app);
  container.RegisterMvcViewComponents(app);

  container.Register<UserService>(Lifestyle.Scoped);

  container.CrossWire<IServiceProvider>(app);
  container.Register<IServiceCollection, ServiceCollection>(Lifestyle.Scoped);
}

Solution

  • Please read the Simple Injector integration page for ASP.NET Core very closely, as Simple Injector integrates very differently with ASP.NET Core as Microsoft documented how DI Containers should integrate. The Simple Injector documentation states:

    Please note that when integrating Simple Injector in ASP.NET Core, you do not replace ASP.NET’s built-in container, as advised by the Microsoft documentation. The practice with Simple Injector is to use Simple Injector to build up object graphs of your application components and let the built-in container build framework and third-party components

    What this means is that, since the built-in container is still in place, resolving components using app.ApplicationServices.GetRequiredService<T>()—while they are registered in Simple Injector—will not work. In that case you are asking the built-in container and it doesn't know about the existence of those registrations.

    Instead, you should resolve your type(s) using Simple Injector:

    container.GetInstance<UserService>()