[英]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.