簡體   English   中英

在Autofac和WebAPI 2 Owin中的服務解析期間獲取User.Identity

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM