Alan Laird
Alan Laird

Reputation: 33

Cannot call Injected [through dependency injection] object method

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();
    }

Upvotes: 0

Views: 131

Answers (1)

Ajeet Kumar
Ajeet Kumar

Reputation: 729

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;
        }
    }

Upvotes: 3

Related Questions