简体   繁体   中英

HttpContextAccessor, IPrincipal and ServiceCollection

Is there a way that I could implement next behaviour?

public static void Configure(IServiceCollection services) {
    services.AddScoped(typeof(Func<IPrincipal>), ???);
    services.AddInstance(typeof(Func<IPrincipal>), ???);
}

1. Does not work:

Func<IServiceProvider, IPrincipal> getPrincipal = 
    (sp) => sp.GetService<IHttpContextAccessor>().HttpContext.User;

services.AddScoped(
    typeof(Func<IPrincipal>), 
    getPrincipal);  

2. Does not work:

var builder = services.BuildServiceProvider();

services.AddInstance(
    typeof(Func<IPrincipal>),
    builder.GetService<IHttpContextAccessor>().HttpContext.User);
Func<IServiceProvider, IPrincipal> getPrincipal = 
    (sp) => sp.GetService<IHttpContextAccessor>().HttpContext.User;

services.AddScoped(
    typeof(Func<IPrincipal>), 
    getPrincipal); 

You are trying to resolve the delegate, but I assume you want to resolve IPrincipal instead. I assume your service may look like this

public class MyService : IMyService 
{
    public MyService(IPrincipal principal) 
    {
        ...
    }
}

If so, then your registration is wrong. You are registering Func<IPrincipal> but expecting IPrincipal which isn't registered.

You should either register the factory for IPrincipal or (less recommended imho) inject the Func<IPrincipal> into your service.

Func<IServiceProvider, IPrincipal> getPrincipal = 
    (sp) => sp.GetService<IHttpContextAccessor>().HttpContext.User;

services.AddScoped<IPrincipal>(getPrincipal); 

or shorter

services.AddScoped<IPrincipal>(
    (sp) => sp.GetService<IHttpContextAccessor>().HttpContext.User
); 

or

public class MyService : IMyService 
{
    priate IPrincipal principal;
    public MyService(Func<IPrincipal> principalFactory) 
    {
        this.principal = principalFactory();
    }
}

Working solution:

Func<IServiceProvider, IPrincipal> getPrincipal = 
    (sp) => sp.GetService<IHttpContextAccessor>().HttpContext.User;

services.AddScoped(typeof(Func<IPrincipal>), sp => {
    Func<IPrincipal> func = () => {
        return getPrincipal(sp);
    };

    return func;
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM