Search code examples
asp.net-core-mvcasp.net-core-2.1

Using ApplicationDbContext in an extension method


I am currently working on an ASP.NET Core application for internal use. This application should list dates and depending on the date some operations are permitted while others are not. I can perfectly use the scaffolded views and they display exactely what I want with one exception: If an operation is not permitted I want to display them greyed out.

My idea was to add an extension method named IsSpecialOperationPermitted to DateTime so I can easily use dateTimeInstance.IsSpecialOperationPermitted.

The method "IsSpecialOperationPermitted" depends on some calculations and another table in the database. Now, to use my extension method I would like to access that table. Usually I'd create an instance of ApplicationDbContext and query that table.

For ASP.NET Core I have a feeling this is not the correct approach but that I should request an already existing ApplicationDbContext. Usually this ApplicationDbContext is injected more or less automatically but I don't have an ApplicationDbContext in my extension method.

What would be the "correct" way to request an ApplicationDbContext in my extension method?


Solution

  • You are trying to build an abstraction above a DateTime type which is perfectly fine. However, if you require a db context to perform your operation, you should explicitly take a DbContext as argument to signal that your method needs at least to read from it.

    You could write something like this

    public static class DateTimeExtensions
    {
        public static bool IsSpecialOperationPermitted(this DateTime value, ApplicationDbContext context)
        {
            // do here your computation
        }
    }
    

    On the other hand, you could reverse it, and extend the DbContext:

    public static class DbContentExtensions
    {
        public static bool IsSpecialOperationPermitted(this ApplicationDbContext context, DateTime value)
        {
            // do here your computation
        }
    }
    

    The latter, in my opinion, is clearer.

    Keep in mind that extension methods are designed to work with documented side effects and certain operations that theoretically could be "nice to have" as extension methods, could result too cryptic in the long run.

    Also, you should be aware that if the caller has pending changes to the context, your method won't see them unless you inspect the Local property.