Search code examples
c#.netfactory-patternthree-tier

What is wrong with my code? Showing Unhandled Exception: System.IO.FileNotFoundException


I am learning c# and I am trying to do a basic login Console Application using the Three Tier Architecture with Factory Method Design Pattern. I added all the layers and implemented all the logics associated with the login app. But when i try to run the code using dotnet run command it's asking for the input, after input it is giving error

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'DataAccessLogic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified. at BusinessLogic.User.getUserName() at FactoryMethod.Program.Main(String[] args) in C:\Users\xxx\Desktop\FactoryPatternSample\FactoryMethodSampleApplication\FactoryMethod\Program.cs:line 14

Although the file is present in the BusinessLogic.User.getUserName();

Code provided here

ILogin.cs

public interface ILogin
    {
        bool AttemptLogin();
        string getUserName();

    }

User.cs

using System;
using DataAccessLogic;
namespace BusinessLogic
{
    class User:ILogin
    {
       private string m_username;
       private string m_password;
       public User(string username, string password)
       {
           this.m_username = username;
           this.m_password = password;
       }
       public bool AttemptLogin()
       {
           if(m_username.Equals("abc") && m_password.Equals("abc123"))
           {
               return true;
           }
           return false;
       }
       public string getUserName()
       {
           IGetDetails objectType = GetDetails.getDetails(m_username);
           Console.WriteLine(objectType.getStudentName());
           return objectType.getStudentName();
       }
    }
}

IGetDetails.cs

using System;

namespace DataAccessLogic
{
    public interface IGetDetails
    {
        string getStudentName();
        string getStudentId();
    }
}

GetDetails.cs

namespace DataAccessLogic
{
    public class GetDetails
    {
        public static IGetDetails getDetails(string username)
        {
            Console.WriteLine(username);
            IGetDetails objectType = null;
            objectType = new GetValue(username);
            return objectType;
        }
    }
}

GetValue.cs

namespace DataAccessLogic
{
    public class GetValue:IGetDetails
    {
        private string m_username = string.Empty;
        public GetValue(string username)
        {
            this.m_username = username;
        }
        public string getStudentName()
        {
            return m_username;
        }
        public string getStudentId()
        {
            return "2205";
        }
    }

In the Program.cs

ILogin loginType = Login.attemptLogin(email, password);
        if(loginType.AttemptLogin())
        {
            Console.WriteLine("Name: "+ loginType.getUserName());
        }

in loginType.getUserName() is giving error, if I change the getUserName() method to just return a string like "hello" it is giving output, but when i try to return the string from object IGetDetails giving error.

Full SOurce Code Github

Any help would be appreciated.

Thanks in advance.


Solution

  • As I can see from your FactoryMethod.csproj file, you are not referencing DataAccessLogic in FactoryMethod project. That's why DataAccessLogic.dll is not copied to bin/Debug/netcoreapp2.0/ folder and exception message is literally telling you so.

    You may copy this file by-hands and check if your application runs now, but this will be better to fix your references.

    Explanation:

    You referencing BusinessLogic as external file dependency (..\BusinessLogic\obj\Debug\netstandard2.0\BusinessLogic.dll), not project-to-project. This way .Net CLR doesn't know anything about BusinessLogic dependencies and just copy-if-newer this file to FactoryMethod project's output dir.

    Then, at run-time, CLR will see, that at 14 line of Program.cs file it need a GetDetails class, which is in DataAccessLogic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null assembly. It tryes to load this assembly from a working dir, but didn't find it, so it throws System.IO.FileNotFoundException.

    Solution:

    Always copy this file by hand OR fix your references so, that FactoryMethod project will reference BusinessLogic project (not file). This can be done at Projects tab in Reference Manager window.

    Now Visual studio will build outdated BusinessLogic project and copy-if-newer all its dependencies.

    Also, fix reference in BusinessLogic project in the same way. There is a nice docs about references. Take a look.