7

I'm currently refactoring a bloated MVC .NET Core app to a more simpler .NET Core app using Razor Pages and Mediatr.

In the MVC approach there's a BaseController that all controllers inherits from. The BaseController handles the Mediatr DI. How will I go about doing this in Razor Pages? Is it wise to create a BasePageModel class that handles the Mediatr DI, or should I just include the Mediatr DI in every PageModel I create?

FLICKER
  • 6,439
  • 4
  • 45
  • 75
KlaasJan
  • 193
  • 2
  • 12
  • 1
    I wouldn't create a BasePageModel just to handle common injected services. You still have to inject them into your derived classes and then pass them on to the base constructor, so I don't see that you gain much. – Mike Brind Feb 22 '19 at 08:12

2 Answers2

7

I'm using a BasePageModel class to hold common code and properties. The subclasses get the DI injected objects and then pass them up to the base class which handles them with an optional parameters list. There might be more elegant way to accomplish this but this is working well for me.

public class BasePageModel : PageModel {
    public BasePageModel(params object[] list) {
        foreach (var item in list) {
            if (item is ILoggerFactory loggerFactory) {
                _logger = loggerFactory.CreateLogger("Projects");
            }
            if (item is ApplicationDbContext context) {
                _dbContext = context;
            }
            if (item is UserManager<ApplicationUser> manager) {
                _userManager = manager;
            }
            if (item is IHostingEnvironment env) {
                _environment = env;
            }
        }
    }

public class IndexModel : BasePageModel {

    public IndexModel(ApplicationDbContext context, UserManager<ApplicationUser> userManager, ILoggerFactory loggerFactory) :
        base(context, userManager, loggerFactory) { }
}
Brad Patton
  • 4,007
  • 4
  • 34
  • 44
1

I tried to use the marked answer but when it comes to below line in code:

private readonly ILogger<IndexPage> _logger;

it seems we have to consider the generic type for ILogger

So, I created a generic base class and came up with a variation of the selected answer.

public class _BasePageModel<T> : PageModel where T : PageModel
{
    protected readonly ILogger<T> _logger;

    public _BasePageModel(params object[] list)
    {
        foreach (var item in list)
        {
            if (item is ILogger logger)
            {
                _logger = (ILogger<T>?)logger;
            }
            // check if there are other injected dependencies
        }
    }
}

And changed the Index page as follow:

public class IndexModel : _BasePageModel<IndexModel>
{
    public IndexModel(ILogger<IndexModel> logger) : base(logger)
    {
        //
    }
}
FLICKER
  • 6,439
  • 4
  • 45
  • 75