MVC 5 template (ASP.Net Identity 2.0) combined with Simple Injector

Sep 1, 2014 at 1:33 PM
Edited Sep 15, 2014 at 7:26 PM
When you start a new MVC 5 project using the newly added templates in VS 2013 you’ll you get to use the new ASP.net Identity 2 framework. The ASP.Net Identity framework 2.0 depends heavily on the Microsoft implementation of Owin. Therefore the template will add a load of files together with some specific Owin startup files, as Owin defines his own startup, working next to the also existing Appplication_Start() event in the Global.asax file. When you first run the application, all works out-of-box. You can even add users and directly authenticate using this newly add user.

But then, as soon as you add Simple injector, all stops… It took me quite some time to figure out which adjustments I needed to make, to keep using the new identity framework together with Simple Injector. Therefore I’m sharing my solution, hoping to help somebody, struggling with the same questions.
First of all let us take a look at what the template gives us (only the items that needs changing for use with Simple Injector):

Startup_auth.cs: Some configuration of the poor man’s D.I. container functionality of the OWIN appcontext. This will create a ApplicationUserManager per web request using the Create() function of the ApplicationUserManager class.

AccountController.cs: The MVC controller for account management. This class has 2 constructors. A default constructor and one where ApplicationUserManager class can be injected. Therefore the templates defines a property to fix the issue of a null value for the usermanager when the default constructor was called.
When you get Simple Injector from NuGet and run the application, verifying of the container throws an exception:

>> SimpleInjector.ActivationException: For the container to be able to create AccountController, it should contain exactly one public constructor, but it has 2

Solution:

Off course the solution is to delete the default constructor from the AccountController. But then Simple Injector needs to know about the ApplicationUserManager. So let’s start to do some changes:
First the DbContext (ApplicationDbContext). Remove the Factory method Create(). And change the constructor to:
public ApplicationDbContext(string connectionstring)
    : base(connectionstring, throwIfV1Schema: false)
{
}
You want to change the constructor in this way, because in this way you can do your configuration in the composition root instead of the ugly solution where the configuration is in the constructor, as is default in the template.

Secondly you can remove the factory method Create() from the ApplicationUserManager class.
Third remove these two lines from the OWIN startup file (we add one of them back in later):
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(
    ApplicationUserManager.Create);
If you used the Simple Injector MVC quick start remove the WebActivator attribute from the SimpleInjectorInitializer class and replace the code with:
namespace MVC5_SI.App_Start
{
    using System.Reflection;
    using System.Web.Mvc;
    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using Microsoft.AspNet.Identity.Owin;
    using Microsoft.Owin.Security.DataProtection;
    using MVC5_SI.Models;
    using Owin;
    using SimpleInjector;
    using SimpleInjector.Advanced;
    using SimpleInjector.Integration.Web.Mvc;
 
    public static class SimpleInjectorInitializer
    {
        public static Container Initialize(IAppBuilder app)
        {
            var container = GetInitializeContainer(app);
 
            container.Verify();
 
            DependencyResolver.SetResolver(
                new SimpleInjectorDependencyResolver(container));
       
            return container;
        }
 
        public static Container GetInitializeContainer(
                  IAppBuilder app)
        {
            var container = new Container();
 
            container.RegisterSingle<IAppBuilder>(app);
 
            container.RegisterPerWebRequest<
                   ApplicationUserManager>();
            
            container.RegisterPerWebRequest<ApplicationDbContext>(() 
              => new ApplicationDbContext(
               "Your constring goes here"));
            
            container.RegisterPerWebRequest<IUserStore<
              ApplicationUser>>(() => 
                new UserStore<ApplicationUser>(
                  container.GetInstance<ApplicationDbContext>()));
 
            container.RegisterInitializer<ApplicationUserManager>(
                manager => InitializeUserManager(manager, app));
 
            container.RegisterMvcControllers(
                    Assembly.GetExecutingAssembly());
 
            return container;
        }

        private static void InitializeUserManager(
            ApplicationUserManager manager, IAppBuilder app)
        {
            manager.UserValidator = 
             new UserValidator<ApplicationUser>(manager)
            {
                AllowOnlyAlphanumericUserNames = false,
                RequireUniqueEmail = true
            };

            //Configure validation logic for passwords
            manager.PasswordValidator = new PasswordValidator()
            {
                RequiredLength = 6,
                RequireNonLetterOrDigit = false,
                RequireDigit = true,
                RequireLowercase = true,
                RequireUppercase = true,
            };
 
            var dataProtectionProvider = 
                 app.GetDataProtectionProvider();
            
            if (dataProtectionProvider != null)
            {
                manager.UserTokenProvider = 
                 new DataProtectorTokenProvider<ApplicationUser>(
                  dataProtectionProvider.Create("ASP.NET Identity"));
            }
        }
    }
}
Then change the code of the OWIN Configuration method in the startup class to:
public void Configuration(IAppBuilder app)
{
    var container = SimpleInjectorInitializer.Initialize(app);
    ConfigureAuth(app, container);
}
Now go back to the ConfigureAuth method and change the signature to:
public void ConfigureAuth(IAppBuilder app, Container container)
{
//...code
}
Then recreate the line to register the ApplicationUserManager within the OwinContext like this:
app.CreatePerOwinContext(() => container.GetInstance<ApplicationUserManager>());
This is necessary because Owin internally also uses the ‘ApplicationUserManager’ and tries to get this from the OwinContext. (see for reference Trailmax Tech)

Last but not least, do not forget to delete the default constructor from the AccountController. And while you’re at it, remove the UserManager property and rename the private field from _userManager to UserManager.

Now you should be good to go.
Sep 10, 2014 at 6:47 AM
Can you please assist on registering the ApplicationSignInManager with Simple Injector
Sep 10, 2014 at 10:29 AM
Edited Mar 10, 2015 at 1:14 PM
Supposing you use the template implementation for the ApplicationSignInManager class, you can register this class as:
container.RegisterPerWebRequest<SignInManager<ApplicationUser, string>, ApplicationSignInManager>();
And for the second constructor parameter IAuthenticationManager the registration is somewhat different:
container.RegisterPerWebRequest<IAuthenticationManager>(() => 
    AdvancedExtensions.IsVerifying(container) 
        ? new OwinContext(new Dictionary<string, object>()).Authentication 
        : HttpContext.Current.GetOwinContext().Authentication); 
Because the IAuthenticationManager is depending upon an OwinContext, verifying the container will fail, because no such context will be there at verifying time. Therefore we will create a new OwinContext during verifying the container and return the Authentication component from this newly created OwinContext. Note that when the container isn't verifying the OwinContext should exist and we just return the 'normal' Authentication component from the OwinContext.

With above registration you can inject the ApplicationSignInManager in your controller or other classes as:
SignInManager<ApplicationUser, string> signInManager and then use it directly.
Sep 15, 2014 at 10:37 AM
Can you please help me register the RoleManager? I have everything else you listed done.

//Identity.config
public class ApplicationRoleManager : RoleManager<IdentityRole>
    {
        public ApplicationRoleManager(IRoleStore<IdentityRole, string> roleStore)
            : base(roleStore)
        {
        }

        public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
        {
            return new ApplicationRoleManager(new RoleStore<IdentityRole>(context.Get<ApplicationDbContext>()));
        }
    }
I also added this in the startup.auth
app.CreatePerOwinContext(() => container.GetInstance<ApplicationRoleManager>());
My problem is here Trying to register this but it is failing in the SimpleInjectorInitializer. It won't compile.
container.RegisterPerWebRequest<RoleManager<IRoleStore<IdentityRole, string>>, ApplicationRoleManager>();
Thank you in advance.
Sep 15, 2014 at 12:00 PM
Edited Sep 15, 2014 at 12:05 PM
mhead11,

