C# Autofac:如何在razor页面中传递注册参数

C# Autofac:如何在razor页面中传递注册参数,c#,autofac,razor-pages,C#,Autofac,Razor Pages,我正在向Razor页面注入一个HttpClient。HttpClient需要三个参数:用户名、密码和服务器地址。在注册期间,我提供服务器地址 builder.RegisterType<HttpClient>().As<IHttpClient>() .WithParameter(new ResolvedParameter( (pi, ctx) => pi.ParameterType == type

我正在向Razor页面注入一个HttpClient。HttpClient需要三个参数:用户名、密码和服务器地址。在注册期间,我提供服务器地址

builder.RegisterType<HttpClient>().As<IHttpClient>()
            .WithParameter(new ResolvedParameter(
                        (pi, ctx) => pi.ParameterType == typeof(string) && 
                        pi.Name == "serverAddress",
                        (pi, ctx) => "https://server.address.com"));
builder.RegisterType().As()
.WithParameter(新解析参数(
(pi,ctx)=>pi.ParameterType==typeof(string)和
pi.Name==“服务器地址”,
(pi,ctx)=>“https://server.address.com"));
但是,我只能在用户登录Razor页面后提供用户名和密码。如何将用户名和密码传递到HttpClient注册表


约翰的回答解决了我的问题。现在,我有一个后续问题。一旦我从Razor页面传递了参数,我如何使依赖于HttpClient的其他类自动获取用户信息?所以现在事情是这样的

builder.RegisterType<HttpClient>().As<IHttpClient>()
            .WithParameter(new ResolvedParameter(
                        (pi, ctx) => pi.ParameterType == typeof(string) && 
                        pi.Name == "serverAddress",
                        (pi, ctx) => "https://server.address.com"));

builder.Register(HttpClientFactory)
            .As<Func<string, string, IHttpClient>>();

builder.RegisterType<Bamboo>().As<IBamboo>();
builder.RegisterType().As()
.WithParameter(新解析参数(
(pi,ctx)=>pi.ParameterType==typeof(string)和
pi.Name==“服务器地址”,
(pi,ctx)=>“https://server.address.com"));
生成器注册(HttpClientFactory)
.As();
builder.RegisterType().As();
其中,竹依靠IHttpClient与竹服务器通信


对于问题的第二部分,我相信我可以为Bambol类创建一个构造函数,并使其包含用户名和密码两个参数。然后,我可以创建一个Func并将其注册到竹类。但是,我很好奇是否可以更新HttpClient中的信息,并使其他类依赖于它自动获取用户信息。

有几种方法可以实现这一点,具体取决于客户端凭据的来源,但最简单和最灵活的选择可能只是注入某种形式的工厂,您可以在运行时使用它。这可以通过自定义factory类来实现,但是如果您希望在不需要在调用堆栈的更深处引用Autofac的情况下,为HttpClient上的依赖项提供最大的灵活性,则可以使用
Func
这样的函数来实现:

private static Func<string, string, IHttpClient> GetHttpClientFactory(IComponentContext c)
{
    var context = c.Resolve<IComponentContext>();
    return (u, p) => context.Resolve<IHttpClient>(new NamedParameter("username", u), new NamedParameter("password", p));
}

...

builder.RegisterType<HttpClient>()
    .As<IHttpClient>()
    .WithParameter(new NamedParameter("serverAddress", "https://server.address.com"));

builder.Register(GetHttpClientFactory)
    .As<Func<string, string, IHttpClient>>();
public class Page
{
    private readonly Func<string, string, IHttpClient> _httpClientFactory;

    public Page(Func<string, string, IHttpClient> httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    public void DoHttpStuff()
    {
        // extract the user http credentials from the logged-in identity here / handle cases where they're not available:
        var user = "SomeUser";
        var password = "SomePassword";
        var client = _httpClientFactory(user, password);
        // use the client
    }
}
私有静态函数GetHttpClientFactory(IComponentContext c)
{
var context=c.Resolve();
return(u,p)=>context.Resolve(新名称参数(“用户名”,u),新名称参数(“密码”,p));
}
...
builder.RegisterType()
.As()
.WithParameter(新名称参数(“服务器地址”)https://server.address.com"));
生成器注册(GetHttpClientFactory)
.As();
然后,您的用法可能如下所示:

private static Func<string, string, IHttpClient> GetHttpClientFactory(IComponentContext c)
{
    var context = c.Resolve<IComponentContext>();
    return (u, p) => context.Resolve<IHttpClient>(new NamedParameter("username", u), new NamedParameter("password", p));
}

...

builder.RegisterType<HttpClient>()
    .As<IHttpClient>()
    .WithParameter(new NamedParameter("serverAddress", "https://server.address.com"));

builder.Register(GetHttpClientFactory)
    .As<Func<string, string, IHttpClient>>();
public class Page
{
    private readonly Func<string, string, IHttpClient> _httpClientFactory;

    public Page(Func<string, string, IHttpClient> httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    public void DoHttpStuff()
    {
        // extract the user http credentials from the logged-in identity here / handle cases where they're not available:
        var user = "SomeUser";
        var password = "SomePassword";
        var client = _httpClientFactory(user, password);
        // use the client
    }
}
公共类页面
{
私有只读函数(httpClientFactory);
公共页面(Func httpClientFactory)
{
_httpClientFactory=httpClientFactory;
}
公共void DoHttpStuff()
{
//从此处登录的标识中提取用户http凭据/处理这些凭据不可用的情况:
var user=“SomeUser”;
var password=“SomePassword”;
var client=\u httpClientFactory(用户,密码);
//使用客户端
}
}

在Autofac注册过程中,您可以通过多种方式进一步了解这一点,并尝试从用户上下文中读取http凭据,但如果上述方法适用于您的场景,则可能会增加许多不必要的复杂性。

谢谢John。我有一个后续问题。我应该把Func放在哪里?在HttpClient类中或注册。我还不太熟悉Func。我测试了它,它运行正常。我在HttpClient的Autofac模块类中创建了一个Func。在Load()函数中,我注册了John描述的Func。没问题-您能将其标记为已回答吗?谢谢