Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net AspNetCore中间件UserManager依赖项注入_Asp.net_Asp.net Core_Asp.net Identity 3 - Fatal编程技术网

Asp.net AspNetCore中间件UserManager依赖项注入

Asp.net AspNetCore中间件UserManager依赖项注入,asp.net,asp.net-core,asp.net-identity-3,Asp.net,Asp.net Core,Asp.net Identity 3,我有一个多层应用程序,我开始用ASP.NETCore1.1编写,我还在学习。我像以前在WebAPI中做的应用一样组织它,我有主机服务(NetCore应用)、业务层和数据库之上的数据层。业务层和数据层是net core标准库,但当我想添加实体框架时,我必须修改数据层,使其看起来像net core应用程序,所以现在我有了Startup.cs,其中有配置。这使我能够配置实体框架服务并在数据层中创建迁移。但现在我有一个问题,因为我想添加asp.net标识。网络上的每一个教程都是关于水疗中心的,它们在一个

我有一个多层应用程序,我开始用ASP.NETCore1.1编写,我还在学习。我像以前在WebAPI中做的应用一样组织它,我有主机服务(NetCore应用)、业务层和数据库之上的数据层。业务层和数据层是net core标准库,但当我想添加实体框架时,我必须修改数据层,使其看起来像net core应用程序,所以现在我有了Startup.cs,其中有配置。这使我能够配置实体框架服务并在数据层中创建迁移。但现在我有一个问题,因为我想添加asp.net标识。网络上的每一个教程都是关于水疗中心的,它们在一个项目中拥有一切。 我已经向Startup.cs添加了标识,并且数据库生成良好

public void ConfigureServices(IServiceCollection services)
{
    var connectionString = Configuration.GetConnectionString("DefaultConnection");
    services.AddEntityFramework(connectionString);
    services.AddMyIdentity();
    services.Configure<IdentityOptions>(options =>
    {
        // Password settings
        options.Password.RequireDigit = true;
        options.Password.RequiredLength = 8;
        options.Password.RequireNonAlphanumeric = false;
        options.Password.RequireUppercase = true;
        options.Password.RequireLowercase = false;

        // Lockout settings
        options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
        options.Lockout.MaxFailedAccessAttempts = 10;


        // User settings
        options.User.RequireUniqueEmail = true;
    });
}
public void Configure(IApplicationBuilder app)
{
    app.UseIdentity();
}
public void配置服务(IServiceCollection服务)
{
var connectionString=Configuration.GetConnectionString(“DefaultConnection”);
服务.附加框架(connectionString);
services.AddMyIdentity();
配置(选项=>
{
//密码设置
options.Password.RequireDigit=true;
options.Password.RequiredLength=8;
options.Password.RequireNonAlphanumeric=false;
options.Password.RequireUppercase=true;
options.Password.RequireLowercase=false;
//锁定设置
options.Lockout.DefaultLockoutTimeSpan=TimeSpan.FromMinutes(30);
options.locket.MaxFailedAccessAttempts=10;
//用户设置
options.User.RequireUniqueEmail=true;
});
}
公共void配置(IApplicationBuilder应用程序)
{
app.UseIdentity();
}
但是现在我需要从一个不是控制器的类中使用UserManager,我不知道如何处理依赖注入。 为了更好地解释,我的主机服务中有一个帐户控制器

[HttpPost]
[Route("Register")]
public async Task<IActionResult> Register([FromBody]RegisterUserDto dto)
{
    var result = await Business.Commands.Accounts.Register(dto);
    return Ok(result);
}
[HttpPost]
[路线(“登记”)]
公共异步任务寄存器([FromBody]寄存器UserDTO)
{
var result=wait Business.Commands.Accounts.Register(dto);
返回Ok(结果);
}
业务层只调用数据层

public async static Task<ResponseStatusDto> Register(RegisterUserDto dto)
{
    // some code here        
    var identityLogon = await Data.Commands.ApplicationUsers.Register(dto);
    // some code here as well

    return new ResponseStatusDto();
}
公共异步静态任务寄存器(RegisterUserDto)
{
//这里有一些代码
var identityLogon=wait Data.Commands.ApplicationUsers.Register(dto);
//这里也有一些代码
将新响应返回到();
}
现在的问题是,如何在数据寄存器方法中获取UserManager?它是一个简单的类,它不从控制器继承,依赖项注入不适用于构造函数,如这里的示例所示

