代码之家  ›  专栏  ›  技术社区  ›  topcool

Asp核心,对象引用未设置为存储库模式中对象的实例

  •  2
  • topcool  · 技术社区  · 6 年前

    我正在开发asp core 1.1,我想创建一个 select 我的项目中的存储库模式。

    存储库类中的我的代码:

    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();
        }
    }
    

    和在控制器中

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

    使现代化

    这是我的创业课程

    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?}");
            });
        }
    }
    

    appsettings中的我的连接字符串。json

    {
      "ConnectionStrings": {
      "DefualtConnection" : "Data Source=.;Initial Catalog=DataBaseName;User ID = sa; Password = 123"
      },
    
    
    
    
    
      "Logging": {
       "IncludeScopes": false,
        "LogLevel": {
         "Default": "Warning"
        }
      }
    }
    

    问题是 Object reference not set to an instance of an object 运行时 model = _context.authors.Select(a => new Author 在存储库中。 在上面,我展示了控制器代码、存储库类代码和启动代码。 问题出在哪里?

    注:控制器一切正常。问题就出在repository类中。

    3 回复  |  直到 6 年前
        1
  •  2
  •   Mike    6 年前

    您使用的是静态方法,并且构造函数永远不会被调用,因为您永远不会创建对象。您必须将构造函数更改为:

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

    但这是一种非常糟糕的做法,因为必须在构造函数中设置连接,这也会对上下文类产生硬依赖。

    更好的解决方案是创建一个非静态类

    public class AuthorRepository : IAuthorRepository
    {
        private ApplicationDbContext _context;
    
        public AuthorRepository(ApplicationDbContext context)
        {
            _context = context;
        }
    
        // ...
    }
    
    public interface IAuthorRepository
    {
        // ...
    }
    

    使用注入反转依赖关系:

    启动。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>();
        // ...
    }
    

    控制器:

    public HomeController
    {
        private IAuthorRepository _authorRepository;
    
        public HomeController(IAuthorRepository authorRepository)
        {
            _authorRepository = authorRepository;
        }
    
        [HttpGet]
        public IActionResult Index()
        {
            var q = _autorRepository.GetAuthorList();
            return View(q);
        }
    }
    
        2
  •  0
  •   Hix    6 年前

    您的上下文对象可能为空。您的DI/IoC是如何配置的?我会这样调查的。

    应按如下方式添加数据库上下文:

    public void ConfigureServices(IServiceCollection服务) { 服务。AddDbContext(options=>options.UseSqlite(“数据源=blog.db”)); }

    以下是有关如何配置db上下文的文档: https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext

        3
  •  0
  •   Ehsan Sajjad    6 年前

    您尚未在中注册存储库类 services 因此,它无法通过容器解决。在您的 ConfigureServices 方法尝试以下操作:

    services.AddScoped<AuthorReposetory>();