7

I'm confused on how the OWIN CreatePerOwinContext method is to be used. As far as I can see it's a poor mans DI mechanism. Yet, I fail to see how to use it.

We can register a type/implementation at the Startup sequence like:

app.CreatePerOwinContext<IUserService>(() => {
     return new UserService() as IUserService;
});

Then how do we resolve to that later on. Documentation says it can be retrieved via Get method. But Get<T> expects a string parameter, which is the key to that entry in the Enviornment IDictionary? How can I know the key in this case?

IUserService userService = context.Get<IUserService>(???);
BuddhiP
  • 6,231
  • 5
  • 36
  • 56

2 Answers2

3

You can use typeof to get the key parameter:

HttpContext.GetOwinContext().Get<ApplicationDbContext>(typeof(ApplicationDbContext).ToString());

Also, Microsoft.AspNet.Identity.Owin assembly contains the parameterless version of Get<T>() method, so you can use it if you already have ASP.NET Identity in your project.

Sergey Kolodiy
  • 5,829
  • 1
  • 36
  • 58
  • 1
    This answer pointed me in the right direction. However, if you want take the item with the key, we have to prefix the AssemblyQualifiedName with 'AspNet.Identity.Owin:', giving just the fully qualified type name will not work – BuddhiP Sep 10 '15 at 18:31
  • 1
    I dont think this works. I inspected the ctx.Environment Property Keys and it appears that the key added is a fully qualified assembly name by changing to typeof(ApplicationDbContext).AssemblyQualifiedName. I love how the owin documentation mentions none of this. – enorl76 Mar 16 '16 at 18:25
3

I have a more correct answer after running into this myself, trying to implement the code within this stackoverflow answer: https://stackoverflow.com/a/31918218

So given this initialization code within the conventional Configure method:

static void Configuration(IAppBuilder app)
{
    //https://stackoverflow.com/a/31918218
    app.CreatePerOwinContext<AppBuilderProvider>(() => new AppBuilderProvider(app));

    ConfigureAuth(app); //note implementation for this is typically in separate partial class file ~/App_Start/Startup.Auth.cs
}

One can retrieve the instance created by this code:

public ActionResult SomeAction() 
{
    //https://stackoverflow.com/a/31918218
    var app = HttpContext.GetOwinContext().Get<AppBuilderProvider>("AspNet.Identity.Owin:" + typeof(AppBuilderProvider).AssemblyQualifiedName).Get();
    var protector = Microsoft.Owin.Security.DataProtection.AppBuilderExtensions.CreateDataProtector(app, typeof(Microsoft.Owin.Security.OAuth.OAuthAuthorizationServerMiddleware).Namespace, "Access_Token", "v1");
    var tdf = new Microsoft.Owin.Security.DataHandler.TicketDataFormat(protector);
    var ticket = new AuthenticationTicket(ci, null);
    var accessToken = tdf.Protect(ticket);

    //you now have an access token that can be used.
}
Community
  • 1
  • 1
enorl76
  • 2,562
  • 1
  • 25
  • 38
  • Looking back, it might have been easier to create the protector in Startup.Auth and inject it into OwinContext – enorl76 Feb 11 '22 at 21:22