Skip to content

Commit

Permalink
Merge pull request #8 from Boriszn/feature/ISS-1-Add-Automapper
Browse files Browse the repository at this point in the history
Feature/iss 1 add automapper
  • Loading branch information
Boriszn authored Feb 18, 2018
2 parents adfca04 + b81b9fd commit 8af0a4b
Show file tree
Hide file tree
Showing 17 changed files with 212 additions and 55 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

Web API Solution demonstrates mutliteantcy architecture, using Entity Framework, UnitOfWork, Repository patterns

![alt text](https://github.com/Boriszn/DeviceManager.Api/blob/feature/ISS-1-Add-Automapper/assets/arhitecture-diag.png "Logo Title Text 1")


## Installation

1. Clone repository
Expand Down
Binary file added assets/arhitecture-diag.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions src/DeviceManager.Api/Controllers/DevicesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ public DevicesController(IDeviceService deviceService)
[HttpGet]
[SwaggerOperation("GetDevices")]
[ValidateActionParameters]
public IActionResult Get([FromQuery][Required]string page, [FromQuery][Required]string pageSize)
public IActionResult Get([FromQuery][Required]int page, [FromQuery][Required]int pageSize)
{
if (!this.ModelState.IsValid)
{
return new BadRequestObjectResult(this.ModelState);
}

return new ObjectResult(deviceService.GetDevices());
return new ObjectResult(deviceService.GetDevices(page, pageSize));
}

/// <summary>
Expand Down Expand Up @@ -78,6 +78,8 @@ public IActionResult GetDeviceByTitle(string deviceTitle)
/// <returns></returns>
[HttpPost]
[SwaggerOperation("CreateDevice")]
[SwaggerResponse(204, null, "Device was saved successfuly")]
[SwaggerResponse(400, null, "Error in saving the Device")]
public IActionResult Post([FromBody]DeviceViewModel deviceViewModel)
{
if (!this.ModelState.IsValid)
Expand Down
5 changes: 5 additions & 0 deletions src/DeviceManager.Api/Data/Management/ContextFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ private static void ValidateTenantId(string tenantId)
{
throw new ArgumentNullException(nameof(tenantId));
}

if (!Guid.TryParse(tenantId, out Guid tenantGuid))
{
throw new ArgumentNullException(nameof(tenantId));
}
}
}
}
8 changes: 8 additions & 0 deletions src/DeviceManager.Api/Data/Management/IRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ public interface IRepository<T>
/// <returns>List of entities</returns>
IQueryable<T> GetAll();

/// <summary>
/// Gets all. With data pagination.
/// </summary>
/// <param name="page">The page.</param>
/// <param name="pageCount">The page count.</param>
/// <returns></returns>
IQueryable<T> GetAll(int page, int pageCount);

/// <summary>
/// Gets all and offers to include a related table
/// </summary>
Expand Down
8 changes: 8 additions & 0 deletions src/DeviceManager.Api/Data/Management/Repository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.EntityFrameworkCore;

namespace DeviceManager.Api.Data.Management
Expand Down Expand Up @@ -76,6 +77,13 @@ public IQueryable<T> GetAll()
return this.dbSet;
}

public IQueryable<T> GetAll(int page, int pageCount)
{
var pageSize = (page - 1) * pageCount;

return this.dbSet.Skip(pageSize).Take(pageCount);
}

