0

I am trying to call the SendQueuedEmailsToRecipients method from a Maintenance class. My understanding is that because the Maintenance class depends on the SendQueuedEmailsToRecipients method (which is in a different namespace) then I need to DI the method into the Maintenance class. Is this correct? - I am having trouble doing this.

I am unsure if I am going about this the right way. (Still learning Csharp and ASP.NET core). I do not really know where to call up IBulkEmailQueue. Sorry- I am a bit lost here but am trying to understand.

My code is: root/BLL/MaintenanceBLL/Maintenance.cs

public class Maintenance : IMaintenance
{
    private readonly ApplicationDbContext _context;

    public Maintenance(ApplicationDbContext Context)
    {
        _context = Context;
    }
    //-------------------**MY DI ATTEMPT**
    private readonly BulkEmailQueue _bulkEmailQueue;

    public Maintenance(BulkEmailQueue BulkEmailQueue)
    {
        _bulkEmailQueue = BulkEmailQueue;
    }
    //-------------
    public void DoMaintenance()
    {
        //Parse Maintenance table and action those items
        //where Active=True and ActionDate has pass
        //==================================
        //Retrieve list of rows in Maintenance table
        var maintenances = _context.Maintenance;
        foreach (Models.Maintenance m in maintenances)
        {
            switch (m.Subject)
            {
                case "Send Queued Emails":
                    if (m.ActionDateTime <= DateTime.Now)
                    {
                        //BulkEmailQueue bulkEmailQueue = new BulkEmailQueue();//Create new instance 
                        //BulkEmailQueue.SendQueuedEmailsToRecipients();

                        _bulkEmailQueue.SendQueuedEmailsToRecipients();  **ERROR DISPLAYS ON THIS LINE**. System.NullReferenceException: 'Object reference not set to an instance of an object.'

                        m.ActionDateTime = DateTime.Now.AddMinutes(15);
                        m.LastActionDateTime = DateTime.Now;
                    }
                    break;
                default:
                    // code block
                    break;
            }
        }

My root/startup contains:

       services.AddTransient<IMaintenance, Maintenance>();
       services.AddTransient<IBulkEmailQueue, BulkEmailQueue>();

My root/Services/IBulkEmailQueue.cs contains

    public interface IBulkEmailQueue
     {
       public void SendQueuedEmailsToRecipients();
       public void DeleteRecord();
       public void AddToQueue();
    }
2
  • 1
    Why do you have two constructors for your Maintenance class? Which one will be called? Commented Aug 29, 2020 at 9:19
  • are we assuming ApplicationDbContext is also set correctly in startup file? Commented Aug 29, 2020 at 9:29

1 Answer 1

3

It is all fine except that Only one constructor shall be required to inject the dependency IMaintenance and ApplicationDbContext. Also, make sure that ApplicationDbContext is also setup in the startup.cs as done for IMaintenance and IBulkEmailQueue

The MODIFIED code goes as below.

public class Maintenance : IMaintenance
{
    private readonly ApplicationDbContext _context;

    private readonly IBulkEmailQueue _bulkEmailQueue; // this should be interface

    public Maintenance(ApplicationDbContext Context,IBulkEmailQueue BulkEmailQueue)
    {
        _context = Context;
        _bulkEmailQueue = BulkEmailQueue;
    }
    //-------------------**MY DI ATTEMPT**
    public void DoMaintenance()
    {
    //Parse Maintenance table and action those items
    //where Active=True and ActionDate has pass
    //==================================
    //Retrieve list of rows in Maintenance table
    var maintenances = _context.Maintenance;
    foreach (Models.Maintenance m in maintenances)
    {
        switch (m.Subject)
        {
            case "Send Queued Emails":
                if (m.ActionDateTime <= DateTime.Now)
                {
                    _bulkEmailQueue.SendQueuedEmailsToRecipients();  **NO ERROR SHALL DISPLAY ON THIS LINE**. 

                    m.ActionDateTime = DateTime.Now.AddMinutes(15);
                    m.LastActionDateTime = DateTime.Now;
                }
                break;
            default:
                // code block
                break;
        }
    }
Sign up to request clarification or add additional context in comments.

1 Comment

Brilliant, thank you Ajeet. Much appreciated. I am trying to learn C# and ASP.NET core Razor pages but I come from an ASP.NET web forms and VBA background. It is a bit of an uphill challenge!!! Thanks again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.