.Net Core - 从API中间件到存储库层注入依赖关系IUserInfo

Kev*_*ing 3 c# dependency-injection repository-pattern asp.net-core asp.net-core-webapi

假设我从下到上有以下结构化项目层,如Repository - > Service - > API,Code sample:

库:

public interface IUserInfo
{
    int UID{ get; set; }
}
public class UserInfo : IUserInfo
{
    public int UID { get; set; }
}
public class ProductionRepository : Repository, IProductionRepository {
    public ProductionRepository(IUserInfo userInfo, StoreDbContext dbContext) : base(userInfo, dbContext)
    {}
    //...
}
Run Code Online (Sandbox Code Playgroud)

服务:

public class ProductionService : Service, IProductionService {
        public ProductionService(IUserInfo userInfo, StoreDbContext dbContext)
            : base(userInfo, dbContext)
        {
        }
//...
}
public abstract class Service {        
    protected IProductionRepository m_productionRepository;
    public Service(IUserInfo userInfo, StoreDbContext dbContext)
    {
        UserInfo = userInfo;
        DbContext = dbContext;
    }
    protected IProductionRepository ProductionRepository
            => m_productionRepository ?? (m_productionRepository = new ProductionRepository(UserInfo, DbContext));
}
Run Code Online (Sandbox Code Playgroud)

API:

  public class ProductionController : Controller {
        private readonly IUserInfo userInfo;
        protected IProductionService ProductionBusinessObject;
        public ProductionController(IUserInfo _userInfo, IProductionService productionBusinessObject)
        {
            userInfo = _userInfo;
            ProductionBusinessObject = productionBusinessObject;
        }
  }
Run Code Online (Sandbox Code Playgroud)

现在,在我的Startup.cs中,我使用带有" OnTokenValidated "事件的JWT令牌从令牌中获取UserInfo信息:

services.AddAuthentication(options =>
{
     options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
     options.Events = new JwtBearerEvents
     {
         #region Jwt After Validation Authenticated
         OnTokenValidated = async context =>
         {
              #region Get user's immutable object id from claims that came from ClaimsPrincipal
              var userID = context.Principal.Claims.Where(c => c.Type == ClaimTypes.NameIdentifier)
              services.Configure<UserInfo>(options =>
              {
                    options.UID = userID;
              });
              #endregion
          },
          #endregion
       }
};
Run Code Online (Sandbox Code Playgroud)

我正在使用services.Configure并尝试将UID分配给IUserInfo对象,但是当我在我的控制器中调试时,IUserInfo总是表示一个null对象,如构造函数或api方法.我知道我可能在.Net核心中滥用了依赖注入,所以请随时指导我将IUserInfo注入我的Controller - > Service - > Repository的正确方法,这样所有这些都可以得到实际的UserInfo信息!

Bra*_*rad 6

您可以IUserInfo通过在Startup中将其注册为服务来注入.

services.AddScoped<IUserInfo>(provider =>
{
    var context = provider.GetService<IHttpContextAccessor>();

    return new UserInfo
    {
        UID = context.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier)
    };
});
Run Code Online (Sandbox Code Playgroud)