0

I am having an issue adding a new Account() to a list that is in FileAccountRepository.cs, I am still learning about inheritance, so there might be something that I do not know. In PremiumAccountTestRepository.cs, I am trying to pass the _account that is a new Account() with properties and try to add it to the list that is in FileAccountRepository.cs. The error message I get is that _fileAccountRepository was null on PremiumAccountTestRepository.cs. Would like to know the reason I cannot add to the list that is FileAccountRepository.cs?

FileAccountRepository.cs

public class FileAccountRepository : IAccountRepository
{
    public List<Account> fileAccounts = new List<Account>();

    public FileAccountRepository(string mode)
    {
        GetUsers(mode);
    }        

    public void GetUsers(string mode) {            
        var dictionaryOfModes = new Dictionary<string, string>
        {
            ["FreeTest"] = "F",
            ["BasicTest"] = "B",
            ["PremiumTest"] = "P"
        };

        string path = @".\Accounts.txt";
        string[] rows = File.ReadAllLines(path);

        for (int i = 1; i < rows.Length; i++)
        {
            string[] columns = rows[i].Split(',');

            if (columns[3] == dictionaryOfModes[mode])
            {
                Account _account = new Account();
                _account.AccountNumber = columns[0];
                _account.Name = columns[1];
                _account.Balance = Decimal.Parse(columns[2]);
                if (columns[3] == "F")
                {
                    _account.Type = AccountType.Free;
                }
                else if (columns[3] == "B")
                {
                    _account.Type = AccountType.Basic;
                }
                else if (columns[3] == "P")
                {
                    _account.Type = AccountType.Premium;
                }

                //fileAccounts.Add(_account);
                StoreAccounts(_account);
            }
        }            
    }

    public Account LoadAccount(string AccountNumber)
    {
        return fileAccounts.FirstOrDefault(x => x.AccountNumber == AccountNumber);
    }

    public void SaveAccount(Account account)
    {
        //_account = account;
    }

    public void StoreAccounts(Account addAccount)
    {
        fileAccounts.Add(addAccount);
    }
}

PremiumAccountTestRepository.cs

public class PremiumAccountTestRepository : IAccountRepository
{
    private FileAccountRepository _fileAccountRepository;        

    public PremiumAccountTestRepository(FileAccountRepository fileAccountRepository)
    {
        _fileAccountRepository = fileAccountRepository;
    }

    public PremiumAccountTestRepository()
    {
        StoreAccounts(_account);
    }

    private static Account _account = new Account
    {
        Name = "Premium Account",
        Balance = 100M,
        AccountNumber = "44444",
        Type = AccountType.Premium
    };

    public Account LoadAccount(string AccountNumber)
    {

        if (_fileAccountRepository.fileAccounts.Any(x => x.AccountNumber == AccountNumber))
        {
            return _account;
        }

        return null;
    }

    public void SaveAccount(Account account)
    {
        _account = account;            
    } 

    public void StoreAccounts(Account addAccount)
    {
        _fileAccountRepository.fileAccounts.Add(addAccount); //_fileAccountRepository was null.
    }
}

AccountManagerFactory.cs

public static AccountManager Create()
    {
        string mode = ConfigurationManager.AppSettings["Mode"].ToString();

        switch (mode)
        {
            case "FreeTest":
                return new AccountManager(new FileAccountRepository(mode), new FreeAccountTestRepository());                    
            case "BasicTest":
                return new AccountManager(new FileAccountRepository(mode), new BasicAccountTestRepository());
            case "PremiumTest":
                return new AccountManager(new FileAccountRepository(mode), new PremiumAccountTestRepository());

            default:
                throw new Exception("Mode value in app config is not valid");
        }


    }
