Asp核心,Object引用未设置为Repository模式中对象的实例

时间:2018-04-08 16:11:30

标签: asp.net-mvc asp.net-core repository repository-pattern

我正在开发一个asp核心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);
}

更新

这是我的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?}");
        });
    }
}

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 个答案:

答案 0 :(得分:1)

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

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
{
    // ...
}

使用注入反转依赖性:

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

控制器:

public HomeController
{
    private IAuthorRepository _authorRepository;

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

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

答案 1 :(得分:0)

您的_context对象可能为null。您的DI / IoC如何配置?我会这样调查。

您的数据库上下文应该像这样添加:

public void ConfigureServices(IServiceCollection services) {     services.AddDbContext(options =&gt; options.UseSqlite(“Data Source = blog.db”)); }

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

答案 2 :(得分:0)

您尚未在services中注册您的存储库类,因此无法通过容器解析。在ConfigureServices方法中试试这个:

services.AddScoped<AuthorReposetory>();