You can delete the Create() method from the Identity Config. Also no need to register the RoleManager with Owin, so remove the call to CreatePerOwinContext

You can register the ApplicationRoleManager just like the UserManager. Like:
container.RegisterPerWebRequest<ApplicationRoleManager>();

container.RegisterPerWebRequest<IRoleStore<IdentityRole, string>>(
        () => new RoleStore<IdentityRole>(
              container.GetInstance<ApplicationDbContext>()));
And that should do it.
Nov 25, 2014 at 6:15 PM
Is it possible to acquire and register IOwinContext without using HttpContext.Current?
Nov 25, 2014 at 7:57 PM
No, the owin context is saved in the HttpContext. To get it you must access the context and use the extension method. The extension method is offcourse optional, but the most easy way.
Dec 5, 2014 at 6:20 PM
On the IdentityFramework 2.1, inside the class ApplicationDbContext, there is a static constructor static ApplicationDbContext() that calls the ApplicationDbInitializer() to seed the database. How would I go about registering / setting that initializer as well? That ApplicationDbInitializer() references userManager and roleManager via HttpContext.Current.GetOwinContext().

Or do I just not need to do anything and whenever I request the ApplicationDbContext() instance it will run that initializer for me if the model has been changed (I have it inherit from DropCreateDatabaseIfModelChanges)?
Dec 6, 2014 at 9:49 AM
I downloaded asp.net identity 2.1 but I can't find a static constructor in the generated code. I must be doing something wrong. So please post the code, or show how I can install the template you used.
Dec 6, 2014 at 5:35 PM
It's in the pre-release sample package. Here are the steps to install that template: (I am using Visual Studio Community 2013)
  1. Create a new project, then select Visual C# -> Web -> ASP.NET Web Application
  2. Pick the empty template.
  3. Open the NuGet package manager, click the dropdown to include pre-releases, and search "Microsoft.AspNet.Identity.Samples".
  4. Installing that should give you a MVC-like project template. I will go ahead and update all the packages just to make sure I get the latest of everything. Make sure you switch back to stable only rather than include releases when you do the updates.
  5. The Visual Studio should need to be restarted.
  6. The static constructor of ApplicationDbContext should be located under /Models/IdentityModels.cs.
Thanks a lot for the time you spent trying to help!
Dec 6, 2014 at 11:06 PM
Edited Dec 8, 2014 at 1:44 PM
@davidliang2008
I managed to download and install the sample.

The ApplicationDbInitializer will seed your Db when you change the model. So the first thing you should ask yourself is, do I really need that functionality? And second, but I suppose you already know that, the code supplied by the sample is highly unlikely and undesirable to be used in production code. Creating a default admin user in the admin role like this is just evil, even for an example IMO.

That being said, let me answer your question.
The static constructor in ApplicationDbContext only calls SetInitializer() on the static Database class. You can call this from anywhere in your application so the nasty static constructor from the template is really strange. They could have just as easily used the original 'Composition root' of the template: ConfigureAuth() and this solution would be much more straightforward to understand. Enough said, some code:

