Asp core, Object reference not set to an instance of an object in Repository pattern
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);
}
}
Related videos on Youtube
topcool
Updated on June 04, 2022Comments
-
topcool almost 2 years
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 runmodel = _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.
-
Ehsan Sajjad about 6 yearsshow your starup class where you configure context
-
topcool about 6 years@Ehsan Sajjad I add it to my question
-
Ehsan Sajjad about 6 yearsmight be the connection string is not correct, as you have DBContext configure in the startup
-
topcool about 6 years@EhsanSajjad Do I need to put code of the connection?
-
Brad about 6 yearsWhy is your
_context
static inAuthorRepository
?
-
-
topcool about 6 years@hix my context works without repository and in controller but when i use it in repository class not works, any idea to solve it?
-
Hix about 6 yearsWell, I can not see any controller or repository in your configuration. Include them, and your solution will work ;) I think that the exception occurs when you make a call to your AuthorReposetory class from your controller.
-
Hix about 6 yearsAnd please do not put an exception in the dispose method. It is like you shoot yourself in the head :)
-
topcool about 6 yearsI don`t know what I have to do exactly ?
-
Hix about 6 yearsYou have to add your repo, and service classes into dependency injection. You can do that in the ConfigureServices method in your startup class. The syntax is like : services.AddTransient<TMyInterface>(TMyInterfaceImplementation);
-
Ehsan Sajjad about 6 years@saeed put break point in repository constructor and check if context is being set
-
Hix about 6 yearsIt won't call your constructor. It is not aware of its existence. You have to tell the engine what I have mentioned above.
-
topcool about 6 years@Hix in which class shoud i change?
-
Hix about 6 yearsI told you already: You have to add your repo, and service classes into dependency injection. You can do that in the ConfigureServices method in your startup class. The syntax is like : services.AddTransient<TMyInterface, TMyInterfaceImplementation>();
-
Ehsan Sajjad about 6 yearsyou need to register your repository class in container
-
topcool about 6 yearsI add it to
ConfigureServcies
but Repository constructor not work again -
Ehsan Sajjad about 6 yearsthis should work i think, may be you have something else missing too
-
topcool about 6 yearsmaybe i sholud create a new instance of repository in controller to use it
-
Brad about 6 years
services.AddDbContext()
registers the DbContext in DI. There's no need to do it again. And it's best to add the repositories as Scoped, not Transient. -
Mike about 6 years@Brad true that. Edited.