如何在ASP中使用依赖注入设计一个存储库模式。网络核心MVC ?

时间:2021-09-06 15:47:17

Being fairly new to ASP.NET Core 1.0 MVC, I have decided to use a Repository Pattern for an MVC Core app; I'm using a SQL DB for the Data Layer SampleDbContext, and I want to have a Repository class for some of my business Entities. So far I have done the following in thestartup.cs, CustomerController.cs and CustomerRepository.cs files, where a sample Entity is "Customer".

对ASP来说是相当新的。NET Core 1.0 MVC,我决定使用一个MVC Core app的存储库模式;我正在为数据层SampleDbContext使用SQL DB,我想为我的一些业务实体拥有一个存储库类。到目前为止,我在创业公司做了以下工作。cs,CustomerController。cs和CustomerRepository。cs文件,其中示例实体是“Customer”。

In the ConfigureServices method of the Startup Class:

在启动类的ConfigureServices方法中:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<SampleDbContext>(options =>
       options.UseSqlServer(Configuration.GetConnectionString("SampleDB")));
}

In a Controller:

控制器:

public class CustomerController : Controller
{

    private SampleDBContext _context;
    private CustomerRepository = new CustomerRepository (new SampleDBContext());

    public CustomerController(SampleDBContext context)
    {
        _context = context;
    }
}

In a Repository:

在一个存储库:

public class CustomerRepository
{
    private SampleDBContext _context;

    public CustomerRepository(SampleDBContext context)
    {
        _context = context;
    }
}

With this design, I plug in the SampleDbContext as a service in the startup.cs once, and then for each Controller (that receives Dependency Injection) I instantiate a corresponding Repository passing along a new instance of the SampleDbContext. Is this repetitive instantiation of the DB context a good design for a multi-user environment? I suppose I could add each Repository as a service to the startup.cs but that doesn't look nice. Please tell me a good design implementation for my case, or put me in the right track if I'm lost.

通过这种设计,我在启动时将SampleDbContext作为服务插入。cs一次,然后对于每个控制器(接收依赖注入),我实例化一个对应的存储库,它传递一个SampleDbContext的新实例。这种对DB上下文的重复实例化对于多用户环境来说是一个好的设计吗?我想我可以将每个存储库添加为启动的服务。但那看起来不太好。请告诉我一个好的设计实现,如果我迷路了,请把我放在正确的轨道上。

3 个解决方案

#1


19  

You can see simple example how to use repository pattern:

您可以看到如何使用存储库模式的简单示例:

You create repository interface:

你创建存储库接口:

using System.Collections.Generic;

namespace TodoApi.Models
{
    public interface ITodoRepository
    {
        void Add(TodoItem item);
        IEnumerable<TodoItem> GetAll();
        TodoItem Find(long key);
        void Remove(long key);
        void Update(TodoItem item);
    }
}

Then implement it:

然后实现它:

using System;
using System.Collections.Generic;
using System.Linq;

namespace TodoApi.Models
{
    public class TodoRepository : ITodoRepository
    {
        private readonly TodoContext _context;

        public TodoRepository(TodoContext context)
        {
            _context = context;
            Add(new TodoItem { Name = "Item1" });
        }

        public IEnumerable<TodoItem> GetAll()
        {
            return _context.TodoItems.ToList();
        }

        public void Add(TodoItem item)
        {
            _context.TodoItems.Add(item);
            _context.SaveChanges();
        }

        public TodoItem Find(long key)
        {
            return _context.TodoItems.FirstOrDefault(t => t.Key == key);
        }

        public void Remove(long key)
        {
            var entity = _context.TodoItems.First(t => t.Key == key);
            _context.TodoItems.Remove(entity);
            _context.SaveChanges();
        }

        public void Update(TodoItem item)
        {
            _context.TodoItems.Update(item);
            _context.SaveChanges();
        }
    }
}

Then register in ConfigureServices:

然后在ConfigureServices注册:

services.AddSingleton<ITodoRepository, TodoRepository>();

Then inject it to Controller:

然后注入控制器:

namespace TodoApi.Controllers
{
    [Route("api/[controller]")]
    public class TodoController : Controller
    {
        public TodoController(ITodoRepository todoItems)
        {
            TodoItems = todoItems;
        }
        public ITodoRepository TodoItems { get; set; }
    }
}

#2


2  

Some argue that DbContext itself is a repository pattern. If you want to go that route, you can download the sample code at ASP.NET Core and Angular 2.

有些人认为DbContext本身是一个存储库模式。如果您想走这条路,您可以在ASP下载示例代码。净核和角2。

For example -

例如,

public class CustomerController : Controller
{
    private SampleDBContext _context;

    public CustomerController(SampleDBContext context)
    {
        _context = context;
    }

