5

I have been trying to get stateless auth with JWTs working using Nancy on dotnet core. I am running this on an Ubuntu VM. But I keep running into a cannot resolve type error in my Startup.cs at x.UseNancy();

My startup class looks like this:

public class Startup
{
   public static IConfigurationRoot Configuration;



   public Startup(IHostingEnvironment env)
   {
        Configuration = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json")
            .AddEnvironmentVariables()
            .Build();
   }

    public void Configure(IApplicationBuilder app)
    {
        app.UseOwin(x =>
        {
            x.RequiresStatelessAuth(
                new MySecureTokenValidator(new ConfigProvider(Configuration)),
                new StatelessAuthOptions() { IgnorePaths = new List<string>(new[] { "/login", "/content" }) });
            x.UseNancy();
        });
    }
}

My ConfigProvider class:

public class ConfigProvider : IConfigProvider
{
    private readonly IConfigurationRoot config;

    public ConfigProvider(IConfigurationRoot config)
    {
        this.config = config;
    }

    public string GetAppSetting(string propertyName)
    {
        return config.GetSection($"AppSettings:{propertyName}").ToString();
    }
}

RequiresStatelessAuth Extension:

using MidFunc = System.Func<System.Func<System.Collections.Generic.IDictionary<string, object>,
    System.Threading.Tasks.Task>, System.Func<System.Collections.Generic.IDictionary<string, object>,
    System.Threading.Tasks.Task>>;

public static class StatelessAuthExtensions
{
    public static Action<MidFunc> RequiresStatelessAuth(this Action<MidFunc> builder, ITokenValidator tokenValidator, StatelessAuthOptions options = null)
    {
         builder(next => new StatelessAuth(next, tokenValidator, options).Invoke);
         return builder;
    }
}

HomeModule:

public class HomeModule : NancyModule
{
    public HomeModule(IConfigProvider configProvider, IJwtWrapper jwtWrapper)
    {
        //some code here
    }
}

I am not registering anything with the IoC container. But I have tried the below in my bootstrapper:

protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
    base.ConfigureApplicationContainer(container);
    container.Register<IConfigProvider, ConfigProvider>();
    container.Register<ConfigurationRoot>();
}

For that to work, I changed IConfigurationRoot to ConfigurationRoot across the application.