公共类AccountController:控制器
{
private readonly UserManager,但是只将null值传递给UseManager构造函数的答案不起作用,我认为这也不好

//根据集合的答案进行编辑

我已经删除了所有的静态引用,但还没有完全删除。我遵循了依赖项注入说明,但我不确定如何实例化和调用Add方法

我已经创建了一个接口

public interface IIdentityTransaction
{
    Task<IdentityResult> Add(ApplicationUser appUser, string password);
}
公共接口IIdentityTransaction
{
任务添加(ApplicationUser appUser,字符串密码);
}
并付诸实施

public class IdentityTransaction : IIdentityTransaction
{
    private readonly ApplicationDbContext _dbContext;

    private readonly UserManager<ApplicationUser> _userManager;
    private readonly RoleManager<IdentityRole> _roleManager;


    public IdentityTransaction(ApplicationDbContext context, UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager)
    {
        _roleManager = roleManager;
        _userManager = userManager;
        _dbContext = context;
    }

    public async Task<IdentityResult> Add(ApplicationUser applicationUser, string password)
    {
        return await _userManager.CreateAsync(applicationUser, password);
    }

}
public class IdentityTransaction:IIdentityTransaction
{
私有只读应用程序dbContext_dbContext;
专用只读用户管理器

我不能实例化它,也不能在构造函数上使用依赖项注入,因为它只是循环我的问题。@Set

或者将UserManager作为参数传递给方法 从哪里传过来

我想我很接近,但我错过了一些东西。 我试过使用

    IIdentityTransaction it = services.GetRequiredService<IIdentityTransaction>();
IIdentityTransaction it=services.GetRequiredService();

但是作为IServiceProvider的服务是空的,我也不知道从哪里获得它。

ASP.NET核心中的DI使用“构造函数注入”方法对控制器类和非控制器类的工作原理相同

您有问题,因为
Register
方法是
static
,因此无法访问实例变量/属性。您需要

  • 使
    寄存器
    方法非静态
  • 或者将
    UserManager UserManager
    作为参数传递给方法

一般来说,您应该避免在业务逻辑中使用静态类,因为它们无助于正确测试您的代码并产生代码耦合。通过internet/SO搜索,您将发现许多为什么静态不好的主题

使用DI获取控制器中的
Data.Commands.ApplicationUsers
类的实例。如果应用程序只需要此类的一个实例,请使用单实例生存期


更新。再次使用构造函数注入:修改“数据层”类,以便它可以将
IIdentityTransaction
的实例作为构造函数参数:

public class YourDataLayerClass : IYourDataLayerClass
{
    private IIdentityTransaction _identityTransaction;
    public YourDataLayerClass(IIdentityTransaction identityTransaction)
    {
       _identityTransaction = identityTransaction;
    }

    public void MethodWhereYouNeedToCallAdd()
    {
        _identityTransaction.Add(...);
    }
}
对于
IYourDataLayerClass
实例,想法也是一样的:寄存器依赖性

services.AddScoped<IYourDataLayerClass, YourDataLayerClass>();

是的,你很接近

首先,从IdentityTransaction构造函数中删除上下文参数,因为在您的代码中,它似乎是无用的。或者,如果您计划稍后使用它,请在DI容器中声明它:

services.AddScoped<ApplicationDbContext, ApplicationDbContext>();
services.addScope();
第二件事,您只需在控制器的构造函数中添加IIdentityTransaction作为依赖项,并从其依赖项中删除SignInManager和UserManager,因为最终您不会在控制器中直接使用它们:

public class AccountController : Controller
{
    private readonly IEmailSender _emailSender;
    private readonly ISmsSender _smsSender;
    private static bool _databaseChecked;
    private readonly ILogger _logger;
    IIdentityTransaction _identityTransaction;

    public AccountController(
        IEmailSender emailSender,
        ISmsSender smsSender,
        ILoggerFactory loggerFactory,
        IIdentityTransaction identityTransaction)
    {
        _emailSender = emailSender;
        _smsSender = smsSender;
        _logger = loggerFactory.CreateLogger<AccountController>();
        _identityTransaction = identityTransaction;
    }
公共类AccountController:控制器
{
私人只读IEmailSender\u emailSender;
私有只读ISmsSender(U SMSENDER);
检查私有静态bool_数据库;
专用只读ILogger\u记录器;
身份交易(身份交易);;
公共账户控制员(
电邮发送者,
伊斯姆森德·斯姆森德,
伊洛格工厂伐木厂,
IIdentityTransaction(身份交易身份交易)
{
_emailSender=emailSender;
_斯姆森德
public class YourMiddleware
{
    private IYourDataLayerClass _yourDataLayerClass;
    public YourMiddleware(IYourDataLayerClass yourDataLayerClass)
    {
       _yourDataLayerClass = yourDataLayerClass;
    }
    ...
}
services.AddScoped<ApplicationDbContext, ApplicationDbContext>();
public class AccountController : Controller
{
    private readonly IEmailSender _emailSender;
    private readonly ISmsSender _smsSender;
    private static bool _databaseChecked;
    private readonly ILogger _logger;
    IIdentityTransaction _identityTransaction;

    public AccountController(
        IEmailSender emailSender,
        ISmsSender smsSender,
        ILoggerFactory loggerFactory,
        IIdentityTransaction identityTransaction)
    {
        _emailSender = emailSender;
        _smsSender = smsSender;
        _logger = loggerFactory.CreateLogger<AccountController>();
        _identityTransaction = identityTransaction;
    }
services.AddScoped<IIdentityTransaction, IdentityTransaction>();
 IIdentityTransaction it = services.GetRequiredService<IIdentityTransaction>();