Compare commits

..

No commits in common. "c805ce20a89a634076f8eebf9e0db8bd9fd7753f" and "8611427557b60be10589dc57134b94bfe29573a0" have entirely different histories.

28 changed files with 186 additions and 446 deletions

View File

@ -8,17 +8,11 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AB.API\AB.API.csproj" />
<ProjectReference Include="..\AB.Persistence\AB.Persistence.csproj" />
<ProjectReference Include="..\AB.Services\AB.Services.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,33 @@
using Microsoft.AspNetCore.Mvc;
namespace AB_API.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}

View File

@ -1,12 +1,3 @@
using AB.Domain.Repositories;
using AB.Persistence;
using AB.Persistence.Repos;
using AB.Services;
using AB.Services.Abstractions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
@ -14,17 +5,7 @@ var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers().AddApplicationPart(typeof(AB.API.AssemblyReference).Assembly);
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c => c.SwaggerDoc("v1", new OpenApiInfo { Title = "AB-API", Version = "v1" , Description = "An Api for the AB-Application"}));
builder.Services.AddScoped<ICustomerService, CustomerService>();
builder.Services.AddScoped<ICustomerRepository, CustomerRepository>();
builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();
builder.Services.AddDbContextPool<RepoDbContext>(builder =>
{
builder.UseInMemoryDatabase("test");
});
builder.Services.AddSwaggerGen();
var app = builder.Build();

13
AB-API/WeatherForecast.cs Normal file
View File

@ -0,0 +1,13 @@
namespace AB_API
{
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
}

View File