The composition root is the place to be for this code to run. Assuming your using a bootstrapper like mentioned in the first post, you can change the bootstrapper from the first post to
public static class SimpleInjectorInitializer
        {
            public static Container Initialize(IAppBuilder app)
            {
                var container = GetInitializeContainer(app);
 
                container.Verify();
 
                DependencyResolver.SetResolver(
                    new SimpleInjectorDependencyResolver(container));
 
                // set the db initializer after verifying the container
                // just ask the container for a new instance
                var dbInitializer = container.GetInstance<ApplicationDbInitializer>();
                Database.SetInitializer(dbInitializer);
 
                return container;
            }
 
            public static Container GetInitializeContainer(
                      IAppBuilder app)
            {
                var container = new Container();
            
                // a singleton is perfect as it will be used once or never
                container.RegisterSingle<ApplicationDbInitializer>();
 
                container.RegisterSingle<Func<ApplicationUserManager>>(
                                () => container.GetInstance<ApplicationUserManager>());
                container.RegisterSingle<Func<ApplicationRoleManager>>(
                                () => container.GetInstance<ApplicationRoleManager>());
 
                // rest of the code mentioned above;
Notice that I made registrations for UserManager and RoleManger factories. This is needed because the more or less ’static’ ApplicationDbInitializer class depends on User- and RoleManager which both have a shorter lifetime definied (PerWebRequest). So when the Seed() method will be called we need to resolve the then current instances of the ApplicationUserManager and ApplicationRoleManager.

Now we have registrations for the ApplicationDbInitializer class and both factories we can setup our ApplicationDbInitializer using D.I. and remove the need for using the HttpContext and actually use the service locator anti pattern. This would look something like:
public class ApplicationDbInitializer : DropCreateDatabaseIfModelChanges<ApplicationDbContext> 
{
    private readonly Func<ApplicationRoleManager> roleManagerFactory;
    private readonly Func<ApplicationUserManager> userManagerFactory;
 
    public ApplicationDbInitializer(Func<ApplicationUserManager> userManagerFactory, 
        Func<ApplicationRoleManager> roleManagerFactory)
    {
        this.userManagerFactory = userManagerFactory;
        this.roleManagerFactory = roleManagerFactory;
    }
    
    protected override void Seed(ApplicationDbContext context) {
        this.InitializeIdentityForEF(context);
        base.Seed(context);
    }
 
    //Create User=Admin@Admin.com with password=Admin@123456 in the Admin role        
    public void InitializeIdentityForEF(ApplicationDbContext db) {
        // get a instance from the factory
        var userManager = this.userManagerFactory.Invoke();
        var roleManager = this.roleManagerFactory.Invoke();
        
        // rest of code omitted for brevity...
It did a quick test and it works as expected.
Dec 8, 2014 at 7:51 PM
Thank you!!!
Dec 16, 2014 at 4:14 PM
Edited Dec 16, 2014 at 4:14 PM
Has anyone tried this with webapi?
I am trying to implement simple injector with webapi but the following code fails.
app.CreatePerOwinContext(() => container.GetInstance<ApplicationUserManager>());
the message says "The ApplicationUserManager is registered as 'Web API Request' lifestyle, but the instance is requested outside the context of a Web API Request."
This makes sense, but then I wonder how will we assign ApplicationUserManager to OWIN context. Any help is appreciated. Thanks.
Dec 16, 2014 at 8:08 PM
Edited Dec 16, 2014 at 8:17 PM
EDIT
Sorry, I composed the answer below and then reread your question and suddenly realized you allready use the WebApiRequest Lifestyle. Apologies for the useless answer. I nevertheless do not delete it, because using the WebApiRequest Lifestyle should be the way to go. I will spend some time myself with WebApi to test it. Give me some time and I will come back to you.

Allthough I have never tried the ASP.Net identity framework with WebApi the error you receive has to do with the lifestyle of the requested object. When using WepApi you need a specific WebApi Request lifestyle for all the types you want to request within the lifetime of a WebApi request such as e.g. DbContext, and every type depending on this DbContext. Another example would be a unit of work service.

You can read all about the integration of SimpleInjector with WepApi and the different lifestyles in the WebApi integration guide. You'll find that the WebApiRequestLifestyle differs from the WebRequestLifestyle as used in the configuration from the first post.

Please share your results and/or come back if you need any assistance!
Dec 17, 2014 at 5:45 AM
Thanks for the feedback.
Yes, I already use RegisterWebApiRequest. Everything works fine if we swap RegisterWebApiRequest for Register in GetInitializeContainer. But it's not the preferred method as per the simpleinjector docs.
I am still fiddling with the configuration. Please let me know if you happen to find a solution.
Dec 18, 2014 at 11:04 PM
Edited Dec 18, 2014 at 11:13 PM
I have a problem. When I typing a wrong password a few times, I've didn't get lockout. I think problem is somewhere in OWIN side. I've use MVC 5.1, IIS Express, VS2013.4, EF6, LocalDB.
In default VS 2013 project (withouit DI) everything works fine.
I use this code-template from this discussion in my mvc application.

And a little question. Why we use HttpContext.GetOwinContext().Get<ApplicationSignInManager>() for SignInManager property in AccountController? Why we can not use injection through constructor?

P.S. - Sorry for my English.
Dec 18, 2014 at 11:12 PM
Edited Dec 18, 2014 at 11:14 PM
You need to make sure you enable the lockout feature.

2 places you need to check:
  1. In the IdentityConfig.cs under App_Start folder, under the Create method, make sure you have manager.UserLockoutEnabledByDefault = true;. You can also set the lockout timespan like manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); and set the max number of attempts it allows like manager.MaxFailedAccessAttemptsBeforeLockout = 5;.
  2. In the Login method under Account controller, you need to set true on the shouldLockout flag, i.e., var result = await SingInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: true);.
I am not sure if I have answered your question. If you try the above and they don't work out, please give us more details.

Thanks,
David Liang
Dec 19, 2014 at 12:16 AM
Edited Dec 19, 2014 at 12:33 AM
Everything as you say, but it still didn't work for me. Please watch to my code and please tell me where is my mistake.
Thank you for your help!

Here is my Global.asax
public class MvcApplication : HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            SimpleInjectorConfig.RegisterDependencies();
        }
    }
