Search code examples
c#asp.net-web-apiowinasp.net-identity-2simple-injector

SimpleInjector doesn't work - Web API on OWIN


OwinStartup.cs

public class OwinStartup
{
    internal static IDataProtectionProvider DataProtectionProvider { get; private set; }

    public void Configuration(IAppBuilder app)
    {
        DataProtectionProvider = app.GetDataProtectionProvider();
        var config = new HttpConfiguration();

        SimpleInjectorConfig.Configure(app);
        ConfigureOAuth(app);
        WebApiConfig.Register(config);
        app.UseCors(CorsOptions.AllowAll);
        app.UseWebApi(config);  
    }

    private static void ConfigureOAuth(IAppBuilder app)
    {
        app.CreatePerOwinContext(
            () => (IDisposable)GlobalConfiguration.Configuration.DependencyResolver.GetService(
                typeof(AppUserManager)));

        var options = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new AppAuthProvider(),
            AllowInsecureHttp = true,
        };

        app.UseOAuthAuthorizationServer(options);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
    }
}

SimpleInjectorConfig.cs

public static class SimpleInjectorConfig
{
    public static void Configure(IAppBuilder app)
    {
        var container = new Container();
        container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();

        //allows scoped instances to be resolved during OWIN request
        app.Use(async (context, next) =>
        {
            using (AsyncScopedLifestyle.BeginScope(container))
            {
                await next();
            }
        });

        container.Register<AppIdentityDbContext>(Lifestyle.Scoped);
        container.Register<AppUserManager>(Lifestyle.Scoped);
        container.Register(
            () =>
                container.IsVerifying
                    ? new OwinContext().Authentication
                    : HttpContext.Current.GetOwinContext().Authentication, Lifestyle.Scoped);
        container.Register<AppSignInManager>(Lifestyle.Scoped);

        container.Verify();

        GlobalConfiguration.Configuration.DependencyResolver =
            new SimpleInjectorWebApiDependencyResolver(container);
    }
}

So in my implemenation of OAuthAuthorizationServerProvider called AppAuthProvider Im trying to get instance of AppUserManager ( I need to find user ) using this code:

var manager = context.OwinContext.Get<AppUserManager>();

But dont know why I still get null. I really dont know what to do because everythings seems to be configured correctly. Any ideas ? Thanks !


Solution

  • I found a solution. Updated code below:

    OwinStartup.cs

     public class OwinStartup
    {
        internal static IDataProtectionProvider DataProtectionProvider { get; private set; }
    
        public void Configuration(IAppBuilder app)
        {
            DataProtectionProvider = app.GetDataProtectionProvider();
            var container = SimpleInjectorConfig.Configure();
    
            //allows scoped instances to be resolved during OWIN request
            app.Use(async (context, next) =>
            {
                using (AsyncScopedLifestyle.BeginScope(container))
                {
                    await next();
                }
            });
    
            var config = new HttpConfiguration
            {
                DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container)
            };
    
            ConfigureOAuth(app, config);
            WebApiConfig.Register(config);
            app.UseCors(CorsOptions.AllowAll);
            app.UseWebApi(config);  
        }
    
        private static void ConfigureOAuth(IAppBuilder app, HttpConfiguration config)
        {
            app.CreatePerOwinContext(
                () => (AppUserManager)config.DependencyResolver.GetService(
                    typeof(AppUserManager)));
    
            var options = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/Token"),
                Provider = new AppAuthProvider(),
                //TODO: Change in production.
                AllowInsecureHttp = true,
            };
    
            app.UseOAuthAuthorizationServer(options);
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        }
    }
    

    SimpleInjectorConfig.cs

     public static class SimpleInjectorConfig
    {
        public static Container Configure()
        {
            var container = new Container();
            container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
    
            container.Register<AppIdentityDbContext>(Lifestyle.Scoped);
            container.Register<AppUserManager>(Lifestyle.Scoped);
            container.Register(
                () =>
                    container.IsVerifying
                        ? new OwinContext().Authentication
                        : HttpContext.Current.GetOwinContext().Authentication, Lifestyle.Scoped);
            container.Register<AppSignInManager>(Lifestyle.Scoped);
    
            container.Verify();
    
            return container;
        }
    }
    

    Maybe someone will use it.