topcool
topcool

Reputation: 2720

Asp core, Object reference not set to an instance of an object in Repository pattern

I am working on an asp core 1.1 and i want to create a select repository pattern in my project.

my code in repository class :

public class AuthorReposetory : IDisposable
{
    private static ApplicationDbContext _context;

    public AuthorReposetory(ApplicationDbContext context)
    {
        _context = context;
    }




    public static List<Author> GetAuthorList()
    {
        List<Author> model = new List<Author>();

        model = _context.authors.Select(a => new Author
        {
            AuthorId = a.AuthorId,
            AuthorName = a.AuthorName,
            AuthorDescription = a.AuthorDescription
        }).ToList();

        return model;
    }

    public void Dispose()
    {
        throw new NotImplementedException();
    }

    ~AuthorReposetory()
    {
        Dispose();
    }
}

and in controller

[HttpGet]
public IActionResult Index()
{
    var q = AuthorReposetory.GetAuthorList();
    return View(q);
}

Update

Here is my StartUp Class

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        //define Connection string
        services.AddDbContext<ApplicationDbContext>(option => option.UseSqlServer(Configuration.GetConnectionString("DefualtConnection")));
        //For Create and use identity in database
        services.AddIdentity<ApplicationUser, ApplicationRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();


        // Add framework services.
        services.AddMvc();
        services.AddAutoMapper();
        services.AddPaging();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();
        app.UseIdentity();


        app.UseMvc(routes =>
        {

            //New Area For Admin
            routes.MapRoute(
                name: "Admin",
                template: "{area:exists}/{controller=Admin}/{action=Index}/{id?}");

            //New Area For User
            routes.MapRoute(
                name: "UserProfile",
                template: "{area:exists}/{controller=UserProfile}/{action=Index}/{id?}");

            //tranditional Routing
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

My Connection string in appsettings.json

{
  "ConnectionStrings": {
  "DefualtConnection" : "Data Source=.;Initial Catalog=DataBaseName;User ID = sa; Password = 123"
  },





  "Logging": {
   "IncludeScopes": false,
    "LogLevel": {
     "Default": "Warning"
    }
  }
}

The problem is Object reference not set to an instance of an object when run model = _context.authors.Select(a => new Author in repository. In the above i show controller code, Repository class code and start up code to figure out. Where can the problem be?

Note : everything is good in controller. just problem is in repository class.

Upvotes: 4

Views: 18868

Answers (3)

Mike
Mike

Reputation: 3015

You are using static methods and the constructor is never called as you never create the object. You would have to change your constructor to:

public static AuthorReposetory()
{
    _context = new ApplicationDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("DefualtConnection")));
}

but that's quite bad practice since you have to setup the connection in the constructor and this also created a hard dependency on your context class.

A better solution would be to create a non static class

public class AuthorRepository : IAuthorRepository
{
    private ApplicationDbContext _context;

    public AuthorRepository(ApplicationDbContext context)
    {
        _context = context;
    }

    // ...
}

public interface IAuthorRepository
{
    // ...
}

Reverse the dependency with injection:

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    //define Connection string and setup dependency injection
    services.AddDbContext<ApplicationDbContext>(option => option.UseSqlServer(Configuration.GetConnectionString("DefualtConnection")));
    services.AddScoped<IAuthorRepository, AuthorRepository>();
    // ...
}

Controller:

public HomeController
{
    private IAuthorRepository _authorRepository;

    public HomeController(IAuthorRepository authorRepository)
    {
        _authorRepository = authorRepository;
    }

    [HttpGet]
    public IActionResult Index()
    {
        var q = _autorRepository.GetAuthorList();
        return View(q);
    }
}

Upvotes: 2

Ehsan Sajjad
Ehsan Sajjad

Reputation: 62488

You have not registered your repository class in the services so it is not getting resolved via the container. In your ConfigureServices method try this:

services.AddScoped<AuthorReposetory>();

Upvotes: 0

Hix
Hix

Reputation: 39

Probably your _context object is null. How is your DI/IoC configured? I would investigate in that way.

Your db context should be added like this :

public void ConfigureServices(IServiceCollection services) { services.AddDbContext(options => options.UseSqlite("Data Source=blog.db")); }

Here is the documentation on how to configure your db context: https://learn.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext

Upvotes: 0

Related Questions