Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/build-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
- '**.csproj'

env:
DOTNET_VERSION: '7.0.203' # The .NET SDK version to use
DOTNET_VERSION: '8.0.405' # The .NET SDK version to use

jobs:
build:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/code-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
- '**.csproj'

env:
DOTNET_VERSION: '7.0.203' # The .NET SDK version to use
DOTNET_VERSION: '8.0.405' # The .NET SDK version to use

jobs:
build:
Expand Down Expand Up @@ -45,7 +45,7 @@ jobs:
dotnet reportgenerator -reports:${{ github.workspace }}/Tests/Coverage.cobertura.xml -targetdir:"${{ github.workspace }}/Tests/coveragereport" -reporttypes:Html

- name: Archive code coverage results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: code-coverage-report
path: ${{ github.workspace }}/Tests/
2 changes: 1 addition & 1 deletion .github/workflows/run-unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
- '**.csproj'

env:
DOTNET_VERSION: '7.0.203' # The .NET SDK version to use
DOTNET_VERSION: '8.0.405' # The .NET SDK version to use

jobs:
build:
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ A market place for services

Wants to demonstrate testing in dotnet.

Based on clean architecture.

[![build](https://github.com/afsharm/ServicePlace/actions/workflows/build-validation.yml/badge.svg)](https://github.com/afsharm/ServicePlace/actions/workflows/build-validation.yml)

## instructions
Expand Down
7 changes: 7 additions & 0 deletions src/ServicePlace.Core/BaseDomainEntity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
public abstract class BaseDomainEntity
{
public BaseDomainEntity()
=> Id = Guid.NewGuid();

public Guid Id { get; set; }
}
7 changes: 7 additions & 0 deletions src/ServicePlace.Core/Commands/CreateProviderCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace ServicePlace.Core.Commands;

public class CreateProviderCommand
{
public Guid? ServiceId { get; set; }
public string? Name { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace ServicePlace.Model.Commands;
namespace ServicePlace.Core.Commands;

public class CreateService
{
Expand Down
7 changes: 7 additions & 0 deletions src/ServicePlace.Core/Commands/UpdateProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace ServicePlace.Core.Commands;

public class UpdateProvider
{
public Guid Id { get; set; }
public string? Name { get; set; }
}
7 changes: 7 additions & 0 deletions src/ServicePlace.Core/Commands/UpdateService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace ServicePlace.Core.Commands;

public class UpdateService
{
public Guid Id { get; set; }
public string? Name { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
using ServicePlace.Model.Queries;
using ServicePlace.Model.Commands;
using ServicePlace.Model;
using ServicePlace.Core.Queries;
using ServicePlace.Core.Commands;
using Microsoft.Extensions.Logging;
using ServicePlace.Model.Results;
using ServicePlace.Model.Constants;
using ServicePlace.Data.Contracts;
using ServicePlace.Service.Contracts;
using ServicePlace.Core.Results;
using ServicePlace.Core.Constants;
using ServicePlace.Core.Contracts;
using ServicePlace.Core.DomainEntities;

namespace ServicePlace.Service;
namespace ServicePlace.Core;

public class CommonService : ICommonService
{
private readonly ILogger<CommonService> _logger;
private readonly IServiceRepository _serviceRepository;
private readonly IProviderRepository _providerRepository;
private readonly IUnitOfWork _unitOfWork;

public CommonService(ILogger<CommonService> logger, IServiceRepository serviceRepository, IProviderRepository providerRepository, IUnitOfWork unitOfWork)
public CommonService(ILogger<CommonService> logger, IServiceRepository serviceRepository, IProviderRepository providerRepository
)
{
_logger = logger;
_serviceRepository = serviceRepository;
_providerRepository = providerRepository;
_unitOfWork = unitOfWork;
}

public async Task<PagingResult<ProviderDisplay>> GetAllProvidersAsync(ProviderPagingQuery query)
Expand All @@ -37,14 +35,13 @@ public async Task<IEnumerable<ServiceDisplay>> GetServicesAsync()
public async Task<CreateServiceResult> CreateServiceAsync(CreateService command)
{
ValidateCreateService(command);
var service = new Model.Entities.Service

var service = new ServiceDomain
{
Name = command.Name
};
await _serviceRepository.AddAsync(service);

//doing save changes is necessary here because we need to return database generated id without exposing Entities to upper layers
await _unitOfWork.SaveChangesAsync();
await _serviceRepository.AddAsync(service);

return new CreateServiceResult
{
Expand All @@ -58,7 +55,7 @@ void ValidateCreateService(CreateService command)
throw new Exception();
}

public async Task<IEnumerable<ProviderDisplay>> GetProviderByServiceIdAsync(int serviceId)
public async Task<IEnumerable<ProviderDisplay>> GetProviderByServiceIdAsync(Guid serviceId)
{
return await _providerRepository.GetProviderByServiceIdAsync(serviceId);
}
Expand Down Expand Up @@ -90,10 +87,9 @@ public async Task<CreateProviderResult> CreateProviderAsync(CreateProviderComman
if (anyDuplicate)
throw new Exception(ErrorMessageConstants.DuplicateServiceName);

var newProvider = new Model.Entities.Provider { Name = command.Name, ServiceId = command.ServiceId.Value };
var newProvider = new ProviderDomain { Name = command.Name, ServiceId = command.ServiceId.Value };

await _providerRepository.AddProviderAsync(newProvider);
await _unitOfWork.SaveChangesAsync();

return new CreateProviderResult { ProviderId = newProvider.Id };
}
Expand All @@ -110,12 +106,12 @@ private void ValidateProviderName(string? name)
throw new ArgumentException(ErrorMessageConstants.ShouldNotBeSmaller, nameof(name));
}

public async Task DeleteServiceAsync(int serviceId)
public async Task DeleteServiceAsync(Guid serviceId)
{
await _serviceRepository.DeleteAsync(serviceId);
}

public async Task<ServiceDisplay?> GetServiceByIdAsync(int serviceId)
public async Task<ServiceDisplay?> GetServiceByIdAsync(Guid serviceId)
{
return await _serviceRepository.GetServiceByIdAsync(serviceId);
}
Expand All @@ -125,12 +121,12 @@ public async Task UpdateServiceAsync(UpdateService command)
await _serviceRepository.UpdateServiceAsync(command);
}

public async Task<ProviderDisplay?> GetProviderByIdAsync(int providerId)
public async Task<ProviderDisplay?> GetProviderByIdAsync(Guid providerId)
{
return await _providerRepository.GetProviderByIdAsync(providerId);
}

public async Task DeleteProviderAsync(int providerId)
public async Task DeleteProviderAsync(Guid providerId)
{
await _providerRepository.DeleteAsync(providerId);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace ServicePlace.Model.Constants;
namespace ServicePlace.Core.Constants;

public class ErrorMessageConstants
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
using ServicePlace.Model.Commands;
using ServicePlace.Model.Queries;
using ServicePlace.Model.Results;
using ServicePlace.Core.Commands;
using ServicePlace.Core.Queries;
using ServicePlace.Core.Results;

namespace ServicePlace.Service.Contracts;
namespace ServicePlace.Core.Contracts;

public interface ICommonService
{
Task<PagingResult<ProviderDisplay>> GetAllProvidersAsync(ProviderPagingQuery query);
Task<IEnumerable<ServiceDisplay>> GetServicesAsync();
Task<CreateServiceResult> CreateServiceAsync(CreateService command);
Task<IEnumerable<ProviderDisplay>> GetProviderByServiceIdAsync(int serviceId);
Task<IEnumerable<ProviderDisplay>> GetProviderByServiceIdAsync(Guid serviceId);
Task UpdateProviderAsync(UpdateProvider command);
Task<CreateProviderResult> CreateProviderAsync(CreateProviderCommand? command);
Task DeleteServiceAsync(int serviceId);
Task<ServiceDisplay?> GetServiceByIdAsync(int serviceId);
Task DeleteServiceAsync(Guid serviceId);
Task<ServiceDisplay?> GetServiceByIdAsync(Guid serviceId);
Task UpdateServiceAsync(UpdateService command);
Task<ProviderDisplay?> GetProviderByIdAsync(int providerId);
Task DeleteProviderAsync(int providerId);
Task<ProviderDisplay?> GetProviderByIdAsync(Guid providerId);
Task DeleteProviderAsync(Guid providerId);
}
17 changes: 17 additions & 0 deletions src/ServicePlace.Core/Contracts/IProviderRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using ServicePlace.Core.DomainEntities;
using ServicePlace.Core.Queries;
using ServicePlace.Core.Results;

namespace ServicePlace.Core.Contracts;

public interface IProviderRepository
{
Task<PagingResult<ProviderDisplay>> GetAllProvidersAsync(ProviderPagingQuery query);
Task<IEnumerable<ProviderDisplay>> GetProviderByServiceIdAsync(Guid serviceId);
Task<ProviderDomain?> GetProviderAsync(Guid id);
void UpdateProvider(ProviderDomain provider);
Task<bool> AnyDuplicateAsync(string? name, Guid? serviceId);
Task AddProviderAsync(ProviderDomain newProvider);
Task<ProviderDisplay?> GetProviderByIdAsync(Guid providerId);
Task DeleteAsync(Guid providerId);
}
14 changes: 14 additions & 0 deletions src/ServicePlace.Core/Contracts/IServiceRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using ServicePlace.Core.Commands;
using ServicePlace.Core.DomainEntities;
using ServicePlace.Core.Queries;

namespace ServicePlace.Core.Contracts;

public interface IServiceRepository
{
Task<IEnumerable<ServiceDisplay>> GetServicesAsync();
Task AddAsync(ServiceDomain service);
Task DeleteAsync(Guid serviceId);
Task<ServiceDisplay?> GetServiceByIdAsync(Guid serviceId);
Task UpdateServiceAsync(UpdateService command);
}
6 changes: 6 additions & 0 deletions src/ServicePlace.Core/DomainEntities/ProviderDomain.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace ServicePlace.Core.DomainEntities;
public class ProviderDomain: BaseDomainEntity
{
public string? Name { get; set; }
public Guid ServiceId { get; set; }
}
5 changes: 5 additions & 0 deletions src/ServicePlace.Core/DomainEntities/ServiceDomain.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace ServicePlace.Core.DomainEntities;
public class ServiceDomain: BaseDomainEntity
{
public string? Name { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace ServicePlace.Model;
namespace ServicePlace.Core;

[System.Serializable]
public class NotFoundException : System.Exception
Expand All @@ -8,4 +8,4 @@
public NotFoundException(string message, System.Exception inner) : base(message, inner) { }
protected NotFoundException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }

Check warning on line 11 in src/ServicePlace.Core/NotFoundException.cs

View workflow job for this annotation

GitHub Actions / build-ubuntu-latest

'Exception.Exception(SerializationInfo, StreamingContext)' is obsolete: 'This API supports obsolete formatter-based serialization. It should not be called or extended by application code.' (https://aka.ms/dotnet-warnings/SYSLIB0051)

Check warning on line 11 in src/ServicePlace.Core/NotFoundException.cs

View workflow job for this annotation

GitHub Actions / build-ubuntu-latest

'Exception.Exception(SerializationInfo, StreamingContext)' is obsolete: 'This API supports obsolete formatter-based serialization. It should not be called or extended by application code.' (https://aka.ms/dotnet-warnings/SYSLIB0051)

Check warning on line 11 in src/ServicePlace.Core/NotFoundException.cs

View workflow job for this annotation

GitHub Actions / build-ubuntu-latest

'Exception.Exception(SerializationInfo, StreamingContext)' is obsolete: 'This API supports obsolete formatter-based serialization. It should not be called or extended by application code.' (https://aka.ms/dotnet-warnings/SYSLIB0051)

Check warning on line 11 in src/ServicePlace.Core/NotFoundException.cs

View workflow job for this annotation

GitHub Actions / build-ubuntu-latest

'Exception.Exception(SerializationInfo, StreamingContext)' is obsolete: 'This API supports obsolete formatter-based serialization. It should not be called or extended by application code.' (https://aka.ms/dotnet-warnings/SYSLIB0051)

Check warning on line 11 in src/ServicePlace.Core/NotFoundException.cs

View workflow job for this annotation

GitHub Actions / build-ubuntu-latest

'Exception.Exception(SerializationInfo, StreamingContext)' is obsolete: 'This API supports obsolete formatter-based serialization. It should not be called or extended by application code.' (https://aka.ms/dotnet-warnings/SYSLIB0051)

Check warning on line 11 in src/ServicePlace.Core/NotFoundException.cs

View workflow job for this annotation

GitHub Actions / build-ubuntu-latest

'Exception.Exception(SerializationInfo, StreamingContext)' is obsolete: 'This API supports obsolete formatter-based serialization. It should not be called or extended by application code.' (https://aka.ms/dotnet-warnings/SYSLIB0051)

Check warning on line 11 in src/ServicePlace.Core/NotFoundException.cs

View workflow job for this annotation

GitHub Actions / build-windows-latest

'Exception.Exception(SerializationInfo, StreamingContext)' is obsolete: 'This API supports obsolete formatter-based serialization. It should not be called or extended by application code.' (https://aka.ms/dotnet-warnings/SYSLIB0051)

Check warning on line 11 in src/ServicePlace.Core/NotFoundException.cs

View workflow job for this annotation

GitHub Actions / build-windows-latest

'Exception.Exception(SerializationInfo, StreamingContext)' is obsolete: 'This API supports obsolete formatter-based serialization. It should not be called or extended by application code.' (https://aka.ms/dotnet-warnings/SYSLIB0051)

Check warning on line 11 in src/ServicePlace.Core/NotFoundException.cs

View workflow job for this annotation

GitHub Actions / build-windows-latest

'Exception.Exception(SerializationInfo, StreamingContext)' is obsolete: 'This API supports obsolete formatter-based serialization. It should not be called or extended by application code.' (https://aka.ms/dotnet-warnings/SYSLIB0051)

Check warning on line 11 in src/ServicePlace.Core/NotFoundException.cs

View workflow job for this annotation

GitHub Actions / build-windows-latest

'Exception.Exception(SerializationInfo, StreamingContext)' is obsolete: 'This API supports obsolete formatter-based serialization. It should not be called or extended by application code.' (https://aka.ms/dotnet-warnings/SYSLIB0051)

Check warning on line 11 in src/ServicePlace.Core/NotFoundException.cs

View workflow job for this annotation

GitHub Actions / build-windows-latest

'Exception.Exception(SerializationInfo, StreamingContext)' is obsolete: 'This API supports obsolete formatter-based serialization. It should not be called or extended by application code.' (https://aka.ms/dotnet-warnings/SYSLIB0051)

Check warning on line 11 in src/ServicePlace.Core/NotFoundException.cs

View workflow job for this annotation

GitHub Actions / build-windows-latest

'Exception.Exception(SerializationInfo, StreamingContext)' is obsolete: 'This API supports obsolete formatter-based serialization. It should not be called or extended by application code.' (https://aka.ms/dotnet-warnings/SYSLIB0051)

Check warning on line 11 in src/ServicePlace.Core/NotFoundException.cs

View workflow job for this annotation

GitHub Actions / build-windows-latest

'Exception.Exception(SerializationInfo, StreamingContext)' is obsolete: 'This API supports obsolete formatter-based serialization. It should not be called or extended by application code.' (https://aka.ms/dotnet-warnings/SYSLIB0051)

Check warning on line 11 in src/ServicePlace.Core/NotFoundException.cs

View workflow job for this annotation

GitHub Actions / build-windows-latest

'Exception.Exception(SerializationInfo, StreamingContext)' is obsolete: 'This API supports obsolete formatter-based serialization. It should not be called or extended by application code.' (https://aka.ms/dotnet-warnings/SYSLIB0051)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace ServicePlace.Model.Queries;
namespace ServicePlace.Core.Queries;


public abstract class PagingQueryBase
Expand Down
10 changes: 10 additions & 0 deletions src/ServicePlace.Core/Queries/ProviderDisplay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

namespace ServicePlace.Core.Queries;

public class ProviderDisplay
{
public Guid Id { get; set; }
public string? Name { get; set; }
public Guid ServiceId { get; set; }
public string? ServiceName { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace ServicePlace.Model.Queries;
namespace ServicePlace.Core.Queries;

public class ProviderPagingQuery : PagingQueryBase
{
Expand Down
8 changes: 8 additions & 0 deletions src/ServicePlace.Core/Queries/ServiceDisplay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

namespace ServicePlace.Core.Queries;

public class ServiceDisplay
{
public Guid Id { get; set; }
public string? Name { get; set; }
}
6 changes: 6 additions & 0 deletions src/ServicePlace.Core/Results/CreateProviderResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace ServicePlace.Core.Results;

public class CreateProviderResult
{
public Guid ProviderId { set; get; }
}
6 changes: 6 additions & 0 deletions src/ServicePlace.Core/Results/CreateServiceResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace ServicePlace.Core.Results;

public class CreateServiceResult
{
public Guid ServiceId { set; get; }
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using ServicePlace.Model.Queries;
using ServicePlace.Core.Queries;

namespace ServicePlace.Model.Results;
namespace ServicePlace.Core.Results;

public class PagingResult<T>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
</ItemGroup>

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
Expand Down
5 changes: 5 additions & 0 deletions src/ServicePlace.Data/BaseEntity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
public abstract class BaseDatabaseEntity
{
public Guid Id { get; set; }
public bool IsDeleted { get; set; }
}
17 changes: 0 additions & 17 deletions src/ServicePlace.Data/Contracts/IProviderRepository.cs

This file was deleted.

14 changes: 0 additions & 14 deletions src/ServicePlace.Data/Contracts/IServiceRepository.cs

This file was deleted.

Loading
Loading