[英]Getting the User.Identity during service Resolution in Autofac and WebAPI 2 Owin
我要做的是实例化一个UserContext
(理想情况下每个用户一个实例)。 UserContext
取决于当前登录的用户。
通过调用GlobalContext.User(username)
创建MyUser
从我的Startup.Configuration(IAppBuilder app)
调用以下代码段:
private static IContainer RegisterServices()
{
var builder = new ContainerBuilder();
builder.RegisterApiControllers(System.Reflection.Assembly.GetAssembly(typeof(MyWeb.API.Startup)));
builder.RegisterType<GlobalContext>().As<IGlobalContext>().SingleInstance();
builder.Register(c => c.Resolve<IGlobalContext>().User(
HttpContext.Current.User.Identity.Name)
).As<MyUser>();
builder.RegisterType<UserContext>().As<IUserContext>().InstancePerLifetimeScope();
return builder.Build();
}
在IIS Express中运行时,一切似乎工作正常。 当我使用Owin WebApp.Start<Startup>(url: BaseAddress)
在集成测试中运行此代码时, WebApp.Start<Startup>(url: BaseAddress)
HttpContext.Current
为null。 到目前为止,我已经完成了所有阅读,这是可以预期的,但是还有什么选择呢?
我认为我需要访问owinContext或autofac生存期范围才能在解析期间获取当前用户,但是我该怎么做?
有一个更好的方法吗? 还是我缺少一些琐碎的东西?
感谢所有帮助。
编辑以添加信息:如果有帮助,请在此处包括我的Configuration()
方法:
using System.Web;
using System.Web.Http;
using Autofac;
using Autofac.Integration.WebApi;
using Owin;
using System.Reflection;
namespace SomeNameSpace
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var configuration = new HttpConfiguration{ IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always };
WebApiConfig.Register(configuration);
BreezeConfig.Register(configuration);
CorsConfig.Register(configuration);
// Autofac IoC
var container = RegisterServices();
app.UseAutofacMiddleware(container);
app.UseWindowsAuthentication();
var urt = new UserRolesTranformer(new GlobalContext());
app.UseClaimsTranformation(urt.Transformation);
app.UseAutofacWebApi(configuration);
configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
//app.Use(typeof(TestMiddleware));
app.UseAutofacWebApi(configuration);
app.UseWebApi(configuration);
}
}
最终目标:创建一个测试,以模拟多个并发用户登录并确保每个用户都拥有自己的UserContext实例。
在单元测试的情况下,您实际上不需要访问HttpContext或OwinContext。 就像您已经发现的那样,单元测试没有HttpContext的概念。
我假设您的IGlobalContext有一个User方法,该方法采用一个Username并向您返回一个User,也许是基于从当前上下文传入的Username从数据库中返回的?
您应该做的是为您的网站和单元测试使用不同的Autofac注册,以便在每个环境中都可以具有不同的依赖关系。 然后,在单元测试Autofac注册中,您可以注册一个完全不同的依赖关系,以在单元测试中解决,或者可以将您知道的模拟用户名传递给User方法。
因此,您将其保留为您网站上的Autofac注册。
private static IContainer RegisterServices()
{
var builder = new ContainerBuilder();
builder.RegisterApiControllers(System.Reflection.Assembly.GetAssembly(typeof(MyWeb.API.Startup)));
builder.RegisterType<GlobalContext>().As<IGlobalContext>().SingleInstance();
builder.Register(c => c.Resolve<IGlobalContext>().User(
HttpContext.Current.User.Identity.Name)
).As<MyUser>();
builder.RegisterType<UserContext>().As<IUserContext>().InstancePerLifetimeScope();
return builder.Build();
}
然后在您的单元测试中,当您使用以下内容注册Autofac注册时。
private static IContainer RegisterServices()
{
var builder = new ContainerBuilder();
builder.RegisterApiControllers(System.Reflection.Assembly.GetAssembly(typeof(MyWeb.API.Startup)));
builder.RegisterType<GlobalContext>().As<IGlobalContext>().SingleInstance();
builder.Register(c => c.Resolve<IGlobalContext>().User(
"MyTestUser")
).As<MyUser>();
builder.RegisterType<UserContext>().As<IUserContext>().InstancePerLifetimeScope();
return builder.Build();
}
这样,您就可以在单元测试中确切知道要传递的用户和应该返回的用户。
或者使用您自己的完全嘲笑的用户,像这样...
public class TestUser : MyUser
{
//Known Test Scenario Properties and Methods as required
}
private static IContainer RegisterServices()
{
var builder = new ContainerBuilder();
builder.RegisterApiControllers(System.Reflection.Assembly.GetAssembly(typeof(MyWeb.API.Startup)));
builder.RegisterType<GlobalContext>().As<IGlobalContext>().SingleInstance();
builder.RegisterType<TestUser>().As<MyUser>();
builder.RegisterType<UserContext>().As<IUserContext>().InstancePerLifetimeScope();
return builder.Build();
}
我希望这有帮助?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.