Here is my Startup
public partial class Startup
    {
        internal static IDataProtectionProvider DataProtectionProvider { get; private set; }

        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
            DataProtectionProvider = app.GetDataProtectionProvider();
        }
    }
Here is my InjectionsConfig
public class SimpleInjectorConfig
    {

        public static void RegisterDependencies()
        {
            var container = new Container();
            container.RegisterPerWebRequest<AppDbContext>();
            container.RegisterPerWebRequest<UserStore>(() => new UserStore(container.GetInstance<AppDbContext>()));
            container.RegisterPerWebRequest<RoleStore>(() => new RoleStore(container.GetInstance<AppDbContext>()));
            container.RegisterPerWebRequest<ApplicationSignInManager>(() => new ApplicationSignInManager(
                container.GetInstance<ApplicationUserManager>(),
                container.GetInstance<IAuthenticationManager>()));
            container.RegisterPerWebRequest<ApplicationUserManager>(() => new ApplicationUserManager(container.GetInstance<UserStore>()));
            container.RegisterPerWebRequest<IAuthenticationManager>(() => HttpContext.Current.GetOwinContext().Authentication);
            container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
            container.RegisterMvcIntegratedFilterProvider();

            DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
        }
    }
Here is my ApplicationUserManager
    public class ApplicationUserManager : UserManager<User, long>
    {
        public ApplicationUserManager(IUserStore<User, long> store)
            : base(store)
        {
            this.UserValidator = new UserValidator<User, long>(this)
            {
                AllowOnlyAlphanumericUserNames = false,
                RequireUniqueEmail = true
            };
            this.PasswordValidator = new PasswordValidator
            {
                RequiredLength = 6,
                RequireNonLetterOrDigit = false,
                RequireDigit = true,
                RequireLowercase = true,
                RequireUppercase = true
            };
            this.UserLockoutEnabledByDefault = true;
            this.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
            this.MaxFailedAccessAttemptsBeforeLockout = 2;
            var dataProtectionProvider = Startup.DataProtectionProvider;
            if (dataProtectionProvider != null)
            {
                this.UserTokenProvider =
                    new DataProtectorTokenProvider<User, long>(dataProtectionProvider.Create("ASP.NET Identity"))
                    {
                        TokenLifespan = TimeSpan.FromHours(3)
                    };
            }
        }
    }
