2
votes

I can't seem to use the DependencyResolver in my OAuthAuthorizationServerProvider.

DependencyResolver.Current

returns the MVC one which I don't use, and

GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IXXX))

throws the following error:

No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.

Any ideas if I am doing something wrong or I simply can't use a dependency where I'm trying?

This is what my Startup.Auth.cs looks like:

        var config = new HttpConfiguration();

        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
          name: "DefaultApi",
          routeTemplate: "api/{controller}/{action}/{id}",
          defaults: new { id = RouteParameter.Optional }
          );

        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

        var builder = new ContainerBuilder();
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
        builder.RegisterType<XXX>().As<IXXX>().InstancePerRequest();

        var container = builder.Build();

        //I've tried  both approached here!
        GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container); 
        config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
        app.UseAutofacMiddleware(container);
        app.UseAutofacWebApi(webApiConfig);
        app.UseWebApi(webApiConfig);

And this is my OAuth provider code:

public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
    public SimpleAuthorizationServerProvider(string publicClientId)
    {
        if (publicClientId == null)
            throw new ArgumentNullException("publicClientId");
        _publicClientId = publicClientId;
    }

    public IXXX XXX
    {
        get { return (IXXX)(_xxx??GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IXXX))); }
        set { _xxx= value; }
    }

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        //Dependency IXXX used here
    }

    private readonly string _publicClientId;
    private IXXX _xxx;
}
2

2 Answers

1
votes

You can use OwinContext.GetAutofacLifetimeScope()

See the nuget package: http://alexmg.com/owin-support-for-the-web-api-2-and-mvc-5-integrations-in-autofac/

0
votes

Funnily enough I'm working through a similar problem at the minute and using the following OSS library to achieve this: https://github.com/DotNetDoodle/DotNetDoodle.Owin.Dependencies

This is an IoC container adapter for OWIN middleware, which puts a request level container into the environment dictionary of the OWIN middleware. The container can then be accessed from within your OWIN middleware implementation from which per-request scoped services can be resolved.

This is taken from the documentation from the github repository:

public override async Task Invoke(IOwinContext context)
{
    IServiceProvider requestContainer = context.Environment.GetRequestContainer();
    IRepository repository = requestContainer.GetService(typeof(IRepository)) as IRepository;

    // use repos
}

The following additional links may be useful for you:

Hope some of this may be of help to you.