背后的10多个剃须刀页面代码通过依赖注入获得dbcontexts

时间:2019-07-17 17:38:46

标签: c# asp.net-core dependency-injection razor-pages

我开发了一个C# ASP.NET Core MVC众多的razor pages应用。 我的大多数剃须刀页面都使用日志记录发送电子邮件并使用多个dbcontextes

很多班级是这样的:

class A : PageModel
{
        private readonly ADbContext _context;
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly IEmailSender _emailSender;
        private readonly ILogger<MyModel> _logger;

        public UpdateModel(ADbContext context,
                            UserManager<ApplicationUser> userManager,
                            IEmailSender emailSender,
                            ILogger<MyModel> logger)
        {
            _context = context;
            _userManager = userManager;
            _emailSender = emailSender;
            _logger = logger;
        }
}

我有10多个这样的页面。 创建页面时,必须添加这些字段。所以很多次。

摆脱许多字段声明的理想方法是什么?一个base class继承了我开发的每个页面模型吗?但是,此基类将是具有日志记录,Email和彼此之间确实不太相似的上下文的真正通用基类。 每次我声明使用它们的类时都声明这些字段是一个好的架构选择吗?

3 个答案:

答案 0 :(得分:2)

通常,是的,这就是您要做的。您的依赖项被注入,这意味着您需要ivars来容纳它们,并需要一个构造函数来接受它们。它可以感觉到并且似乎是重复的,但这实际上是一件好事。它使您的班级一目了然:您可以快速查看班级具有哪些依赖关系。

您可以根据需要创建基类。但是,您应该注意只在您的基类中包括真正适用于每个派生的事物。危险在于添加并非在所有情况下实际上都不需要的依赖项,然后,现在您有一堆页面加载不需要和不利用的依赖项。

您还可以在某种程度上使用抽象。例如,如果每个页面都依赖于上下文,但是在不同情况下可能是不同的上下文,则可以使ivar键入为DbContext,而不是具体的上下文类型,然后可以将其设置为任何有效的DbContext的派生。您的记录器也是如此。实际上,您实际上想注入ILogger<MyPageModel>,但是您可以使基类上的ivar仅为ILogger,它将接受任何记录器。

仍然,当您开始执行此操作时,您将很难确定类的依赖关系,因此这是一个让步。就个人而言,如果存在共享逻辑,我只会使用基类。如果基类的唯一目的是定义一组特定的依赖关系,那是不值得的。

答案 1 :(得分:0)

使用过滤器代替它是一个好机会吗?您的过滤器依赖项可以通过DI注入吗?

https://www.learnrazorpages.com/razor-pages/filters

您还可以通过在需要服务的函数级别直接注入而不是在构造函数级别通过在参数上方添加'[FromService]'来注入注入来简化DI的某些情况:

    [HttpGet]
    public ActionResult OnGetDoSomething([FromServices] IEmailSender emailService)
    {
        // Do something
    }

这样,如果不需要,您就不必实例化那些服务。

答案 2 :(得分:0)

这样的事情怎么办?

class A : BasePage {
    public UpdateModel(IServiceProvider provider) : base(provider) {

        // here you can access the base properties

    }
}

class BasePage : PageModel {
    public ADbContext _context { get; set; }
    public UserManager<ApplicationUser> _userManager; { get; set; }
    public IEmailSender _emailSender; { get; set; }
    public ILogger<MyModel> _logger; { get; set; }

    public UpdateModel(IServiceProvider provider) : base(provider) {
        Context = (ADbContext)provider.GetRequiredService(typeof(ADbContext));
        UserManager = (UserManager)provider.GetRequiredService(typeof(UserManager));
        EmailSender = (IEmailSender)provider.GetRequiredService(typeof(IEmailSender));
        Logger = (ILogger)provider.GetRequiredService(typeof(ILogger));
    }
}