And Here is my AccountController
[Authorize]
    public class AccountController : Controller
    {
        private IAuthenticationManager _authenticationManager;
        private ApplicationSignInManager _signInManager;
        private ApplicationUserManager _applicationUserManager;

        public AccountController(IAuthenticationManager authenticationManager)
        {
            _authenticationManager = authenticationManager;
        }

        private IAuthenticationManager AuthenticationManager
        {
            get { return _authenticationManager; }
        }

        private ApplicationSignInManager SignInManager
        {
            get
            {
                return _signInManager ?? (_signInManager = new ApplicationSignInManager(ApplicationUserManager, AuthenticationManager));
            }
        }

        private ApplicationUserManager ApplicationUserManager
        {
            get
            {
                return _applicationUserManager ?? (_applicationUserManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>());
            }
        }

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }
            var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: true);
            switch (result)
            {
                case SignInStatus.Success:
                    return RedirectToLocal(returnUrl);
                case SignInStatus.LockedOut:
                    return View("Lockout");
                default:
                    ModelState.AddModelError("", "Неудачная попытка входа.");
                    return View(model);
            }
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult LogOff()
        {
            AuthenticationManager.SignOut();
            return RedirectToAction("Index", "Home");
        }

        private ActionResult RedirectToLocal(string returnUrl)
        {
            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            return RedirectToAction("Index", "Home");
        }
}
Dec 19, 2014 at 12:42 AM
Edited Dec 19, 2014 at 12:43 AM
I think maybe by default OWIN somewhere saves count of failure attempts and after some fail attempts will locks account, but when I've use IoC container it creates new objects for each request.
Coordinator
Dec 20, 2014 at 12:27 PM
It would be very strange if OWIN saves the count of failure attempts in-memory instead of storing them in the user account database, because this would allow a hacker to have an unlimited amount of retries if he is able to cause a app domain recycle. That would be a quite severe security flaw.
Dec 20, 2014 at 7:49 PM
I managed to solve my issue using the method described by nicodega in this post
I used the following code right after registering the dependencies
public static void UseOwinContextInjector(this IAppBuilder app, Container container)
{
     // Create an OWIN middleware to create an execution context scope
     app.Use(async (context, next) =>
     {
         using (var scope = container.BeginExecutionContextScope())
         {
             await next.Invoke();
         }
     });
}
and then replaced var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>(); in ApplicationOAuthProvider with this one var userManager = Startup.Container.GetInstance<ApplicationUserManager>();

Thanks TheBigRic and nicodega
Feb 11, 2015 at 2:59 PM
Continuing on su8898, I need to register the context that exists in that lambda.

See, in OWIN this context holds request specific data.
In normal IIS hosted ASP.NET you could access this through the Static HttpContext.Current. When you are self hosted, you can't.

So please, anyone. How can I register that context as the implementation for IOwinContext??

Pseudo code:
public static void UseOwinContextInjector(this IAppBuilder app, Container container)
{
     // Create an OWIN middleware to create an execution context scope
     app.Use(async (context, next) =>
     {
         using (var scope = container.BeginExecutionContextScope())
         {
             container.Register<IOwinContext>( () => context); // <--- How? This code runs on every request.
             await next.Invoke();
         }
     });
}
Feb 13, 2015 at 8:55 AM
I'm not sure I understand the question correctly. I think you mean that the HttpContext is unavailable in a self hosted environment. And therefore you are unable to access the OwinContext.

The context will be, as you noticed available from the middleware. By creating a Context which holds the current IOwinContext you can inject this context in all classes you need it in. So let us define an IOwinContextContext:
public interface IOwinContextContext
{
    void SetCurrentOwinContext(IOwinContext owinContext);
    IOwinContext CurrentContext { get; } 
}
with this implementation:
public class OwinContextContext : IOwinContextContext
{
    private IOwinContext owinContext;

