skip to Main Content

In simple terms, I have a services.AddScoped which I would like to access globally without directly adding it to every class constructor (of which there are very many). I have static helper functions which are easy to access globally, so I would like to be able to access this scoped helper from this static helper function, or have some other global method of accessing this scoped dependency.

I know this might break DI patterns or something, but I don’t really care. I just need a separate instance of a global variable for each individual request in a way that is as easy to implement as possible.

EDIT: I should mention that I am looking for a solution that does not actually require any modification to the constructor of the calling class, although requiring specific inputs to the static method or attributes in the static method is fine. Because there will be many many different classes calling this static method and I am not interested in modifying every single one of them just to pass in a reference.

2

Answers


  1. You can create scope via ServiceProviderServiceExtensions.CreateScope inside your static method by passing instance of the IServiceProvider (or using root service provider saved into some static field/property after DI container is build on app start):

    public static void Do(IServiceProvider sp)
    {
        using(var scope = sp.CreateScope())
        {
            var service = scope.ServiceProvider.GetRequiredService<ScopedService>();
            // use service
        }
    }
    

    Though in general I would recommend against this pattern. Also note that if service implements or has injected IDisposable‘s those (depended on the lifetime) will be disposed with the scope.

    Login or Signup to reply.
  2. As you mentioned this is not the suggested way of getting the services but you could use Service Locator pattern.

    private static readonly HttpContextAccessor _HttpContextAccessor = new ();
    
    public static void DoSomething()
    {
        var service = HttpContextAccessor.HttpContext.RequestServices.GetService<TService>();
    }
    

    Of course this would only work when you call this method in a scope of a http request.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search