Trying to figure out a way to establish session management with DryIoC (v2.0.0-rc4build353), MS OWIN (v3.0.1, WebAPI2 (client v5.2.3) on VS2015, .Net 4.5.
I'm wrapping a rather elaborate legacy application with REST API. Strictly API server, no UI/MVC. I understand that it's impossible for me to go fully state-less because I have to keep a "model" open server-side. User must authenticate into the model as well. Hence concept of a Session came along. I want to use DI as much as possible.
My first discarded attempt was to use Ninject and map ISession to a provider factory. While Ninject has its pros (modules, for one), I didn't like the complexity of it. I can't figure out how to access request object from the factory. After some research I decided to switch to DryIoC.
In the code sample below DryIoC creates a singleton session (see Reuse below) and injects it into my RootController. If I register Session in Transient Scope, I obviously get a session per request. I envision that a call to, say, "api/login" will generate a token. Client will cache it and submit it with subsequent calls in a header (to enable API versioning as well).
Struggling with how to manage scoping.
EDIT: Clarification on what I think I need: I'm not sure how to implement a factory that DryIoC would call before instantiating a controller, where I'd lookup the session token and create/lookup associated ISession instance. DryIoC would then use it to inject into the controller.
EDIT: I am trying to hide all session management boilerplate and have all controllers be injected with an already initialized session. In case there's no session for this request, a separate route would return an error. Another thing to note is that a client has to acquire a token explicitly. There's no notion of a global "current" token or session.
using System;
using System.Web.Http;
using Microsoft.Owin.Hosting;
using Microsoft.Owin.Diagnostics;
using Owin;
using DryIoc;
using DryIoc.WebApi;
namespace di_test
{
class Program
{
static void Main(string[] args)
{
var url = "http://localhost:8065";
using (WebApp.Start<Startup>(url))
{
Console.WriteLine("Owin host started, any key to exit");
Console.ReadKey();
}
}
}
class Startup
{
public void Configuration(IAppBuilder app_)
{
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "default",
routeTemplate: "{controller}"
);
var di = new DryIoc.Container();
di.Register<ISession, Session>(Reuse.Singleton);
di.WithWebApi(config);
app_.UseWebApi(config);
app_.UseErrorPage(ErrorPageOptions.ShowAll);
}
}
public interface ISession
{
string Token { get; }
}
public class Session : ISession
{
string m_token = null;
public Session()
{
Console.WriteLine("Session()");
}
public string Token => m_token ?? (m_token = Guid.NewGuid().ToString());
}
[RoutePrefix("api")]
public class RootController : ApiController
{
readonly ISession m_session;
public RootController(ISession session_)
{
m_session = session_;
}
[Route()]
public IHttpActionResult GetApiRoot()
{
return Json(
new
{
type = "root",
token = m_session.Token
});
}
}
}