    public void SetCurrentOwinContext(IOwinContext owinContext)
    {
        this.owinContext = owinContext;
    }

    public IOwinContext CurrentContext
    {
        get { return this.owinContext; }
    }
}
By using the previous mentioned `ExecutionScopeStarter extension method (notice that I renamed this method, because the naming is a bit unclear to me). For completeness:
public static void UseBeginStartExecutionScope(this IAppBuilder app, Container container)
{
    // Create an OWIN middleware to create an execution context scope
    app.Use(async (context, next) =>
    {
        using (var scope = container.BeginExecutionContextScope())
        {
            await next.Invoke();
        }
    });
}
Secondly we could create middleware that retrieves the IOwinContextContext from the container and sets the current IOwinContext for the request. This will look something like (notice that I used the name previously used for beginning the execution scope):
public static void UseOwinContextInjector(this IAppBuilder app, Container container)
{
    app.Use(async (context, next) =>
    {
        var owinContextContext = container.GetInstance<IOwinContextContext>();
        owinContextContext.SetCurrentOwinContext(context);

        await next.Invoke();
    });
}
You would want to register the IOwinContextContext with a PerWebApiRequest lifestyle, like this:
    container.RegisterWebApiRequest<IOwinContextContext, OwinContextContext>();
And register the middleware in the Owin pipeline in this order:
    app.UseBeginStartExecutionScope(container);
    app.UseOwinContextInjector(container);
Use like this:
public class UserController : ApiController 
{
    private readonly IOwinContextContext owinContextContext;

    public UserController(IOwinContextContext owinContextContext) 
    {
        this.owinContextContext = owinContextContext;
    }

    public void SomeMethod()
    {
        var user = this.owinContextContext.CurrentContext.Request.User;
        // do something with user
    }
}
I think you need to ask yourself the question if this solution is exactly what you need. IOwinContext smells like a God class, given you access to all kinds of information. But do you need all this information everywhere you want to inject this context? Or do you only need a small part. In that case you always follow the exact same approach but not return the complete context but only the part you actually need. So for instance, you only need the current user from the context. Create an IUserContext like this:
public interface IUserContext
{
    void SetUser (IPrincipal user)
    IPrincipal User { get; } 
}
and create the extension method for injecting this in the Owin Middleware:
public static void UseOwinUserContextInjector(this IAppBuilder app, Container container)
{
    app.Use(async (context, next) =>
    {
        var userContext = container.GetInstance<IUserContext>();
        userContext.SetUser(context.Request.User);

        await next.Invoke();
    });
}
Hope this helped!
Feb 13, 2015 at 1:28 PM
Well, it helped but it still doesn't work!

It should work, but I don't get the same instance in the controller as I do in the middleware!

I have 3 middlewares and a testcontroller.

1 middleware creates the ExecutionScope.
The second middleware extracts the owincontext and sets it to the (IOwinContextContext) instance.
The third (test) middleware simply do a container.GetInstance and it works as expected, the OwinContextContext is populated.

The Controller takes the IOwinContextContext in the constructor, but this is where everything breaks. It does not receive the same instance of the OwinContextContext, instead it creates a new!

I can't understand what i am doing wrong.

The IOwinContextContext is registered per request:
container.RegisterWebApiRequest<IOwinContextContext, OwinContextContext>();
:( I really wanted this to work. Although it didn't work fully, your explanation were top notch. Thanks for that at least!
Feb 15, 2015 at 7:37 PM
Edited Feb 15, 2015 at 7:38 PM
There come a number of things to mind that could cause this. My bet is that it is number 2...

1. You use a different container for the configuration of Owin than the one that is creating your ApiController.
This will give you indeed a new IOwinContextContext which will be transient. However if you followed my example completely, this will throw an SimpleInjector.ActivationException, because the container will be unable to create an instance of IOwinContextContext if you didn't register this in the container that is used for creating the ApiController. But when you leave the interface for what it is, and use the implementation directly in your constructor, the container will be able to create an instance and it will then create a transient, which is offcourse, evertytime a new one.

2. You have a nested ExecutionScope.
The UseBeginStartExecutionScope extension method creates a new ExecutionScope. It was always a little unclear to me why this is needed since the scope will be normally started automatically when the framework (WebApi in this case) will call BeginScope on the DependencyResolver. I think this is still happening and therefore you get a nested scope. You may ask yourself where and why you need this.
As the IOwinContextContext is registered on a PerWebApiRequest basis you will indeed get a new version of the IOwinContextContext in the ApiController because this will probably run in another ExecutionScope.

I did some research and I'm a little frustrated that I (or you for that matter) did not do this a little earlier, because getting the OwinContext in a self hosted environment is pretty straightforward and documented since there is another extension method on HttpRequestMessage also called GetOwinContext.

SimpleInjector has built-in support for getting the current HttpRequestMessage as you can read here. The implementation of the OwinContextContext is therefore as simple as writing your name.

You can loose the extension method UseOwinContextInjector (and maybe also UseBeginStartExecutionScope...?!!).

Change the IOwinContextContext to:
public interface IOwinContextContext
{
    IOwinContext CurrentContext { get; } 
}
and the implemtation:
public class OwinContextContext : IOwinContextContext
{
    // An example of IRequestMessageProvider can be found here:
    // https://simpleinjector.readthedocs.org/en/latest/webapiintegration.html
    private readonly IRequestMessageProvider messageProvider;
    
    public OwinContextContext(IRequestMessageProvider messageProvider)
    {
        this.messageProvider = messageProvider;
    }

    public IOwinContext CurrentContext
    {
        get { return this.messageProvider.CurrentMessage.GetOwinContext(); }
    }
}
The registration for the IOwinContextContext must stay the same (PerWebApiRequest).

And that should do it.
Feb 16, 2015 at 9:07 AM
Edited Feb 16, 2015 at 11:36 AM
Hey again!

Well, that looked like a nice solution - But sadly it doesn't work for Middlewares.
If you try to access the CurrentMessage while in a middleware, it will be null.

I spent a couple of hours this morning and got a workaround (based on your former proposal, with SetContext Middleware).
  1. I make use of the use.SetExecutionSCope() middleware to create the scope used by the web api
  2. I make use of the use.InjectOwinContext() middleware to set the context on a instance of IOwinContextContext.
  3. I rewrote the WebApiDependencyResolver0, to not create a new executionScope. (And simply rely on the middleware to create a shared scope)
I copied the class (from http://simpleinjector.codeplex.com/SourceControl/latest#SimpleInjector.Integration.WebApi/SimpleInjectorWebApiDependencyResolver.cs) and removed the call to container.BeginExecutionScope (Since i rely on a middleware to do this).

Can you think of any problems with this change (Except that I put a dependency on a middleware to create the exceutionscope?)

Very thankful for all the time you and others put into this issue. IF my solution is "OK" I will publish a blog post + demonstration repository.
Feb 16, 2015 at 1:16 PM
In further investigations I sometimes loose the ExecutionContext.
_container.GetCurrentExecutionContextScope() returns null.

This seems to happen when moving between Middlewares that are located in different types / files.

If i have multiple "inline" middlwares, e.g.

app.use (async (context, next) => {}); // 1
app.use (async (context, next) => {}); // 2
app.use (async (context, next) => {}); // 3

They all receive the same executionContext.

But when I add this;
app.UseSomeOtherMiddleware(); // 4

When i enter the lambda inside the static extension method (4), the Current Execution Context is null.
Coordinator
Feb 24, 2015 at 6:29 AM
Edited Jan 6 at 6:35 AM
Hi guys,

This thread is now officially closed to prevent it from becoming a magnet to everyone’s problems. Please start a new thread with your specific question.