LightInject - No scope when calling WebApi OWIN Identity TokenEndpointPath

1.4k views Asked by At

I have a very basic WebAPI setup with token authentication.
In the application start I do:

protected void Application_Start()
{
    DependencyConfig.RegisterDependecis();
    //...
    //...
}

Which calls:

public class DependencyConfig
{
    private static ServiceContainer _LightInjectContainer;

    public static ServiceContainer LightInjectContainer
    {
        get { return _LightInjectContainer; }
    }

    public static void RegisterDependecis()
    {
        var container = new LightInject.ServiceContainer();
        container.RegisterApiControllers();
        container.ScopeManagerProvider = new PerLogicalCallContextScopeManagerProvider();
        container.EnableWebApi(GlobalConfiguration.Configuration);

        container.Register<IRegistrationManager, RegistrationManager>(new PerScopeLifetime());

        _LightInjectContainer = container;
    }
}

Now, when the client invokes the token endpoint (requests a token), the provider I defined here:

OAuthOptions = new OAuthAuthorizationServerOptions
{
    //...
    //...
    Provider = new SimpleAuthorizationServerProvider()
    //...
    //...
};

Is being used with this method:

public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
    //...

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        //...
        // Here I get the exception!
        var registrationManager = DependencyConfig.LightInjectContainer.GetInstance<IRegistrationManager>();
        //...
    }

    //...
}

And when I try to get the instance the following error:

Attempt to create a scoped instance without a current scope.

I know the LightInject has a concept of Start/End scope for each request and It's actually telling me that no scope was started. But I can't seem to figure what exactly is broken and needs to be fixed.

2

There are 2 answers

5
Yaron Levi On BEST ANSWER

By reading on of the last answers in this question, I came up with this solution: (Starting a scope manually)

using(DependencyConfig.LightInjectContainer.BeginScope())
{
    IRegistrationManager manager = DependencyConfig.LightInjectContainer.GetInstance<IRegistrationManager>();
}

Technicaly it works, but I not sure if it's the right solution regarding whats happening behind the scenes.

4
seesharper On

I am the author of LightInject

Can you try this inside your handler(SimpleAuthorizationServerProvider)

request.GetDependencyScope().GetService(typeof(IRegistrationManager)) as IRegistrationManager;

There is actually no reason that you should expose the container as a static public member as this makes it very easy to start using the service locator anti-pattern.

Take a look at this blog post for more information.

http://www.strathweb.com/2012/11/asp-net-web-api-and-dependencies-in-request-scope/