微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 依赖注入循环依赖.net核心2.0

我希望我的ApplicationContext构造函数将UserManager作为参数,但是依赖注入有问题.

码:

public class ApplicationContext : IdentityDbContext<ApplicationUser>
{
    private IHttpContextAccessor _contextAccessor { get; set; }
    public ApplicationUser ApplicationUser { get; set; }
    private UserManager<ApplicationUser> _userManager;

    public ApplicationContext(DbContextOptions<ApplicationContext> options,IHttpContextAccessor contextAccessor,UserManager<ApplicationUser> userManager)
        : base(options)
    {
        _contextAccessor = contextAccessor;
        var user = _contextAccessor.HttpContext.User;
        _userManager = userManager;
        ApplicationUser = _userManager.Users.FirstOrDefault(u => u.Id == _userManager.GetUserId(user));
    }
}

在startup.cs中

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddDbContext<ApplicationContext>(options =>
        options.UsesqlServer(Configuration.GetConnectionString("DefaultConnection"),b => b.MigrationsAssembly("RCI.App")));

    services.AddIdentity<ApplicationUser,IdentityRole>()
        .AddEntityFrameworkStores<ApplicationContext>()
        .AddDefaultTokenProviders();

    services.AddAuthentication();

    services.AddMvc();

    // Add application services.
    services.AddTransient<IEmailSender,AuthMessageSender>();
    services.AddTransient<ISmsSender,AuthMessageSender>();
    services.AddTransient<IHttpContextAccessor,HttpContextAccessor>();

    services.AddOptions();

}

错误代码

A circular dependency was detected for the service of type
‘Microsoft.AspNetCore.Identity.UserManager`1[RCI.App.Models.ApplicationUser]’.

谁能指出我做错了什么?

解决方法

循环依赖通常是应用程序设计不当的标志,应该进行修改.正如我在评论中已经提到的,拥有依赖于用户管理器的数据库上下文似乎不是一个好主意.这使我假设您的数据库上下文做得太多,可能违反了 single-responsibility principle.

只是查看数据库上下文的依赖关系,您已经在其中添加了太多特定于应用程序的状态:您不仅依赖于用户管理器,还依赖于HTTP上下文访问器;并且您也在构造函数中立即解析HTTP上下文(这通常不是最好的主意).

从您的代码摘录中,您似乎想要检索当前用户以供以后使用.如果您想使用它来过滤用户查询,那么您应该考虑将其静态烘焙到数据库上下文实例中是否真的是个好主意.考虑在方法中接受ApplicationUser.这样,您可以摆脱所有这些依赖关系,使您的数据库上下文更易于测试(因为用户不再是上下文的状态),并且您还可以使上下文的单一责任更加清晰:

public IList<Thing> GetThings (ApplicationUser user)
{
    // just an example…
    return Things.Where(t => t.UserId == user.Id).ToList();
}

请注意,这也是inversion of control.而不是让数据库上下文主动检索它应该查询用户(这将增加一个责任,违反SRP),它希望传递应该查询用户,将控件移动到调用代码.

现在,如果您经常查询当前用户内容,解析控制器中的当前用户然后将其传递给数据库上下文可能会有些烦人.在这种情况下,创建一个服务no longer repeat yourself.该服务可以依赖于数据库上下文和其他东西来找出当前用户.

但是,只是从它不应该做的事情中清除数据库上下文就足以解决这个循环依赖.

原文地址:https://www.jb51.cc/csharp/98639.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