Alejandro H
  • 424
  • 5
  • 15
  • 2
    You don't show the code where you initialize an instance of the `PremiumAccountTestRepository` class, but the default constructor does not set `_fileAccountRepository`, and the other one accepts a `null` argument value. In either of those cases, you'd have this issue. – Rufus L Dec 06 '19 at 01:31
  • You may want to show the exception stack trace to help diagnose your issue. – Mark McWhirter Dec 06 '19 at 01:31
  • 1
    Does this answer your question? [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Sir Rufo Dec 06 '19 at 01:41
  • Why you are using two constructors in PremiumAccountTestRepository? it looks like the dependency injection didn't initialize the FileAccountRepository, that's why it is null – Cyber Progs Dec 06 '19 at 01:44
  • I am calling PremiumAccountTestRepository, but not passing in anything. But I need to initialize fileAccountRepository. – Alejandro H Dec 06 '19 at 01:47
  • Is there another way to initialize? – Alejandro H Dec 06 '19 at 01:52
  • I must say I don’t like the new “does this answer your question” prefix. I find it somewhat smarmy – MickyD Dec 06 '19 at 02:11
  • try this code, I didn't test it because I don't have the whole code : – Cyber Progs Dec 06 '19 at 02:11
  • I added AccountManager.cs, I will probably have to go a different route, if I am not doing something right. – Alejandro H Dec 06 '19 at 02:17

3 Answers3

1

Try this code, I was not able to test it :

  public class PremiumAccountTestRepository : IAccountRepository
    {
    private FileAccountRepository _fileAccountRepository;
    private Account _account;   

    public PremiumAccountTestRepository(FileAccountRepository fileAccountRepository)
    {
        _fileAccountRepository = fileAccountRepository;

        _account= new Account
        {
            Name = "Premium Account",
            Balance = 100M,
            AccountNumber = "44444",
            Type = AccountType.Premium
        };


        StoreAccounts(_account);
    }


    public Account LoadAccount(string AccountNumber)
    {

        if (_fileAccountRepository.fileAccounts.Any(x => x.AccountNumber == AccountNumber))
        {
            return _account;
        }

        return null;
    }

    public void SaveAccount(Account account)
    {
        _account = account;            
    } 

    public void StoreAccounts(Account addAccount)
    {
        _fileAccountRepository.fileAccounts.Add(addAccount); //_fileAccountRepository was 
                                                                  null.
    }
   }

The issue in your code is that you have two constructors, _fileAccountRepository is not initialized with the dependency injection because of the other empty constructor

Cyber Progs
  • 2,964
  • 3
  • 23
  • 32
  • Ok I get it, so in my AccountMangerFactory.cs, what would I have to pass in to new PremiumAccountTestRepository() ? – Alejandro H Dec 06 '19 at 02:44
  • you don't have to pass anything the dependency injector should take care of creating new instances, do you still got any errors? – Cyber Progs Dec 06 '19 at 02:55
  • it has an error on AccountManagerFactory.cs on new PremiumAccountTestRepository(), says that there is no argument given that corresponds to required formal paramer fileAccountRepository – Alejandro H Dec 06 '19 at 02:59
  • because you are trying to initialize an object with dependency injection in a static class, it will not work, what kind of IoC container you are using to manage the dependency injection? – Cyber Progs Dec 06 '19 at 03:08
  • I have to review exactly what is IoC container, but for now I will just share my github project: https://github.com/alextech1/SWGBanks . – Alejandro H Dec 06 '19 at 03:14
  • check this tutorial, it contains a good and simple example https://www.tutorialsteacher.com/ioc/ioc-container – Cyber Progs Dec 06 '19 at 03:35
  • I just watched this video, https://www.youtube.com/watch?v=mCUNrRtVVWY , and I dont think I have a dependency injector. In the video he uses autofac, looks like there is many to chose from, not sure if that matters. – Alejandro H Dec 07 '19 at 02:08
  • I think you need the basic implementation of dependency injector, so it doesn't matter which one you choose, just make sure to choose a library that helps with the static class – Cyber Progs Dec 08 '19 at 01:22
  • 1
    Got it working now, using the video I watched helped. – Alejandro H Dec 08 '19 at 19:08
0

_fileAccountRepository is set in exactly one place in your code, in

public PremiumAccountTestRepository(FileAccountRepository fileAccountRepository)

The second creator

public PremiumAccountTestRepository()

Does not set it, so it will be null.

I suggest putting a break in both creators and see which is being called, and then you will know where from.

I don't see the top level driving code in your posting. I strongly suspect that the second form of the creator is getting called, and thus _fileAccountRepository is null.

Richard Keene
  • 308
  • 2
  • 9
  • I added the code for AccountManagerFactory.cs, which is where I am calling. As you can see, I have an issue. I don't know if I should be passing in something or not. – Alejandro H Dec 06 '19 at 01:38
0

what happens if this line is altered from

private FileAccountRepository _fileAccountRepository

to

private FileAccountRepository _fileAccountRepository = new FileAccountRepository()
Shane.A
  • 64
  • 9