/// <inheritdoc />
public IQueryable<T> GetAll(string include)
{
Expand Down
2 changes: 2 additions & 0 deletions src/DeviceManager.Api/DeviceManager.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="6.2.2" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="2.0.1" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
Expand Down
26 changes: 26 additions & 0 deletions src/DeviceManager.Api/Mappings/MapProfile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using AutoMapper.Configuration;
using DeviceManager.Api.Data.Model;
using DeviceManager.Api.Model;

namespace DeviceManager.Api.Mappings
{
/// <summary>
/// Contains objects mapping
/// </summary>
/// <seealso cref="AutoMapper.Configuration.MapperConfigurationExpression" />
public class MapsProfile : MapperConfigurationExpression
{
/// <summary>
/// Initializes a new instance of the <see cref="MapsProfile"/> class
/// </summary>
public MapsProfile()
{
// Device ViewModel To Device
this.CreateMap<DeviceViewModel, Device>()
.ForMember(dest => dest.DeviceTitle, opt => opt.MapFrom(src => src.Title))
.ForMember(dest => dest.DeviceId, opt => opt.MapFrom(src => Guid.NewGuid()))
;
}
}
}
3 changes: 2 additions & 1 deletion src/DeviceManager.Api/Model/DeviceViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System;
using System.ComponentModel.DataAnnotations;

namespace DeviceManager.Api.Model
{
Expand Down
19 changes: 8 additions & 11 deletions src/DeviceManager.Api/Services/DeviceService.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using DeviceManager.Api.Data.Management;
using DeviceManager.Api.Data.Model;
using DeviceManager.Api.Model;
Expand All @@ -11,20 +12,23 @@ namespace DeviceManager.Api.Services
public class DeviceService : IDeviceService
{
private readonly IUnitOfWork unitOfWork;
private readonly IMapper mapper;

/// <inheritdoc />
public DeviceService(
IUnitOfWork unitOfWork)
IUnitOfWork unitOfWork,
IMapper mapper)
{
this.unitOfWork = unitOfWork;
this.mapper = mapper;
}

/// <inheritdoc />
public List<Device> GetDevices()
public List<Device> GetDevices(int page, int pageSize)
{
var deviceRepository = unitOfWork.GetRepository<Device>();

return deviceRepository.GetAll().ToList();
return deviceRepository.GetAll(page, pageSize).ToList();
}

/// <inheritdoc />
Expand All @@ -46,13 +50,7 @@ public void CreateDevice(DeviceViewModel deviceViewModel)
{
var deviceRepository = unitOfWork.GetRepository<Device>();

// Add new device
deviceRepository.Add(
new Device
{
DeviceId = Guid.NewGuid(),
DeviceTitle = deviceViewModel.Title
});
deviceRepository.Add(mapper.Map<DeviceViewModel, Device>(deviceViewModel));

// Commit changes
unitOfWork.Commit();
Expand All @@ -71,7 +69,6 @@ public void UpdateDevice(Guid deviceId, DeviceViewModel deviceViewModel)
throw new NullReferenceException();
}

// Update device properties
device.DeviceTitle = deviceViewModel.Title;

deviceRepository.Update(device);
Expand Down
4 changes: 3 additions & 1 deletion src/DeviceManager.Api/Services/IDeviceService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ public interface IDeviceService
/// <summary>
/// Gets the list of devices.
/// </summary>
/// <param name="page">The page.</param>
/// <param name="pageSize">Size of the page.</param>
/// <returns></returns>
List<Device> GetDevices();
List<Device> GetDevices(int page, int pageSize);

/// <summary>
/// Gets the device by identifier.
Expand Down
4 changes: 3 additions & 1 deletion src/DeviceManager.Api/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DeviceManager.Api.Configuration;
using AutoMapper;
using DeviceManager.Api.Configuration;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
Expand Down Expand Up @@ -31,6 +32,7 @@ public void ConfigureServices(IServiceCollection services)

// Add framework services.
services.AddMvc();
services.AddAutoMapper();

// Swagger API documentation
SwaggerConfiguration.ConfigureService(services);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AutoMapper" Version="6.2.2" />
<PackageReference Include="FluentAssertions" Version="5.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="Moq" Version="4.7.145" />
Expand Down
125 changes: 125 additions & 0 deletions test/DeviceManager.Api.UnitTests/Services/DeviceServiceBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using AutoMapper;
using DeviceManager.Api.Services;
using DeviceManager.Api.Data.Management;
using DeviceManager.Api.Data.Model;
using DeviceManager.Api.Mappings;
using Microsoft.EntityFrameworkCore;
using Moq;

namespace DeviceManager.Api.UnitTests.Services
{
public class DeviceServiceBuilder
{
private readonly Mock<IRepository<Device>> mockRepository;
private readonly Mock<IUnitOfWork> mockUnitOfWork;
private readonly MapperConfiguration mapperConfiguration;
private readonly Mapper mapper;

public DeviceServiceBuilder()
{
var mockRepositoryObjet = new MockRepository(MockBehavior.Strict);

mockUnitOfWork = mockRepositoryObjet.Create<IUnitOfWork>();
mockRepository = mockRepositoryObjet.Create<IRepository<Device>>();

// Default automapper configuration
mapperConfiguration = new MapperConfiguration(new MapsProfile());
mapper = new Mapper(mapperConfiguration);
}

/// <summary>
/// With the repository methods mock.
/// </summary>
/// <param name="devicesList">The devices list.</param>
/// <param name="device">The device.</param>
/// <returns></returns>
public DeviceServiceBuilder WithRepositoryMock(List<Device> devicesList, Device device)
{
// 'GetAll' repository mock
this.mockRepository.Setup(x => x.GetAll(1, 1)).Returns(devicesList.AsQueryable);

// 'Get' repository mock
this.mockRepository.Setup(x => x.Get(It.IsAny<Guid>())).Returns(device);

// 'Update' repository mock
this.mockRepository.Setup(x => x.Update(It.IsAny<Device>())).Returns(It.IsAny<EntityState>());

// 'Add' repository mock
this.mockRepository.Setup(x => x.Add(It.IsAny<Device>())).Returns(EntityState.Added);

// 'FindBy' repository mock
this.mockRepository.Setup(x => x.FindBy(It.IsAny<Expression<Func<Device, bool>>>()))
.Returns(() =>
devicesList.AsQueryable());

return this;
}

/// <summary>
/// With the repository GetAll mock.
/// </summary>
/// <param name="devicesList">The devices list.</param>
/// <returns></returns>
public DeviceServiceBuilder WithRepositoryGetAllMock(List<Device> devicesList)
{
// 'GetAll' repository mock
this.mockRepository.Setup(x => x.GetAll()).Returns(devicesList.AsQueryable);

return this;
}

/// <summary>
/// With the repository get all mock.
/// </summary>
/// <param name="page">The page.</param>
/// <param name="pageSize">Size of the page.</param>
/// <param name="devicesList">The devices list.</param>
/// <returns></returns>
public DeviceServiceBuilder WithRepositoryGetAllMock(int page, int pageSize, List<Device> devicesList)
{
// 'GetAll' repository mock
this.mockRepository.Setup(x => x.GetAll(page, pageSize)).Returns(devicesList.AsQueryable);

return this;
}

/// <summary>
/// With the repository Get mock.
/// </summary>
/// <param name="device">The device.</param>
/// <returns></returns>
public DeviceServiceBuilder WithRepositoryGetMock(Device device)
{
// 'Get' repository mock
this.mockRepository.Setup(x => x.Get(It.IsAny<Guid>())).Returns(device);

return this;
}

/// <summary>
/// With the unit of work setup.
/// </summary>
/// <returns></returns>
public DeviceServiceBuilder WithUnitOfWorkSetup()
{
this.mockUnitOfWork.Setup(x => x.Commit()).Returns(1);
this.mockUnitOfWork.Setup(u => u.GetRepository<Device>()).Returns(this.mockRepository.Object);
return this;
}

/// <summary>
/// Builds this instance.
/// </summary>
/// <returns></returns>
public DeviceService Build()
{
return new DeviceService(
this.mockUnitOfWork.Object,
mapper);
}
}
}
Loading

0 comments on commit 8af0a4b

Please sign in to comment.