Commit 61436fa4 authored by Steve Smith's avatar Steve Smith

Cleaning up EF code and writing some more tests.

parent 0d6a317e
...@@ -4,6 +4,6 @@ namespace CleanArchitecture.Core.Model ...@@ -4,6 +4,6 @@ namespace CleanArchitecture.Core.Model
{ {
public abstract class BaseDomainEvent public abstract class BaseDomainEvent
{ {
public DateTime DateOccurred { get; protected set; } = DateTime.Now; public DateTime DateOccurred { get; protected set; } = DateTime.UtcNow;
} }
} }
\ No newline at end of file
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace CleanArchitecture.Core.Model namespace CleanArchitecture.Core.Model
{ {
// This can be modified to BaseEntity<TId> to support multiple key types (e.g. Guid)
public abstract class BaseEntity public abstract class BaseEntity
{ {
public int Id { get; set; } public int Id { get; set; }
......
using System.Collections.Generic; using CleanArchitecture.Core.Interfaces;
using CleanArchitecture.Core.Interfaces;
using CleanArchitecture.Core.Model; using CleanArchitecture.Core.Model;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System.Linq; using System.Linq;
...@@ -37,54 +36,4 @@ namespace CleanArchitecture.Infrastructure.Data ...@@ -37,54 +36,4 @@ namespace CleanArchitecture.Infrastructure.Data
return base.SaveChanges(); return base.SaveChanges();
} }
} }
public class EfRepository<T> : IRepository<T> where T : BaseEntity
{
private readonly AppDbContext _dbContext;
public EfRepository(AppDbContext dbContext)
{
_dbContext = dbContext;
}
public T GetById(int id)
{
return _dbContext.Set<T>().FirstOrDefault(e => e.Id == id);
}
public List<T> List()
{
return _dbContext.Set<T>().ToList();
}
public T Add(T entity)
{
if (entity.Id == 0)
{
int newId = 1;
var entities = List();
if (entities.Any())
{
newId = entities.Max(z => z.Id) + 1;
}
entity.Id = newId;
}
_dbContext.Set<T>().Add(entity);
_dbContext.SaveChanges();
return entity;
}
public void Delete(T entity)
{
_dbContext.Set<T>().Remove(entity);
_dbContext.SaveChanges();
}
public void Update(T entity)
{
_dbContext.Entry(entity).State = EntityState.Modified;
_dbContext.SaveChanges();
}
}
} }
\ No newline at end of file
using System.Collections.Generic;
using System.Linq;
using CleanArchitecture.Core.Interfaces;
using CleanArchitecture.Core.Model;
using Microsoft.EntityFrameworkCore;
namespace CleanArchitecture.Infrastructure.Data
{
public class EfRepository<T> : IRepository<T> where T : BaseEntity
{
private readonly AppDbContext _dbContext;
public EfRepository(AppDbContext dbContext)
{
_dbContext = dbContext;
}
public T GetById(int id)
{
return _dbContext.Set<T>().SingleOrDefault(e => e.Id == id);
}
public List<T> List()
{
return _dbContext.Set<T>().ToList();
}
public T Add(T entity)
{
// if using in memory EF, need to support IDENTITY keys
//if (entity.Id == 0)
//{
// int newId = 1;
// var entities = List();
// if (entities.Any())
// {
// newId = entities.Max(z => z.Id) + 1;
// }
// entity.Id = newId;
//}
_dbContext.Set<T>().Add(entity);
_dbContext.SaveChanges();
return entity;
}
public void Delete(T entity)
{
_dbContext.Set<T>().Remove(entity);
_dbContext.SaveChanges();
}
public void Update(T entity)
{
_dbContext.Entry(entity).State = EntityState.Modified;
_dbContext.SaveChanges();
}
}
}
\ No newline at end of file
using CleanArchitecture.Infrastructure.Data; using CleanArchitecture.Core.Interfaces;
using CleanArchitecture.Infrastructure;
using CleanArchitecture.Infrastructure.Data;
using CleanArchitecture.Infrastructure.DomainEvents;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
...@@ -32,6 +35,8 @@ namespace CleanArchitecture.Web ...@@ -32,6 +35,8 @@ namespace CleanArchitecture.Web
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc(); services.AddMvc();
services.AddTransient<IDomainEventDispatcher, DomainEventDispatcher>();
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
......
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
using CleanArchitecture.Infrastructure.Data;
using CleanArchitecture.Core.Model;
using System.Linq;
using CleanArchitecture.Core.Events;
using CleanArchitecture.Core.Interfaces;
using Moq;
namespace CleanArchitecture.Tests.Integration.Data
{
public class EfRepositoryAddShould
{
private static DbContextOptions<AppDbContext> CreateNewContextOptions()
{
// Create a fresh service provider, and therefore a fresh
// InMemory database instance.
var serviceProvider = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
// Create a new options instance telling the context to use an
// InMemory database and the new service provider.
var builder = new DbContextOptionsBuilder<AppDbContext>();
builder.UseInMemoryDatabase()
.UseInternalServiceProvider(serviceProvider);
return builder.Options;
}
[Fact]
public void AddItemAndSetId()
{
var repository = GetRepository();
var item = new ToDoItem();
repository.Add(item);
var newItem = repository.List().FirstOrDefault();
Assert.Equal(item, newItem);
Assert.True(newItem.Id > 0);
}
private EfRepository<ToDoItem> GetRepository()
{
var options = CreateNewContextOptions();
var mockDispatcher = new Mock<IDomainEventDispatcher>();
return new EfRepository<ToDoItem>(new AppDbContext(options, mockDispatcher.Object));
}
}
}
\ No newline at end of file
...@@ -3,13 +3,21 @@ ...@@ -3,13 +3,21 @@
"testRunner": "xunit", "testRunner": "xunit",
"dependencies": { "dependencies": {
"CleanArchitecture.Core": "1.0.0-*", "CleanArchitecture.Core": "1.0.0-*",
"CleanArchitecture.Infrastructure": "1.0.0-*",
"NETStandard.Library": "1.6.0", "NETStandard.Library": "1.6.0",
"xunit": "2.2.0-beta2-build3300", "xunit": "2.2.0-beta2-build3300",
"dotnet-test-xunit": "2.2.0-preview2-build1029" "dotnet-test-xunit": "2.2.0-preview2-build1029",
"Microsoft.EntityFrameworkCore": "1.0.0",
"Microsoft.EntityFrameworkCore.InMemory": "1.0.0",
"System.Diagnostics.TraceSource": "4.0.0",
"Moq": "4.6.25-alpha"
}, },
"frameworks": { "frameworks": {
"netcoreapp1.0": { "netcoreapp1.0": {
"imports": [
"dotnet5.6"
],
"dependencies": { "dependencies": {
"Microsoft.NETCore.App": { "Microsoft.NETCore.App": {
"type": "platform", "type": "platform",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment