Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions AutoMapperMapping/TodoProfile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using AutoMapper;
using TodoApi.EntityLayer.Entities;
using TodoApi.Models;


namespace TodoApi.AutoMapperMapping
{
public class TodoProfile : Profile
{
public TodoProfile()
{
CreateMap<TodoItem, TodoItemDTO>().ReverseMap();
}
}
}
16 changes: 16 additions & 0 deletions BusinessLayer/Abstract/ITodoItemsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using TodoApi.Models;

namespace TodoApi.BusinessLayer.Abstract
{
public interface ITodoItemsService
{
public Task<TodoItemDTO> CreateTodoAsync(TodoItemDTO item);
public Task<TodoItemDTO> GetTodoAsync(long id);
public Task<List<TodoItemDTO>> GetTodoList();
public Task UpdateTodoAsync(long id, TodoItemDTO item);
public Task DeleteTodoAsync(long id);

}
}
64 changes: 64 additions & 0 deletions BusinessLayer/Concrete/TodoItemsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using AutoMapper;
using System.Collections.Generic;
using System.Threading.Tasks;
using TodoApi.BusinessLayer.Abstract;
using TodoApi.DataAccessLayer.Abstract;
using TodoApi.EntityLayer.Entities;
using TodoApi.Models;

namespace TodoApi.BusinessLayer.Concrete
{
public class TodoItemsService : ITodoItemsService
{
private readonly ITodoItemDal _todoDal;
private readonly IMapper _mapper;

public TodoItemsService(ITodoItemDal todoDal, IMapper mapper)
{
_todoDal = todoDal;
_mapper = mapper;
}

public async Task<TodoItemDTO> CreateTodoAsync(TodoItemDTO item)
{
var itemToBeCreated = DTOToEntity(item);
var createdItem = await _todoDal.CreateAsync(itemToBeCreated);
var createdItemDTO = EntityToDTO(createdItem);
return createdItemDTO;
}

public async Task DeleteTodoAsync(long id)
{
await _todoDal.DeleteAsync(id);
}

public async Task<TodoItemDTO> GetTodoAsync(long id)
{
var item = await _todoDal.GetAsync(id);
var itemDto = EntityToDTO(item);
return itemDto;
}

public async Task<List<TodoItemDTO>> GetTodoList()
{
var todoList = await _todoDal.GetAllAsync();
var todoDTOList = _mapper.Map<List<TodoItemDTO>>(todoList);
return todoDTOList;
}

public Task UpdateTodoAsync(long id, TodoItemDTO item)
{
var updatedItem = DTOToEntity(item);
return _todoDal.UpdateAsync(id, updatedItem);

}
private TodoItemDTO EntityToDTO(TodoItem todoItem)
{
return _mapper.Map<TodoItemDTO>(todoItem);
}
private TodoItem DTOToEntity(TodoItemDTO todoItemDTO)
{
return _mapper.Map<TodoItem>(todoItemDTO);
}
}
}
17 changes: 17 additions & 0 deletions BusinessLayer/DependencyInjection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using AutoMapper;
using Microsoft.Extensions.DependencyInjection;
using TodoApi.BusinessLayer.Abstract;
using TodoApi.BusinessLayer.Concrete;

namespace TodoApi.BusinessLayer
{
public static class DependencyInjection
{
public static IServiceCollection AddApplication(this IServiceCollection services)
{
services.AddScoped<ITodoItemsService, TodoItemsService>();
services.AddAutoMapper(typeof(DependencyInjection));
return services;
}
}
}
82 changes: 10 additions & 72 deletions Controllers/TodoItemsController.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TodoApi.BusinessLayer.Abstract;
using TodoApi.Models;

namespace TodoApi.Controllers
Expand All @@ -11,106 +10,45 @@ namespace TodoApi.Controllers
[ApiController]
public class TodoItemsController : ControllerBase
{
private readonly TodoContext _context;
private readonly ITodoItemsService manager;

public TodoItemsController(TodoContext context)
public TodoItemsController(ITodoItemsService todoManager)
{
_context = context;
manager = todoManager;
}

[HttpGet]
public async Task<ActionResult<IEnumerable<TodoItemDTO>>> GetTodoItems()
{
return await _context.TodoItems
.Select(x => ItemToDTO(x))
.ToListAsync();
return await manager.GetTodoList();
}

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);

if (todoItem == null)
{
return NotFound();
}

return ItemToDTO(todoItem);
return await manager.GetTodoAsync(id);
}

[HttpPut("{id}")]
public async Task<IActionResult> UpdateTodoItem(long id, TodoItemDTO todoItemDTO)
{
if (id != todoItemDTO.Id)
{
return BadRequest();
}

var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}

todoItem.Name = todoItemDTO.Name;
todoItem.IsComplete = todoItemDTO.IsComplete;

try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException) when (!TodoItemExists(id))
{
return NotFound();
}

await manager.UpdateTodoAsync(id, todoItemDTO);
return NoContent();
}

[HttpPost]
public async Task<ActionResult<TodoItemDTO>> CreateTodoItem(TodoItemDTO todoItemDTO)
{
var todoItem = new TodoItem
{
IsComplete = todoItemDTO.IsComplete,
Name = todoItemDTO.Name
};

_context.TodoItems.Add(todoItem);
await _context.SaveChangesAsync();

return CreatedAtAction(
nameof(GetTodoItem),
new { id = todoItem.Id },
ItemToDTO(todoItem));
var createdItem = await manager.CreateTodoAsync(todoItemDTO);
return CreatedAtAction(nameof(GetTodoItem), new { id = createdItem.Id }, createdItem);
}

[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);

if (todoItem == null)
{
return NotFound();
}

_context.TodoItems.Remove(todoItem);
await _context.SaveChangesAsync();

await manager.DeleteTodoAsync(id);
return NoContent();
}

private bool TodoItemExists(long id) =>
_context.TodoItems.Any(e => e.Id == id);

private static TodoItemDTO ItemToDTO(TodoItem todoItem) =>
new TodoItemDTO
{
Id = todoItem.Id,
Name = todoItem.Name,
IsComplete = todoItem.IsComplete
};
}
}
15 changes: 15 additions & 0 deletions DataAccessLayer/Abstract/IGenericDal.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using TodoApi.EntityLayer.Entities.Abstract;

namespace TodoApi.DataAccessLayer.Abstract
{
public interface IGenericDal<T> where T: BaseEntity
{
public Task<T> CreateAsync(T item);
public Task<T> GetAsync(long id);
public Task<List<T>> GetAllAsync();
public Task UpdateAsync(long id, T item);
public Task DeleteAsync(long id);
}
}
8 changes: 8 additions & 0 deletions DataAccessLayer/Abstract/ITodoItemDal.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using TodoApi.EntityLayer.Entities;

namespace TodoApi.DataAccessLayer.Abstract
{
public interface ITodoItemDal : IGenericDal<TodoItem>
{
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore;
using TodoApi.EntityLayer.Entities;

namespace TodoApi.Models
namespace TodoApi.DataAccessLayer.Context
{
public class TodoContext : DbContext
{
Expand Down
15 changes: 15 additions & 0 deletions DataAccessLayer/DependencyInjection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Microsoft.Extensions.DependencyInjection;
using TodoApi.DataAccessLayer.Abstract;
using TodoApi.DataAccessLayer.EntityFramework;

namespace TodoApi.DataAccessLayer
{
public static class DependencyInjection
{
public static IServiceCollection AddDataRepositories(this IServiceCollection services)
{
services.AddScoped<ITodoItemDal, EFTodoItemRepository>();
return services;
}
}
}
14 changes: 14 additions & 0 deletions DataAccessLayer/EntityFramework/EFTodoItemRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using TodoApi.DataAccessLayer.Abstract;
using TodoApi.DataAccessLayer.Context;
using TodoApi.DataAccessLayer.Repositories;
using TodoApi.EntityLayer.Entities;

namespace TodoApi.DataAccessLayer.EntityFramework
{
public class EFTodoItemRepository : GenericRepository<TodoItem>, ITodoItemDal
{
public EFTodoItemRepository(TodoContext context) : base(context)
{
}
}
}
67 changes: 67 additions & 0 deletions DataAccessLayer/Repositories/GenericRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TodoApi.DataAccessLayer.Abstract;
using TodoApi.DataAccessLayer.Context;
using TodoApi.EntityLayer.Entities.Abstract;

namespace TodoApi.DataAccessLayer.Repositories
{
public class GenericRepository<T> : IGenericDal<T> where T : BaseEntity
{
protected private TodoContext _context;

public GenericRepository(TodoContext context)
{
_context = context;
}

public async Task<T> CreateAsync(T item)
{
_context.Add(item);
await _context.SaveChangesAsync();
return item;
}
public async Task DeleteAsync(long id)
{
var item = await _context.Set<T>().FindAsync(id)
?? throw new NullReferenceException("The item with the provided 'id' doesn't exist in the db.");
_context.Remove(item);
await _context.SaveChangesAsync();
}

public async Task<List<T>> GetAllAsync()
{
return await _context.Set<T>().ToListAsync();
}
public async Task<T> GetAsync(long id)
{
return await _context.Set<T>().FindAsync(id) ?? throw new NullReferenceException("The item with the provided 'id' doesn't exist in the db.");
}
public async Task UpdateAsync(long id, T item)
{
if (id != item.Id)
{
throw new ArgumentException("The 'id' parameter doesn't match the 'Id' property of the 'item'.");
}
if (!ItemExists(_context, id))
throw new NullReferenceException("The item with the provided 'id' doesn't exist in the db.");
_context.Update(item);
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException) when (!ItemExists(_context, id))
{
throw new InvalidOperationException("An error occurred while attempting to modify the item with the 'id' in the db. " +
"The item no longer exists in the database.");
}
}

private static bool ItemExists(DbContext context, long id) =>
context.Set<T>().Any(e => e.Id == id);
}
}
11 changes: 11 additions & 0 deletions EntityLayer/Entities/Abstract/BaseEntity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace TodoApi.EntityLayer.Entities.Abstract
{
public abstract class BaseEntity
{
public long Id { get; set; }
}
}
Loading