Reputation: 411
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".
In the ConfigureServices
method of the Startup Class:
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.
Upvotes: 23
Views: 47011
Reputation: 8625
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:
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; }
}
}
Upvotes: 33
Reputation: 62260
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.
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();
...
}
}
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<SampleDBContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"])
);
}
Upvotes: 2
Reputation: 368
I'm not sure its the best method, but I've always created the repository as an interface that the controllers implement.
IRepository.cs:
public interface IRepository
{
SomeList GetSomeList(string userId);
Some GetSomeDetail(int someId);
}
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).
Happy to be corrected if this is a bad method.
Upvotes: 1