    public async Task<IActionResult> Index(int id)
    {
        var user = _context.Users.Where(i => i.Id == id).FirstOrDefault();
        ...
    }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<SampleDBContext>(options =>
        options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"])
        );
}

#3


1  

I'm not sure its the best method, but I've always created the repository as an interface that the controllers implement.

我不确定这是最好的方法,但我总是将存储库创建为控制器实现的接口。

IRepository.cs:

IRepository.cs:

public interface IRepository
{
     SomeList GetSomeList(string userId);
     Some GetSomeDetail(int someId);
}

DbInterface.cs:

DbInterface.cs:

public class DbInterface : IRepository
{
    public SomeList GetSomeList(string userId)
    {

    }

    public Some GetSomeDetail(int someId)
    {

    }
}

SomeList being a datatype that I've defined with all the properties to be displayed on a page as a list. I.e. a list of tasks in a task app. Some being a data type defined which returns the details of a task (so the input would be taskId or such).

SomeList是一个数据类型,我定义它的所有属性都以列表的形式显示在页面上。例如,任务应用程序中的任务列表。有些是定义的数据类型,返回任务的细节(因此输入是taskId或类似的)。

Happy to be corrected if this is a bad method.

如果这是一个糟糕的方法,很高兴被纠正。

#1


19  

You can see simple example how to use repository pattern:

您可以看到如何使用存储库模式的简单示例:

You create repository interface:

你创建存储库接口:

using System.Collections.Generic;

namespace TodoApi.Models
{
    public interface ITodoRepository
    {
        void Add(TodoItem item);
        IEnumerable<TodoItem> GetAll();
        TodoItem Find(long key);
        void Remove(long key);
        void Update(TodoItem item);
    }
}

Then implement it:

然后实现它:

using System;
using System.Collections.Generic;
using System.Linq;

namespace TodoApi.Models
{
    public class TodoRepository : ITodoRepository
    {
        private readonly TodoContext _context;

        public TodoRepository(TodoContext context)
        {
            _context = context;
            Add(new TodoItem { Name = "Item1" });
        }

        public IEnumerable<TodoItem> GetAll()
        {
            return _context.TodoItems.ToList();
        }

        public void Add(TodoItem item)
        {
            _context.TodoItems.Add(item);
            _context.SaveChanges();
        }

        public TodoItem Find(long key)
        {
            return _context.TodoItems.FirstOrDefault(t => t.Key == key);
        }

        public void Remove(long key)
        {
            var entity = _context.TodoItems.First(t => t.Key == key);
            _context.TodoItems.Remove(entity);
            _context.SaveChanges();
        }

        public void Update(TodoItem item)
        {
            _context.TodoItems.Update(item);
            _context.SaveChanges();
        }
    }
}

Then register in ConfigureServices:

然后在ConfigureServices注册:

services.AddSingleton<ITodoRepository, TodoRepository>();

Then inject it to Controller:

然后注入控制器:

namespace TodoApi.Controllers
{
    [Route("api/[controller]")]
    public class TodoController : Controller
    {
        public TodoController(ITodoRepository todoItems)
        {
            TodoItems = todoItems;
        }
        public ITodoRepository TodoItems { get; set; }
    }
}

#2


2  

Some argue that DbContext itself is a repository pattern. If you want to go that route, you can download the sample code at ASP.NET Core and Angular 2.

有些人认为DbContext本身是一个存储库模式。如果您想走这条路,您可以在ASP下载示例代码。净核和角2。

For example -

例如,

public class CustomerController : Controller
{
    private SampleDBContext _context;

    public CustomerController(SampleDBContext context)
    {
        _context = context;
    }

    public async Task<IActionResult> Index(int id)
    {
        var user = _context.Users.Where(i => i.Id == id).FirstOrDefault();
        ...
    }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<SampleDBContext>(options =>
        options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"])
        );
}

#3


1  

I'm not sure its the best method, but I've always created the repository as an interface that the controllers implement.

我不确定这是最好的方法,但我总是将存储库创建为控制器实现的接口。

IRepository.cs:

IRepository.cs:

public interface IRepository
{
     SomeList GetSomeList(string userId);
     Some GetSomeDetail(int someId);
}

DbInterface.cs:

DbInterface.cs:

public class DbInterface : IRepository
{
    public SomeList GetSomeList(string userId)
    {

    }

    public Some GetSomeDetail(int someId)
    {

    }
}

SomeList being a datatype that I've defined with all the properties to be displayed on a page as a list. I.e. a list of tasks in a task app. Some being a data type defined which returns the details of a task (so the input would be taskId or such).

SomeList是一个数据类型,我定义它的所有属性都以列表的形式显示在页面上。例如,任务应用程序中的任务列表。有些是定义的数据类型,返回任务的细节(因此输入是taskId或类似的)。

Happy to be corrected if this is a bad method.

如果这是一个糟糕的方法,很高兴被纠正。