【发布时间】:2016-02-21 01:55:39
【问题描述】:
试图找出一种在 VS2015、.Net 4.5 上使用 DryIoC (v2.0.0-rc4build353)、MS OWIN (v3.0.1、WebAPI2 (client v5.2.3) 建立会话管理的方法。
我正在使用 REST API 包装一个相当复杂的遗留应用程序。 严格的 API 服务器,没有 UI/MVC。 我知道我不可能完全无状态,因为我必须保持一个“模型”开放的服务器端。用户也必须对模型进行身份验证。因此,会话的概念出现了。我想尽可能多地使用 DI。
我第一次放弃的尝试是使用 Ninject 并将 ISession 映射到提供程序工厂。虽然 Ninject 有它的优点(例如模块),但我不喜欢它的复杂性。我不知道如何从工厂访问请求对象。经过一番研究,我决定改用 DryIoC。
在下面的代码示例中,DryIoC 创建了一个单例会话(请参阅下面的重用)并将其注入我的 RootController。如果我在 Transient Scope 中注册 Session,显然每个请求都会获得一个会话。我设想调用“api/login”将生成一个令牌。客户端将缓存它并在标头中与后续调用一起提交(以启用 API 版本控制)。
苦于如何管理范围。
编辑:澄清我认为我需要什么:我不确定如何实现 DryIoC 在实例化控制器之前调用的工厂,我将在其中查找会话令牌并创建/查找关联的 ISession 实例。然后 DryIoC 会使用它来注入控制器。
编辑:我试图隐藏所有会话管理样板,并让所有控制器都注入一个已经初始化的会话。如果此请求没有会话,则单独的路由将返回错误。需要注意的另一件事是客户端必须显式获取令牌。没有全局“当前”令牌或会话的概念。
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
});
}
}
}
【问题讨论】:
-
我不太明白:你想要一个会话按什么?
-
@FyodorSoikin Session per "something" :) 我不确定如何实现 DryIoC 在实例化控制器之前调用的工厂,我将在其中查找会话令牌并创建/查找关联的 ISession实例。然后 DryIoC 将使用它注入控制器。
-
我认为你把这个复杂化了。如果遗留系统能够调用 API,那么它就有能力调用 API 来获取令牌。令牌存储在客户端,并在调用资源 API 时在标头中传递。查找 JWT 和 oAuth。 API 不应该有会话的概念。
-
@StephenBrickner 这只是更大系统的“服务器端”。还有其他模块(Node / Angular)将调用。JWT / oAuth在计划中,这正是我所说的“在标头中传递令牌”的意思,但是问题是我想用正确的会话注入来实例化控制器进去。为了注入正确的会话实例,我需要 DI 容器使用 http 上下文调用我,但我不知道该怎么做。
标签: session asp.net-web-api asp.net-web-api2 owin dryioc