@ -1,51 +0,0 @@
using AB.Contracts;
using AB.Services.Abstractions;
using Microsoft.AspNetCore.Mvc;
namespace AB.API.Controllers.BusinessPartner;
[ApiController]
[Route("api/customers")]
public class CustomerController : ControllerBase
{
private readonly ICustomerService _customerService;
public CustomerController(ICustomerService customerService)
{
_customerService = customerService;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<CustomerDto>>> GetCustomers(CancellationToken cancellationToken)
{
var customers = await _customerService.GetAllAsync(cancellationToken);
return Ok(customers);
}
[HttpGet("{customerId:guid}")]
public async Task<ActionResult<CustomerDto>> GetCustomerById(Guid customerId, CancellationToken cancellationToken)
{
var customer = await _customerService.GetByIdAsync(customerId, cancellationToken);
return Ok(customer);
}
[HttpPost]
public async Task<CreatedAtActionResult> CreateCustomer([FromBody] CustomerForCreationDto customerForCreation)
{
var customerDto = await _customerService.CreateAsync(customerForCreation);
return CreatedAtAction(nameof(CreateCustomer), new { customerId = customerDto.Id }, customerDto);
}
[HttpDelete("{customerId:guid}")]
public async Task<NoContentResult> DeleteCustomer(Guid customerId, CancellationToken cancellationToken)
{
await _customerService.DeleteAsync(customerId, cancellationToken);
return NoContent();
}
}

View File

@ -1,48 +0,0 @@
using AB.Contracts;
using AB.Services.Abstractions;
using Microsoft.AspNetCore.Mvc;
namespace AB.API.Controllers.BusinessPartner;
[ApiController]
[Route("api/suppliers")]
public class SupplierController : ControllerBase
{
public readonly ISupplierService _supplierService;
[HttpGet]
public async Task<ActionResult<IEnumerable<SupplierDto>>> GetSupplieres(CancellationToken cancellationToken)
{
var suppliers = await _supplierService.GetAllAsync(cancellationToken);
return Ok(suppliers);
}
[HttpGet("{supplierId:guid}")]
public async Task<ActionResult<SupplierDto>> GetSupplierById(Guid supplierId, CancellationToken cancellationToken)
{
var supplierDto = await _supplierService.GetSupplierByIdAsync(supplierId, cancellationToken);
return Ok(supplierDto);
}
[HttpPost]
public async Task<CreatedAtActionResult> CreateSupplier([FromBody] SupplierForCreationDto supplierForCreation)
{
var supplierDto = await _supplierService.CreateAsync(supplierForCreation);
return CreatedAtAction(nameof(CreateSupplier), new { id = supplierDto.Id }, supplierDto);
}
[HttpDelete("{supplierId:guid}")]
public async Task<NoContentResult> DeleteSupplier(Guid supplierId, CancellationToken cancellationToken)
{
await _supplierService.DeleteAsync(supplierId, cancellationToken);
return NoContent();
}
}

View File

@ -0,0 +1,53 @@
using AB.Contracts;
using AB.Services.Abstractions;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AB.API.Controllers
{
[ApiController]
[Route("api/customers")]
public class CustomerController : ControllerBase
{
private readonly ICustomerService _customerService;
[HttpGet]
public async Task<IActionResult> GetCustomers(CancellationToken cancellationToken)
{
var customers = await _customerService.GetAllAsync(cancellationToken);
return Ok(customers);
}
[HttpGet("{customerId:guid}")]
public async Task<IActionResult> GetCustomerById(Guid customerId, CancellationToken cancellationToken)
{
var customer = await _customerService.GetByIdAsync(customerId, cancellationToken);
return Ok(customer);
}
[HttpPost]
public async Task<IActionResult> CreateCustomer([FromBody] CustomerForCreationDto customerForCreation)
{
var customerDto = await _customerService.CreateAsync(customerForCreation);
return CreatedAtAction(nameof(CreateCustomer), new {customerId = customerDto.Id}, customerDto);
}
[HttpDelete("{customerId:guid}")]
public async Task<IActionResult> DeleteCustomer(Guid customerId, CancellationToken cancellationToken)
{
await _customerService.DeleteAsync(customerId, cancellationToken);
return NoContent();
}
}
}

View File

@ -1,20 +1,15 @@
namespace AB.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public class CustomerDto
namespace AB.Contracts
{
public class CustomerDto
{
public Guid Id { get; set; }
public string Salutaion { get; set; }
public string Name1 { get; set; }
public string Name2 { get; set; }
public string Email { get; set; }
public string Iban { get; set; }
public string PhoneNumber { get; set; }
}
}

View File

@ -1,27 +1,12 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AB.Contracts;
public class CustomerForCreationDto
namespace AB.Contracts
{
[Required]
public string Salutaion { get; set; }
[Required]
public string Name1 { get; set; }
public string? Name2 { get; set; }
public string? Email { get; set; }
public string? Iban { get; set; }
public string? PhoneNumber { get; set; }
public class CustomerForCreationDto
{
}
}

View File

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AB.Contracts;
public class SupplierDto
{
public Guid Id { get; set; }
}

View File

@ -4,8 +4,9 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AB.Contracts;
public class SupplierForCreationDto
namespace AB.Contracts
{
public class SupplierForCreationDto
{
}
}

View File

@ -4,23 +4,11 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AB.Domain.Entities;
public class Customer
namespace AB.Domain.Entities
{
public class Customer
{
Guid coutomerId;
public Guid CustomerId { get; set; }
public string Salutation { get; set; }
public string Name1 { get; set; }
public string Name2 { get; set; }
public string Email { get; set; }
public string Iban { get; set; }
public string PhoneNumber { get; set; }
}
}

View File

@ -4,10 +4,11 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AB.Domain.Entities;
public class Product
namespace AB.Domain.Entities
{
public Guid ProductId { get; set; }
public class Product
{
Guid productId;
}
}

View File

@ -4,10 +4,11 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AB.Domain.Entities;
public class Supplier
namespace AB.Domain.Entities
{
public class Supplier
{
public Guid SupplierId { get; set; }
Guid supplierId;
}
}

View File

@ -4,13 +4,14 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AB.Domain.Exceptions;
public class BusinessPartnerNotFoundException : NotFoundException
namespace AB.Domain.Exceptions
{
public class BusinessPartnerNotFoundException : NotFoundException
{
public BusinessPartnerNotFoundException(Guid businessPartnerId)
: base ($"The BusinessPartner with the indetifier {businessPartnerId} was not found.")
{ }
}
}

View File

@ -4,16 +4,17 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AB.Domain.Exceptions;
[Serializable]
public abstract class NotFoundException : Exception
namespace AB.Domain.Exceptions
{
[Serializable]
public abstract class NotFoundException : Exception
{
public NotFoundException() { }
public NotFoundException(string message) : base(message) { }
public NotFoundException(string message, Exception inner) : base(message, inner) { }
protected NotFoundException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
}

View File

@ -1,16 +1,12 @@
using AB.Domain.Entities;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AB.Domain.Repositories;
public interface ICustomerRepository
namespace AB.Domain.Repositories
{
public Task<IEnumerable<Customer>> GetAllAsync(CancellationToken cancellationToken);
Task<Customer> GetByIdAsync(Guid customerId, CancellationToken cancellationToken);
void Insert(Customer customer);
void Remove(Customer customer);
public class ICustomerRepository
{
}
}

View File

@ -4,8 +4,9 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AB.Domain.Repositories;
public class ISupplierRepository
namespace AB.Domain.Repositories
{
public class ISupplierRepository
{
}
}

View File

@ -1,6 +1,12 @@
namespace AB.Domain.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public interface IUnitOfWork
namespace AB.Domain.Repositories
{
public Task<int> SaveChangesAsync(CancellationToken cancellationToken);
public class IUnitOfWork
{
}
}

View File

@ -6,12 +6,4 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.5" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AB.Domain\AB.Domain.csproj" />
</ItemGroup>
</Project>

View File

@ -1,25 +0,0 @@
using AB.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AB.Persistence;
public sealed class RepoDbContext : DbContext
{
public RepoDbContext(DbContextOptions options)
: base (options)
{
}
public DbSet<Customer> Customers { get; set; }
public DbSet<Supplier> Suppliers { get; set; }
public DbSet<Product> Products { get; set; }
}

View File

@ -1,36 +0,0 @@
using AB.Domain.Entities;
using AB.Domain.Repositories;
using Microsoft.EntityFrameworkCore;
namespace AB.Persistence.Repos;
public class CustomerRepository : ICustomerRepository
{
private readonly RepoDbContext _dbContext;
public CustomerRepository(RepoDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task<IEnumerable<Customer>> GetAllAsync(CancellationToken cancellationToken)
{
return await _dbContext.Customers.ToListAsync(cancellationToken);
}
public async Task<Customer> GetByIdAsync(Guid customerId, CancellationToken cancellationToken)
{
return await _dbContext.Customers.FirstOrDefaultAsync(x => x.CustomerId == customerId, cancellationToken);
}
public void Insert(Customer customer)
{
_dbContext.Customers.Add(customer);
}
public void Remove(Customer customer)
{
_dbContext.Customers.Remove(customer);
}
}

View File

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AB.Persistence.Repos;
public class SupplierRepository
{
}

View File

@ -1,19 +0,0 @@
using AB.Domain.Repositories;
namespace AB.Persistence.Repos;
public class UnitOfWork : IUnitOfWork
{
private readonly RepoDbContext _dbContext;
public UnitOfWork(RepoDbContext dbContext)
{
_dbContext = dbContext;
}
public Task<int> SaveChangesAsync(CancellationToken cancellationToken)
{
return _dbContext.SaveChangesAsync(cancellationToken);
}
}

View File

@ -5,12 +5,13 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AB.Services.Abstractions;
public interface ICustomerService
namespace AB.Services.Abstractions
{
Task<CustomerDto> CreateAsync(CustomerForCreationDto customerForCreation, CancellationToken cancellationToken = default);
public interface ICustomerService
{
Task<CustomerDto> CreateAsync(CustomerForCreationDto customerForCreation);
Task DeleteAsync(Guid customerId, CancellationToken cancellationToken);
Task<IEnumerable<CustomerDto>> GetAllAsync(CancellationToken cancellationToken);
Task<CustomerDto> GetByIdAsync(Guid customerId, CancellationToken cancellationToken);
}
}

View File

@ -1,11 +0,0 @@
using AB.Contracts;
namespace AB.Services.Abstractions;
public interface ISupplierService
{
Task<SupplierDto> CreateAsync(SupplierForCreationDto supplierForCreation);
Task DeleteAsync(Guid supplierId, CancellationToken cancellationToken);
Task<IEnumerable<SupplierDto>> GetAllAsync(CancellationToken cancellationToken);
Task<SupplierDto> GetSupplierByIdAsync(Guid supplierId, CancellationToken cancellationToken);
}

View File

@ -7,7 +7,6 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\AB.Domain\AB.Domain.csproj" />
<ProjectReference Include="..\AB.Services.Abstractions\AB.Services.Abstractions.csproj" />
</ItemGroup>

View File

@ -1,99 +1,15 @@
using AB.Contracts;
using AB.Domain.Entities;
using AB.Domain.Exceptions;
using AB.Domain.Repositories;
using AB.Services.Abstractions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AB.Services;
public class CustomerService : ICustomerService
namespace AB.Services
{
private readonly ICustomerRepository _customerRepository;
private readonly IUnitOfWork _unitOfWork;
public CustomerService(ICustomerRepository customerRepository, IUnitOfWork unitOfWork)
{
_customerRepository = customerRepository;
_unitOfWork = unitOfWork;
}
public async Task<CustomerDto> CreateAsync(CustomerForCreationDto customerForCreation, CancellationToken cancellationToken = default)
internal class CustomerService : ICustomerService
{
var customer = new Customer
{
Salutation = customerForCreation.Salutaion,
Name1 = customerForCreation.Name1,
Name2 = (customerForCreation.Name2 is null) ? string.Empty : customerForCreation.Name2,
Email = (customerForCreation.Email is null) ? string.Empty : customerForCreation.Email,
PhoneNumber = (customerForCreation.PhoneNumber is null) ? string.Empty : customerForCreation.PhoneNumber,
Iban = (customerForCreation.Iban is null) ? string.Empty : customerForCreation.Iban,
};
_customerRepository.Insert(customer);
await _unitOfWork.SaveChangesAsync(cancellationToken);
var customerDto = ConvertToCustomerDto(customer);
return customerDto;
}
public async Task DeleteAsync(Guid customerId, CancellationToken cancellationToken)
{
var customer = await _customerRepository.GetByIdAsync(customerId, cancellationToken);
if (customer == null)
{
throw new BusinessPartnerNotFoundException(customerId);
}
_customerRepository.Remove(customer);
await _unitOfWork.SaveChangesAsync(cancellationToken);
}
public async Task<IEnumerable<CustomerDto>> GetAllAsync(CancellationToken cancellationToken)
{
var customers = await _customerRepository.GetAllAsync(cancellationToken);
var customerDtoList = customers.Select(customer =>
{
return ConvertToCustomerDto(customer);
});
return customerDtoList;
}
public async Task<CustomerDto> GetByIdAsync(Guid customerId, CancellationToken cancellationToken)
{
var customer = await _customerRepository.GetByIdAsync(customerId, cancellationToken);
if (customer is null)
{
throw new BusinessPartnerNotFoundException(customerId);
}
var customerDto = ConvertToCustomerDto(customer);
return customerDto;
}
private static CustomerDto ConvertToCustomerDto(Customer customer)
{
var customerDto = new CustomerDto
{
Id = customer.CustomerId,
Salutaion = customer.Salutation,
Name1 = customer.Name1,
Name2 = customer.Name2,
Email = customer.Email,
PhoneNumber = customer.PhoneNumber,
Iban = customer.Iban,
};
return customerDto;
}
}