Whatever I have tried I get the same error. Stacktrace:

Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: Nancy.NancyEngine
 ---> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: Nancy.Routing.DefaultRequestDispatcher
 ---> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: Nancy.Routing.DefaultRouteResolver
 ---> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: Nancy.Routing.RouteCache
 ---> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: nancyTest.HomeModule
 ---> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: ConfigProvider
 ---> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: Microsoft.Extensions.Configuration.ConfigurationRoot
 ---> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: Microsoft.Extensions.Configuration.ConfigurationRoot
 ---> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: System.Collections.Generic.IList`1[[Microsoft.Extensions.Configuration.IConfigurationProvider, Microsoft.Extensions.Configuration.Abstractions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]]\n
   at Nancy.TinyIoc.TinyIoCContainer.ResolveInternal(TypeRegistration registration, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.ConstructType(Type requestedType, Type implementationType, ConstructorInfo constructor, NamedParameterOverloads parameters, ResolveOptions options)\n  
   --- End of inner exception stack trace ---\n
   at Nancy.TinyIoc.TinyIoCContainer.ConstructType(Type requestedType, Type implementationType, ConstructorInfo constructor, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.MultiInstanceFactory.GetObject(Type requestedType, TinyIoCContainer container, NamedParameterOverloads parameters, ResolveOptions options)\n  
   --- End of inner exception stack trace ---\n
   at Nancy.TinyIoc.TinyIoCContainer.MultiInstanceFactory.GetObject(Type requestedType, TinyIoCContainer container, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.ResolveInternal(TypeRegistration registration, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.ConstructType(Type requestedType, Type implementationType, ConstructorInfo constructor, NamedParameterOverloads parameters, ResolveOptions options)\n  
   --- End of inner exception stack trace ---\n
   at Nancy.TinyIoc.TinyIoCContainer.ConstructType(Type requestedType, Type implementationType, ConstructorInfo constructor, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.SingletonFactory.GetObject(Type requestedType, TinyIoCContainer container, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.SingletonFactory.GetFactoryForChildContainer(Type type, TinyIoCContainer parent, TinyIoCContainer child)\n
   at Nancy.TinyIoc.TinyIoCContainer.GetParentObjectFactory(TypeRegistration registration)\n
   at Nancy.TinyIoc.TinyIoCContainer.ResolveInternal(TypeRegistration registration, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.ConstructType(Type requestedType, Type implementationType, ConstructorInfo constructor, NamedParameterOverloads parameters, ResolveOptions options)\n  
   --- End of inner exception stack trace ---\n
   at Nancy.TinyIoc.TinyIoCContainer.ConstructType(Type requestedType, Type implementationType, ConstructorInfo constructor, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.SingletonFactory.GetObject(Type requestedType, TinyIoCContainer container, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.ResolveInternal(TypeRegistration registration, NamedParameterOverloads parameters, ResolveOptions options)\n
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()\n
   at System.Linq.Enumerable.<CastIterator>d__29`1.MoveNext()\n
   at Nancy.Routing.RouteCache.BuildCache(IEnumerable`1 modules)\n
   at Nancy.Routing.RouteCache..ctor(INancyModuleCatalog moduleCatalog, INancyContextFactory contextFactory, IRouteSegmentExtractor routeSegmentExtractor, IRouteDescriptionProvider routeDescriptionProvider, ICultureService cultureService, IEnumerable`1 routeMetadataProviders)\n
   at lambda_method(Closure , Object[] )\n
   at Nancy.TinyIoc.TinyIoCContainer.ConstructType(Type requestedType, Type implementationType, ConstructorInfo constructor, NamedParameterOverloads parameters, ResolveOptions options)\n  
   --- End of inner exception stack trace ---\n
   at Nancy.TinyIoc.TinyIoCContainer.ConstructType(Type requestedType, Type implementationType, ConstructorInfo constructor, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.SingletonFactory.GetObject(Type requestedType, TinyIoCContainer container, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.ResolveInternal(TypeRegistration registration, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.ConstructType(Type requestedType, Type implementationType, ConstructorInfo constructor, NamedParameterOverloads parameters, ResolveOptions options)\n  
   --- End of inner exception stack trace ---\n
   at Nancy.TinyIoc.TinyIoCContainer.ConstructType(Type requestedType, Type implementationType, ConstructorInfo constructor, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.SingletonFactory.GetObject(Type requestedType, TinyIoCContainer container, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.ResolveInternal(TypeRegistration registration, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.ConstructType(Type requestedType, Type implementationType, ConstructorInfo constructor, NamedParameterOverloads parameters, ResolveOptions options)\n  
   --- End of inner exception stack trace ---\n
   at Nancy.TinyIoc.TinyIoCContainer.ConstructType(Type requestedType, Type implementationType, ConstructorInfo constructor, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.SingletonFactory.GetObject(Type requestedType, TinyIoCContainer container, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.ResolveInternal(TypeRegistration registration, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.ConstructType(Type requestedType, Type implementationType, ConstructorInfo constructor, NamedParameterOverloads parameters, ResolveOptions options)\n  
   --- End of inner exception stack trace ---\n
   at Nancy.TinyIoc.TinyIoCContainer.ConstructType(Type requestedType, Type implementationType, ConstructorInfo constructor, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.SingletonFactory.GetObject(Type requestedType, TinyIoCContainer container, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.ResolveInternal(TypeRegistration registration, NamedParameterOverloads parameters, ResolveOptions options)\n
   at Nancy.TinyIoc.TinyIoCContainer.Resolve[ResolveType]()\n
   at Nancy.Bootstrapper.NancyBootstrapperBase`1.SafeGetNancyEngineInstance()}

I am a total Nancy/Linux/dotnet core noob, can someone explain how to resolve this issue?

EDIT, working code:

Bootstrapper changes:

public class CustomBootstrapper : DefaultNancyBootstrapper
{
    private ConfigurationRoot config;

    public CustomBootstrapper(ConfigurationRoot config)
    {
        this.config = config;
    }

    protected override void ConfigureApplicationContainer(TinyIoCContainer container)
    {
        base.ConfigureApplicationContainer(container);
        container.Register<ConfigurationRoot>(config);
    }

    //more code
}

Startup.cs:

public void Configure(IApplicationBuilder app)
{
    app.UseOwin(x =>
    {
        x.RequiresStatelessAuth(
            new MySecureTokenValidator(new ConfigProvider((ConfigurationRoot)Configuration)),
            new StatelessAuthOptions() { IgnorePaths = new List<string>(new[] { "/login", "/content" }) });
        x.UseNancy(opts => opts.Bootstrapper = new CustomBootstrapper((ConfigurationRoot)Configuration));
    });
}

Site note: I will probably change Configuration in Startup.cs to be of type ConfigurationRoot, and then do the type cast just once in the constructor of Startup.cs - rather than twice in Configure as above.

user3574076
  • 711
  • 1
  • 6
  • 23
  • 1
    Do you have a reference to Microsoft.Extensions.Configuration in project.json? – Jon Oct 22 '16 at 09:53
  • 1
    You might also have to register like so container.Register(myInstanceOfConfigurationRoot); To do this you would have to pass it into your bootstrapper constructor from your Startup class x.UseNancy(opts => opts.Bootstrapper = new Bstrapper(myConfigRoot)); – Jon Oct 22 '16 at 09:55
  • @Jon That was it! I just needed to create a constructor on my bootstrapper, pass in Configuration, and register it as you suggested. If you post your comment as an answer I will accept it. Thanks! – user3574076 Oct 22 '16 at 15:33
  • Maybe it is better/clearer to put the solution as an "Answer" on your own post. – Patrick Koorevaar Feb 16 '22 at 15:14

0 Answers0