From d7201c116aa487cd57d3441648b7b706968697fc Mon Sep 17 00:00:00 2001 From: boriszn Date: Fri, 16 Feb 2018 21:29:13 +0100 Subject: [PATCH 1/4] Add AutoMapper infrastructure (Main Library + DI extension); Update logic/servcie; add auto mapper interface injections, MapProfile etc. --- .../Data/Management/ContextFactory.cs | 5 ++++ .../DeviceManager.Api.csproj | 2 ++ src/DeviceManager.Api/Mappings/MapProfile.cs | 26 +++++++++++++++++++ .../Model/DeviceViewModel.cs | 3 ++- .../Services/DeviceService.cs | 15 +++++------ src/DeviceManager.Api/Startup.cs | 4 ++- .../DeviceManager.Api.UnitTests.csproj | 1 + 7 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 src/DeviceManager.Api/Mappings/MapProfile.cs diff --git a/src/DeviceManager.Api/Data/Management/ContextFactory.cs b/src/DeviceManager.Api/Data/Management/ContextFactory.cs index f6ac76f..20bbd72 100644 --- a/src/DeviceManager.Api/Data/Management/ContextFactory.cs +++ b/src/DeviceManager.Api/Data/Management/ContextFactory.cs @@ -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)); + } } } } diff --git a/src/DeviceManager.Api/DeviceManager.Api.csproj b/src/DeviceManager.Api/DeviceManager.Api.csproj index f138385..32cda0b 100644 --- a/src/DeviceManager.Api/DeviceManager.Api.csproj +++ b/src/DeviceManager.Api/DeviceManager.Api.csproj @@ -10,6 +10,8 @@ + + diff --git a/src/DeviceManager.Api/Mappings/MapProfile.cs b/src/DeviceManager.Api/Mappings/MapProfile.cs new file mode 100644 index 0000000..79ec739 --- /dev/null +++ b/src/DeviceManager.Api/Mappings/MapProfile.cs @@ -0,0 +1,26 @@ +using System; +using AutoMapper.Configuration; +using DeviceManager.Api.Data.Model; +using DeviceManager.Api.Model; + +namespace DeviceManager.Api.Mappings +{ + /// + /// Contains objects mapping + /// + /// + public class MappingProfile : MapperConfigurationExpression + { + /// + /// Initializes a new instance of the class + /// + public MappingProfile() + { + // Device ViewModel To Device + this.CreateMap() + .ForMember(dest => dest.DeviceTitle, opt => opt.MapFrom(src => src.Title)) + .ForMember(dest => dest.DeviceId, opt => opt.MapFrom(src => Guid.NewGuid())) + ; + } + } +} diff --git a/src/DeviceManager.Api/Model/DeviceViewModel.cs b/src/DeviceManager.Api/Model/DeviceViewModel.cs index 2f37618..05eb3e4 100644 --- a/src/DeviceManager.Api/Model/DeviceViewModel.cs +++ b/src/DeviceManager.Api/Model/DeviceViewModel.cs @@ -1,4 +1,5 @@ -using System.ComponentModel.DataAnnotations; +using System; +using System.ComponentModel.DataAnnotations; namespace DeviceManager.Api.Model { diff --git a/src/DeviceManager.Api/Services/DeviceService.cs b/src/DeviceManager.Api/Services/DeviceService.cs index ea19b96..056dcea 100644 --- a/src/DeviceManager.Api/Services/DeviceService.cs +++ b/src/DeviceManager.Api/Services/DeviceService.cs @@ -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; @@ -11,12 +12,15 @@ namespace DeviceManager.Api.Services public class DeviceService : IDeviceService { private readonly IUnitOfWork unitOfWork; + private readonly IMapper mapper; /// public DeviceService( - IUnitOfWork unitOfWork) + IUnitOfWork unitOfWork, + IMapper mapper) { this.unitOfWork = unitOfWork; + this.mapper = mapper; } /// @@ -46,13 +50,7 @@ public void CreateDevice(DeviceViewModel deviceViewModel) { var deviceRepository = unitOfWork.GetRepository(); - // Add new device - deviceRepository.Add( - new Device - { - DeviceId = Guid.NewGuid(), - DeviceTitle = deviceViewModel.Title - }); + deviceRepository.Add(mapper.Map(deviceViewModel)); // Commit changes unitOfWork.Commit(); @@ -71,7 +69,6 @@ public void UpdateDevice(Guid deviceId, DeviceViewModel deviceViewModel) throw new NullReferenceException(); } - // Update device properties device.DeviceTitle = deviceViewModel.Title; deviceRepository.Update(device); diff --git a/src/DeviceManager.Api/Startup.cs b/src/DeviceManager.Api/Startup.cs index 58d6171..7deef03 100644 --- a/src/DeviceManager.Api/Startup.cs +++ b/src/DeviceManager.Api/Startup.cs @@ -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; @@ -31,6 +32,7 @@ public void ConfigureServices(IServiceCollection services) // Add framework services. services.AddMvc(); + services.AddAutoMapper(); // Swagger API documentation SwaggerConfiguration.ConfigureService(services); diff --git a/test/DeviceManager.Api.UnitTests/DeviceManager.Api.UnitTests.csproj b/test/DeviceManager.Api.UnitTests/DeviceManager.Api.UnitTests.csproj index eb3108e..6dc5fea 100644 --- a/test/DeviceManager.Api.UnitTests/DeviceManager.Api.UnitTests.csproj +++ b/test/DeviceManager.Api.UnitTests/DeviceManager.Api.UnitTests.csproj @@ -5,6 +5,7 @@ + From e4e7a4af5ddebf58347ea5955115f60fc43a9286 Mon Sep 17 00:00:00 2001 From: boriszn Date: Sun, 18 Feb 2018 19:21:46 +0100 Subject: [PATCH 2/4] Add Automapper + infrastructure; Update / refactor unit tests; Add paging logic --- .../Controllers/DevicesController.cs | 6 +- .../Data/Management/IRepository.cs | 8 ++ .../Data/Management/Repository.cs | 8 ++ src/DeviceManager.Api/Mappings/MapProfile.cs | 6 +- .../Services/DeviceService.cs | 4 +- .../Services/IDeviceService.cs | 4 +- .../{Utils => Builders}/DeviceBuilder.cs | 0 .../DeviceViewModelBuilder.cs | 0 .../Services/DeviceServiceBuilder.cs | 125 ++++++++++++++++++ .../Services/DeviceServiceTests.cs | 53 ++------ 10 files changed, 167 insertions(+), 47 deletions(-) rename test/DeviceManager.Api.UnitTests/{Utils => Builders}/DeviceBuilder.cs (100%) rename test/DeviceManager.Api.UnitTests/{Utils => Builders}/DeviceViewModelBuilder.cs (100%) create mode 100644 test/DeviceManager.Api.UnitTests/Services/DeviceServiceBuilder.cs diff --git a/src/DeviceManager.Api/Controllers/DevicesController.cs b/src/DeviceManager.Api/Controllers/DevicesController.cs index cfe91e2..42ba26b 100644 --- a/src/DeviceManager.Api/Controllers/DevicesController.cs +++ b/src/DeviceManager.Api/Controllers/DevicesController.cs @@ -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)); } /// @@ -78,6 +78,8 @@ public IActionResult GetDeviceByTitle(string deviceTitle) /// [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) diff --git a/src/DeviceManager.Api/Data/Management/IRepository.cs b/src/DeviceManager.Api/Data/Management/IRepository.cs index 4be0972..05f3921 100644 --- a/src/DeviceManager.Api/Data/Management/IRepository.cs +++ b/src/DeviceManager.Api/Data/Management/IRepository.cs @@ -56,6 +56,14 @@ public interface IRepository /// List of entities IQueryable GetAll(); + /// + /// Gets all. With data pagination. + /// + /// The page. + /// The page count. + /// + IQueryable GetAll(int page, int pageCount); + /// /// Gets all and offers to include a related table /// diff --git a/src/DeviceManager.Api/Data/Management/Repository.cs b/src/DeviceManager.Api/Data/Management/Repository.cs index 90d8821..379c562 100644 --- a/src/DeviceManager.Api/Data/Management/Repository.cs +++ b/src/DeviceManager.Api/Data/Management/Repository.cs @@ -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 @@ -76,6 +77,13 @@ public IQueryable GetAll() return this.dbSet; } + public IQueryable GetAll(int page, int pageCount) + { + var pageSize = (page - 1) * pageCount; + + return this.dbSet.Skip(pageSize).Take(pageCount); + } + /// public IQueryable GetAll(string include) { diff --git a/src/DeviceManager.Api/Mappings/MapProfile.cs b/src/DeviceManager.Api/Mappings/MapProfile.cs index 79ec739..a729efb 100644 --- a/src/DeviceManager.Api/Mappings/MapProfile.cs +++ b/src/DeviceManager.Api/Mappings/MapProfile.cs @@ -9,12 +9,12 @@ namespace DeviceManager.Api.Mappings /// Contains objects mapping /// /// - public class MappingProfile : MapperConfigurationExpression + public class MapsProfile : MapperConfigurationExpression { /// - /// Initializes a new instance of the class + /// Initializes a new instance of the class /// - public MappingProfile() + public MapsProfile() { // Device ViewModel To Device this.CreateMap() diff --git a/src/DeviceManager.Api/Services/DeviceService.cs b/src/DeviceManager.Api/Services/DeviceService.cs index 056dcea..9849926 100644 --- a/src/DeviceManager.Api/Services/DeviceService.cs +++ b/src/DeviceManager.Api/Services/DeviceService.cs @@ -24,11 +24,11 @@ public DeviceService( } /// - public List GetDevices() + public List GetDevices(int page, int pageSize) { var deviceRepository = unitOfWork.GetRepository(); - return deviceRepository.GetAll().ToList(); + return deviceRepository.GetAll(page, pageSize).ToList(); } /// diff --git a/src/DeviceManager.Api/Services/IDeviceService.cs b/src/DeviceManager.Api/Services/IDeviceService.cs index a7b7754..2bdb51c 100644 --- a/src/DeviceManager.Api/Services/IDeviceService.cs +++ b/src/DeviceManager.Api/Services/IDeviceService.cs @@ -13,8 +13,10 @@ public interface IDeviceService /// /// Gets the list of devices. /// + /// The page. + /// Size of the page. /// - List GetDevices(); + List GetDevices(int page, int pageSize); /// /// Gets the device by identifier. diff --git a/test/DeviceManager.Api.UnitTests/Utils/DeviceBuilder.cs b/test/DeviceManager.Api.UnitTests/Builders/DeviceBuilder.cs similarity index 100% rename from test/DeviceManager.Api.UnitTests/Utils/DeviceBuilder.cs rename to test/DeviceManager.Api.UnitTests/Builders/DeviceBuilder.cs diff --git a/test/DeviceManager.Api.UnitTests/Utils/DeviceViewModelBuilder.cs b/test/DeviceManager.Api.UnitTests/Builders/DeviceViewModelBuilder.cs similarity index 100% rename from test/DeviceManager.Api.UnitTests/Utils/DeviceViewModelBuilder.cs rename to test/DeviceManager.Api.UnitTests/Builders/DeviceViewModelBuilder.cs diff --git a/test/DeviceManager.Api.UnitTests/Services/DeviceServiceBuilder.cs b/test/DeviceManager.Api.UnitTests/Services/DeviceServiceBuilder.cs new file mode 100644 index 0000000..844f0f9 --- /dev/null +++ b/test/DeviceManager.Api.UnitTests/Services/DeviceServiceBuilder.cs @@ -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> mockRepository; + private readonly Mock mockUnitOfWork; + private readonly MapperConfiguration mapperConfiguration; + private readonly Mapper mapper; + + public DeviceServiceBuilder() + { + var mockRepositoryObjet = new MockRepository(MockBehavior.Strict); + + mockUnitOfWork = mockRepositoryObjet.Create(); + mockRepository = mockRepositoryObjet.Create>(); + + // Default automapper configuration + mapperConfiguration = new MapperConfiguration(new MapsProfile()); + mapper = new Mapper(mapperConfiguration); + } + + /// + /// With the repository methods mock. + /// + /// The devices list. + /// The device. + /// + public DeviceServiceBuilder WithRepositoryMock(List 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())).Returns(device); + + // 'Update' repository mock + this.mockRepository.Setup(x => x.Update(It.IsAny())).Returns(It.IsAny()); + + // 'Add' repository mock + this.mockRepository.Setup(x => x.Add(It.IsAny())).Returns(EntityState.Added); + + // 'FindBy' repository mock + this.mockRepository.Setup(x => x.FindBy(It.IsAny>>())) + .Returns(() => + devicesList.AsQueryable()); + + return this; + } + + /// + /// With the repository GetAll mock. + /// + /// The devices list. + /// + public DeviceServiceBuilder WithRepositoryGetAllMock(List devicesList) + { + // 'GetAll' repository mock + this.mockRepository.Setup(x => x.GetAll()).Returns(devicesList.AsQueryable); + + return this; + } + + /// + /// With the repository get all mock. + /// + /// The page. + /// Size of the page. + /// The devices list. + /// + public DeviceServiceBuilder WithRepositoryGetAllMock(int page, int pageSize, List devicesList) + { + // 'GetAll' repository mock + this.mockRepository.Setup(x => x.GetAll(page, pageSize)).Returns(devicesList.AsQueryable); + + return this; + } + + /// + /// With the repository Get mock. + /// + /// The device. + /// + public DeviceServiceBuilder WithRepositoryGetMock(Device device) + { + // 'Get' repository mock + this.mockRepository.Setup(x => x.Get(It.IsAny())).Returns(device); + + return this; + } + + /// + /// With the unit of work setup. + /// + /// + public DeviceServiceBuilder WithUnitOfWorkSetup() + { + this.mockUnitOfWork.Setup(x => x.Commit()).Returns(1); + this.mockUnitOfWork.Setup(u => u.GetRepository()).Returns(this.mockRepository.Object); + return this; + } + + /// + /// Builds this instance. + /// + /// + public DeviceService Build() + { + return new DeviceService( + this.mockUnitOfWork.Object, + mapper); + } + } +} \ No newline at end of file diff --git a/test/DeviceManager.Api.UnitTests/Services/DeviceServiceTests.cs b/test/DeviceManager.Api.UnitTests/Services/DeviceServiceTests.cs index 81b0040..26d36aa 100644 --- a/test/DeviceManager.Api.UnitTests/Services/DeviceServiceTests.cs +++ b/test/DeviceManager.Api.UnitTests/Services/DeviceServiceTests.cs @@ -1,34 +1,34 @@ -using DeviceManager.Api.Data.Management; using DeviceManager.Api.Data.Model; using DeviceManager.Api.Services; -using System.Linq; -using Moq; using System; using System.Collections.Generic; -using System.Linq.Expressions; using DeviceManager.Api.Model; using DeviceManager.Api.UnitTests.Utils; using FluentAssertions; -using Microsoft.EntityFrameworkCore; using Xunit; namespace DeviceManager.Api.UnitTests.Services { public class DeviceServiceTests : IDisposable { - private readonly Mock> mockRepository; - private readonly Mock mockUnitOfWork; - private readonly DeviceService service; public DeviceServiceTests() { - var mockRepositoryObjet = new MockRepository(MockBehavior.Strict); + // Build Device + Device device = new DeviceBuilder() + .WithId("27be25a2-1b69-4476-a90f-f80498f5e2ec") + .WithTitle("Raspberry3") + .Build(); - mockUnitOfWork = mockRepositoryObjet.Create(); - mockRepository = mockRepositoryObjet.Create>(); + // Build Device list + List devicesList = new List{ device }; - service = this.CreateService(); + // Build device service + service = new DeviceServiceBuilder() + .WithRepositoryMock(devicesList, device) + .WithUnitOfWorkSetup() + .Build(); } public void Dispose() @@ -60,7 +60,7 @@ public void GetDevices_WithValidParameters_SholdNotTrowAnyExceptions() // Arrange // Act - Action comparison = () => { service.GetDevices(); }; + Action comparison = () => { service.GetDevices(1,1); }; // Assert comparison.Should().NotThrow(); @@ -72,14 +72,13 @@ public void GetDevices_WithValidParameters_ShouldHaveOneElement() // Arrange // Act - List devices = service.GetDevices(); + List devices = service.GetDevices(1,1); // Assert devices.Should().NotBeNull(); devices.Should().HaveCount(1); } - [Fact] public void GetDeviceById_WithValidParameters_SholdNotBeNull() { @@ -118,29 +117,5 @@ public void UpdateDevice_WithValidParameters_SholdNotThrowAnyExceptions() // Assert action.Should().NotThrow(); } - - private DeviceService CreateService() - { - var device = new DeviceBuilder() - .WithId("27be25a2-1b69-4476-a90f-f80498f5e2ec") - .WithTitle("Raspberry3") - .Build(); - - var devicesList = new List{ device }; - - this.mockRepository.Setup(x => x.GetAll()).Returns(devicesList.AsQueryable); - this.mockRepository.Setup(x => x.Get(It.IsAny())).Returns(device); - this.mockRepository.Setup(x => x.Update(It.IsAny())).Returns(It.IsAny()); - this.mockRepository.Setup(x => x.Add(It.IsAny())).Returns(EntityState.Added); - - this.mockRepository.Setup(x => x.FindBy(It.IsAny>>())) - .Returns(() => devicesList.AsQueryable()); - - this.mockUnitOfWork.Setup(x => x.Commit()).Returns(1); - this.mockUnitOfWork.Setup(u => u.GetRepository()).Returns(this.mockRepository.Object); - - return new DeviceService( - this.mockUnitOfWork.Object); - } } } From 7dcc9451b2ee856d0cc8391cf2f28a25cdd629a6 Mon Sep 17 00:00:00 2001 From: boriszn Date: Sun, 18 Feb 2018 19:35:12 +0100 Subject: [PATCH 3/4] add architecure diagram --- assets/arhitecture-diag.png | Bin 0 -> 34986 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/arhitecture-diag.png diff --git a/assets/arhitecture-diag.png b/assets/arhitecture-diag.png new file mode 100644 index 0000000000000000000000000000000000000000..eab1ec15b07c05b118ba57a678d442d46a1fa7e8 GIT binary patch literal 34986 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 Date: Sun, 18 Feb 2018 19:41:46 +0100 Subject: [PATCH 4/4] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index c0fd607..259426e 100644 --- a/README.md +++ b/README.md @@ -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