How do we access a non-static variable without the need for instantiation? Entity Framework - ASP. Net Core

Shervan360 1,661 Reputation points
2023-10-17T17:54:42.7833333+00:00

In the EFStoreRepository class, I have a variable of StoreDbContext type(context)

StoreDbContext class and Products field inside it are not static. but I can call Products without instantiating the StoreDbContext class like a static field.

How do we access a non-static field without the need for instantiation?

using Microsoft.AspNetCore.Mvc;
using SportsStore.Models;

namespace SportsStore.Controllers
{
     public class HomeController : Controller
     {
          private IStoreRepository repository;
        public HomeController(IStoreRepository repo)
        {
               repository = repo;
        }
        public IActionResult Index()
          {
               return View(repository.Products);
          }
     }
}

using Microsoft.EntityFrameworkCore;

namespace SportsStore.Models
{

     public static class SeedData
     {

          public static void EnsurePopulated(IApplicationBuilder app)
          {
               StoreDbContext context = app.ApplicationServices
                   .CreateScope().ServiceProvider.GetRequiredService<StoreDbContext>();

               if (context.Database.GetPendingMigrations().Any())
               {
                    context.Database.Migrate();
               }

               if (!context.Products.Any())
               {
                    context.Products.AddRange(
                        new Product
                        {
                             Name = "Kayak",
                             Description = "A boat for one person",
                             Category = "Watersports",
                             Price = 275
                        },
                        new Product
                        {
                             Name = "Lifejacket",
                             Description = "Protective and fashionable",
                             Category = "Watersports",
                             Price = 48.95m
                        },
                        new Product
                        {
                             Name = "Soccer Ball",
                             Description = "FIFA-approved size and weight",
                             Category = "Soccer",
                             Price = 19.50m
                        },
                        new Product
                        {
                             Name = "Corner Flags",
                             Description = "Give your playing field a professional touch",
                             Category = "Soccer",
                             Price = 34.95m
                        },
                        new Product
                        {
                             Name = "Stadium",
                             Description = "Flat-packed 35,000-seat stadium",
                             Category = "Soccer",
                             Price = 79500
                        },
                        new Product
                        {
                             Name = "Thinking Cap",
                             Description = "Improve brain efficiency by 75%",
                             Category = "Chess",
                             Price = 16
                        },
                        new Product
                        {
                             Name = "Unsteady Chair",
                             Description = "Secretly give your opponent a disadvantage",
                             Category = "Chess",
                             Price = 29.95m
                        },
                        new Product
                        {
                             Name = "Human Chess Board",
                             Description = "A fun game for the family",
                             Category = "Chess",
                             Price = 75
                        },
                        new Product
                        {
                             Name = "Bling-Bling King",
                             Description = "Gold-plated, diamond-studded King",
                             Category = "Chess",
                             Price = 1200
                        }
                    );
                    context.SaveChanges();
               }
          }
     }
}

using SportsStore.Models;
using Microsoft.EntityFrameworkCore;
internal class Program

{
     private static void Main(string[] args)
     {
          var builder = WebApplication.CreateBuilder(args);
          builder.Services.AddControllersWithViews();
          builder.Services.AddDbContext<StoreDbContext>(opts =>
          {
               opts.UseSqlServer(builder.Configuration["ConnectionStrings:SportsStoreConnection"]);
          });

          builder.Services.AddScoped<IStoreRepository, EFStoreRepository>();

          var app = builder.Build();

          app.UseStaticFiles();
          app.MapDefaultControllerRoute();

          SeedData.EnsurePopulated(app);

          app.Run();
     }
}

Screenshot 2023-10-17 104724

Screenshot 2023-10-17 104825

using Microsoft.EntityFrameworkCore;

namespace SportsStore.Models
{
     public class StoreDbContext : DbContext
     {
          public StoreDbContext(DbContextOptions<StoreDbContext> options) : base(options) { }
          public DbSet<Product> Products => Set<Product>();
     }
}

using System.ComponentModel.DataAnnotations.Schema;

namespace SportsStore.Models
{
     public class Product
     {
          public long? ProductID { get; set; }
          public string Name { get; set; } = String.Empty;
          public string Description { get; set; } = String.Empty;
          [Column(TypeName = "decimal(8,2)")]
          public decimal Price { get; set; }
          public string Category { get; set; } = String.Empty;
     }
}

namespace SportsStore.Models
{
     public interface IStoreRepository
     {
          IQueryable<Product> Products { get; }
     }
}

namespace SportsStore.Models
{
     public class EFStoreRepository : IStoreRepository
     {
          private StoreDbContext context;
          public EFStoreRepository(StoreDbContext ctx) => context = ctx;
          public IQueryable<Product> Products => context. Products;
     }
}

Developer technologies | .NET | Entity Framework Core
Developer technologies | ASP.NET | ASP.NET Core
Developer technologies | .NET | Other
0 comments No comments
{count} vote

Accepted answer
  1. AgaveJoe 30,126 Reputation points
    2023-10-20T13:09:54.6833333+00:00

    I edited my question and put all the code in my project. Now could you please tell me who is responsible for providing a StoreDbContext to the constructor in the EFStoreRepository class? I didn't create an instance StoreDbContext.

    The simple answer is dependency injection. The code registers the StoreDbContext in the Project.cs file.

    builder.Services.AddDbContext<StoreDbContext>(opts =>
    {
         opts.UseSqlServer(builder.Configuration["ConnectionStrings:SportsStoreConnection"]);
    });
    

    The code also registers the repository service in Project.cs. Order matter here. The StoreDbContext must be registered before the repository.

    builder.Services.AddScoped<IStoreRepository, EFStoreRepository>();
    

    Looking at the code above, any constructor that has a IStoreRepository parameter gets a concrete EFStoreRepository type. This is all handled by ASP.NET Core's dependency injection container.

    private IStoreRepository repository;
    public HomeController(IStoreRepository repo)
    {
        repository = repo;
    }
    

    Likewise the repository gets a concrete StoreDbContext through constructor injection.

    The SeedData class fetches the StoreDbContext directly from the DI contains.

    I think you'll be interested in reading the reference documentation

    Dependency injection in ASP.NET Core

    1 person found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Bruce (SqlWork.com) 77,686 Reputation points Volunteer Moderator
    2023-10-17T18:19:28.2966667+00:00

    non-static variables can only be accessed via the instance. static variables are referenced <ClassName>.<VariableName> as they are properties of the class definition.

    in your line 7, context is an instance variable, and you are accessing the instance property .Products.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.