Merge branch 'dev'

This commit is contained in:
Alejandro Sarmiento
2024-03-10 11:15:01 +01:00
29 changed files with 417 additions and 55 deletions

View File

@@ -1,6 +1,11 @@
using CleanArchitecture.Application.Features.Streamers.Commands.CreateStreamer;
using CleanArchitecture.Application.Features.Streamers.Commands.DeleteStreamer;
using CleanArchitecture.Application.Features.Streamers.Commands.UpdateStreamer;
using CleanArchitecture.Application.Features.Streamers.Queries.DTOs;
using CleanArchitecture.Application.Features.Streamers.Queries.GetStreamersListByName;
using CleanArchitecture.Application.Features.Streamers.Queries.GetStreamersListByUserName;
using CleanArchitecture.Application.Features.Videos.Queries.DTOs;
using CleanArchitecture.Application.Features.Videos.Queries.GetVideosList;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
@@ -19,6 +24,27 @@ namespace CleanArchitecture.API.Controllers
mediator = _mediator;
}
[HttpGet("ByName/{name}", Name = "GetStreamersByName")]
[Authorize]
[ProducesResponseType(typeof(IEnumerable<StreamerBaseVm>), (int)HttpStatusCode.OK)]
public async Task<ActionResult<IEnumerable<StreamerBaseVm>>> GetStreamersByName(string name)
{
var query = new GetStreamerListByNameQuery(name);
var streamers = await mediator.Send(query);
return Ok(streamers);
}
[HttpGet("ByUserName/{username}", Name = "GetStreamersByUserName")]
[Authorize]
[ProducesResponseType(typeof(IEnumerable<StreamerBaseVm>), (int)HttpStatusCode.OK)]
public async Task<ActionResult<IEnumerable<StreamerBaseVm>>> GetStreamersByUserName(string username)
{
var query = new GetStreamerByUserNameListQuery(username);
var streamers = await mediator.Send(query);
return Ok(streamers);
}
[HttpPost(Name = "CreateStreamer")]
[Authorize(Roles = "Administrator")]
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]

View File

@@ -4,6 +4,7 @@ using CleanArchitecture.Application.Features.Streamers.Commands.UpdateStreamer;
using CleanArchitecture.Application.Features.Videos.Commands.CreateVideo;
using CleanArchitecture.Application.Features.Videos.Commands.DeleteVideo;
using CleanArchitecture.Application.Features.Videos.Commands.UpdateVideo;
using CleanArchitecture.Application.Features.Videos.Queries.DTOs;
using CleanArchitecture.Application.Features.Videos.Queries.GetVideosList;
using CleanArchitecture.Domain;
using MediatR;
@@ -30,7 +31,7 @@ namespace CleanArchitecture.API.Controllers
[ProducesResponseType(typeof(IEnumerable<VideosVm>), (int)HttpStatusCode.OK)]
public async Task<ActionResult<IEnumerable<VideosVm>>> GetVideosByUserName(string username)
{
var query = new GetVideosListQuery(username);
var query = new GetVideosListByUserNameQuery(username);
var videos = await mediator.Send(query);
return Ok(videos);
}

View File

@@ -2,6 +2,8 @@ using CleanArchitecture.Application;
using CleanArchitecture.Infrastructure;
using CleanArchitecture.Identity;
using CleanArchitecture.API.Middlewares;
using CleanArchitecture.Infrastructure.Persistence;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
@@ -14,6 +16,7 @@ builder.Services.AddSwaggerGen();
builder.Services.AddInfrastructureServices(builder.Configuration);
builder.Services.AddApplicationServices();
builder.Services.ConfigureIdentityServices(builder.Configuration);
@@ -28,6 +31,40 @@ builder.Services.AddCors(o =>
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
IServiceProvider services = scope.ServiceProvider;
try
{
var dbContext = services.GetRequiredService<StreamerDbContext>(); // Reemplaza YourDbContext con el contexto de tu aplicaci<63>n
dbContext.Database.Migrate(); // Aplica migraciones pendientes
}
catch (Exception ex)
{
// Considera a<>adir alg<6C>n manejo de errores aqu<71>, como loguear el error
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "Un error ocurri<72> mientras se aplicaban las migraciones.");
}
}
using (var scope = app.Services.CreateScope())
{
IServiceProvider services = scope.ServiceProvider;
try
{
var dbContext = services.GetRequiredService<CleanArchitectureIdentityDbContext>(); // Reemplaza YourDbContext con el contexto de tu aplicaci<63>n
dbContext.Database.Migrate(); // Aplica migraciones pendientes
}
catch (Exception ex)
{
// Considera a<>adir alg<6C>n manejo de errores aqu<71>, como loguear el error
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "Un error ocurri<72> mientras se aplicaban las migraciones.");
}
}
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{

View File

@@ -10,6 +10,16 @@
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:14563"
},
"http-production": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:14563"
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,

View File

@@ -1,8 +1,24 @@
{
"ConnectionStrings": {
"ConnectionString": "server=localhost;database=CleanArchitectureV3;user=root;password=securePassword",
"IdentityConnectionString": "server=localhost;database=CleanArchitecture.Security;user=root;password=securePassword"
},
"EmailSettings": {
"FromAddress": "alejandro@asarmiento.es",
"ApiKey": "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",
"FromName": "Alejandro Sarmiento"
},
"JwtSettings": {
"Key": "CjF*Hp$pHvsx$%wsSyfpMevUrzj@%TJv3ZjNPk34daE7N%3KjrjCnv2V76uRY8bCtH5aduTmMwdiuh%QP3iYEh$Fy*XDzz7S&pFyyZVDLDwTdFDxrP9m#A@MBgV6oNCf",
"Issuer": "CleanArchitectureAlejandroSarmiento",
"Audience": "CleanArchitectureUsers",
"DurationInMinutes": 360
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,24 @@
{
"ConnectionStrings": {
"ConnectionString": "server=smariadb.alexdev.es;port=20003;database=CleanArchitecture;user=CleanUser;password=e7848cfeUN$6Ny$v",
"IdentityConnectionString": "server=smariadb.alexdev.es;port=20003;database=CleanArchitecture.Security;user=CleanUser;password=e7848cfeUN$6Ny$v"
},
"EmailSettings": {
"FromAddress": "alejandro@asarmiento.es",
"ApiKey": "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",
"FromName": "Alejandro Sarmiento"
},
"JwtSettings": {
"Key": "CjF*Hp$pHvsx$%wsSyfpMevUrzj@%TJv3ZjNPk34daE7N%3KjrjCnv2V76uRY8bCtH5aduTmMwdiuh%QP3iYEh$Fy*XDzz7S&pFyyZVDLDwTdFDxrP9m#A@MBgV6oNCf",
"Issuer": "CleanArchitectureAlejandroSarmiento",
"Audience": "CleanArchitectureUsers",
"DurationInMinutes": 360
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -1,7 +1,7 @@
{
"ConnectionStrings": {
"ConnectionString": "server=localhost;database=CleanArchitectureV2;user=root;password=securePassword",
"ConnectionString": "server=localhost;database=CleanArchitectureV3;user=root;password=securePassword",
"IdentityConnectionString": "server=localhost;database=CleanArchitecture.Security;user=root;password=securePassword"
},
"EmailSettings": {

View File

@@ -34,7 +34,7 @@ namespace CleanArchitecture.Application.UnitTests.Features.Streamers.Commands.De
}
[Fact]
public async Task UpdateStreamerTest()
public async Task DeleteStreamerTest()
{
var handler = new DeleteStreamerCommandHandler(mockUnitOfWork.Object, mapper, logger.Object);
var request = new DeleteStreamerCommand()

View File

@@ -0,0 +1,42 @@
using AutoMapper;
using CleanArchitecture.Application.Features.Streamers.Queries.DTOs;
using CleanArchitecture.Application.Features.Streamers.Queries.GetStreamersListByName;
using CleanArchitecture.Application.Features.Streamers.Queries.GetStreamersListByUserName;
using CleanArchitecture.Application.Mappings;
using CleanArchitecture.Application.UnitTests.Mocks;
using CleanArchitecture.Infrastructure.Repositories;
using Moq;
using Shouldly;
using Xunit;
namespace CleanArchitecture.Application.UnitTests.Features.Streamers.Queries
{
public class GetStreamerListByNameQueryHandlerXUnitTest
{
private readonly IMapper mapper;
private Mock<UnitOfWork> mockUnitOfWork;
public GetStreamerListByNameQueryHandlerXUnitTest()
{
mockUnitOfWork = MockUnitOfWork.GetUnitOfWork();
var mapperConfiguration = new MapperConfiguration(cfg =>
{
cfg.AddProfile<MappingProfile>();
});
mapper = mapperConfiguration.CreateMapper();
MockStreamerRepository.AddDataStreamerRepository(mockUnitOfWork.Object.StreamerDbContext);
}
[Fact]
public async Task GetStreamerListByNameTest()
{
var handler = new GetStreamerListByNameQueryHandler(mockUnitOfWork.Object, mapper);
var request = new GetStreamerListByNameQuery("Avatar");
var result = await handler.Handle(request, CancellationToken.None);
result.ShouldBeOfType<List<StreamerBaseVm>>();
result.Count.ShouldBe(2);
}
}
}

View File

@@ -0,0 +1,40 @@
using AutoMapper;
using CleanArchitecture.Application.Features.Streamers.Queries.DTOs;
using CleanArchitecture.Application.Features.Streamers.Queries.GetStreamersListByUserName;
using CleanArchitecture.Application.Mappings;
using CleanArchitecture.Application.UnitTests.Mocks;
using CleanArchitecture.Infrastructure.Repositories;
using Moq;
using Shouldly;
using Xunit;
namespace CleanArchitecture.Application.UnitTests.Features.Streamers.Queries
{
public class GetStreamerListByUserNameQueryHandlerXUnitTest
{
private readonly IMapper mapper;
private Mock<UnitOfWork> mockUnitOfWork;
public GetStreamerListByUserNameQueryHandlerXUnitTest()
{
mockUnitOfWork = MockUnitOfWork.GetUnitOfWork();
var mapperConfiguration = new MapperConfiguration(cfg =>
{
cfg.AddProfile<MappingProfile>();
});
mapper = mapperConfiguration.CreateMapper();
MockStreamerRepository.AddDataStreamerRepository(mockUnitOfWork.Object.StreamerDbContext);
}
[Fact]
public async Task GetStreamerListByUserNameTest()
{
var handler = new GetStreamerListByUserNameQueryHandler(mockUnitOfWork.Object, mapper);
var request = new GetStreamerByUserNameListQuery("Alex");
var result = await handler.Handle(request, CancellationToken.None);
result.ShouldBeOfType<List<StreamerBaseVm>>();
result.Count.ShouldBe(1);
}
}
}

View File

@@ -1,5 +1,7 @@
using AutoMapper;
using CleanArchitecture.Application.Contracts.Persistence;
using CleanArchitecture.Application.Features.Streamers.Queries.DTOs;
using CleanArchitecture.Application.Features.Streamers.Queries.GetStreamersListByUserName;
using CleanArchitecture.Application.Features.Videos.Queries.DTOs;
using CleanArchitecture.Application.Features.Videos.Queries.GetVideosList;
using CleanArchitecture.Application.Mappings;
using CleanArchitecture.Application.UnitTests.Mocks;
@@ -30,8 +32,8 @@ namespace CleanArchitecture.Application.UnitTests.Features.Video.Queries
[Fact]
public async Task GetVideoListTest()
{
var handler = new GetVideosListQueryHandler(mockUnitOfWork.Object, mapper);
var request = new GetVideosListQuery("Alex");
var handler = new GetVideosListByUserNameQueryHandler(mockUnitOfWork.Object, mapper);
var request = new GetVideosListByUserNameQuery("Alex");
var result = await handler.Handle(request, CancellationToken.None);
result.ShouldBeOfType<List<VideosVm>>();

View File

@@ -17,6 +17,24 @@ namespace CleanArchitecture.Application.UnitTests.Mocks
fixture.Behaviors.Add(new OmitOnRecursionBehavior());
var streamers = fixture.CreateMany<Streamer>().ToList();
streamers.Add(fixture.Build<Streamer>()
.With(tr => tr.CreatedBy, "Alex")
.Without(tr => tr.Videos)
.Create()
);
streamers.Add(fixture.Build<Streamer>()
.With(tr => tr.Nombre, "Avatar")
.Without(tr => tr.Videos)
.Create()
);
streamers.Add(fixture.Build<Streamer>()
.With(tr => tr.Nombre, "Avatar 2")
.Without(tr => tr.Videos)
.Create()
);
var guidFromText = Guid.Parse("edfe00d5-7599-4788-b52a-acc2a683b188");
streamers.Add(fixture.Build<Streamer>()
.With(tr => tr.Id, guidFromText)

View File

@@ -14,7 +14,6 @@
<Folder Include="Features\Directors\Commands\DeleteDirector\" />
<Folder Include="Features\Directors\Commands\UpdateDirector\" />
<Folder Include="Features\Directors\Queries\" />
<Folder Include="Features\Streamers\Queries\" />
</ItemGroup>
<ItemGroup>

View File

@@ -9,6 +9,7 @@ namespace CleanArchitecture.Application.Contracts.Persistence
{
public interface IStreamerRepository: IAsyncRepository<Streamer>
{
public Task<IEnumerable<Streamer>> GetStreamerByNombre(string nombreVideo);
public Task<IEnumerable<Streamer>> GetStreamerByUserName(string userName);
}
}

View File

@@ -4,7 +4,7 @@ namespace CleanArchitecture.Application.Contracts.Persistence
{
public interface IVideoRepository : IAsyncRepository<Video>
{
Task<Video> GetVideoByNombre(string nombreVideo);
Task<IEnumerable<Video>> GetVideoByNombre(string nombreVideo);
Task<IEnumerable<Video>> GetVideoByUserName(string userName);
}
}

View File

@@ -0,0 +1,15 @@
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CleanArchitecture.Application.Features.Streamers.Queries.DTOs
{
public class StreamerBaseVm
{
public string? Nombre { get; set; }
public string? Url { get; set; }
}
}

View File

@@ -0,0 +1,16 @@
using CleanArchitecture.Application.Features.Streamers.Queries.DTOs;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CleanArchitecture.Application.Features.Streamers.Queries.GetStreamersListByName
{
public class GetStreamerListByNameQuery(string _Name) :
IRequest<List<StreamerBaseVm>>
{
public string Name { get; set; } = _Name;
}
}

View File

@@ -0,0 +1,25 @@
using AutoMapper;
using CleanArchitecture.Application.Contracts.Persistence;
using CleanArchitecture.Application.Features.Streamers.Queries.DTOs;
using CleanArchitecture.Application.Features.Streamers.Queries.GetStreamersListByUserName;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CleanArchitecture.Application.Features.Streamers.Queries.GetStreamersListByName
{
public class GetStreamerListByNameQueryHandler(IUnitOfWork _unitOfWork, IMapper _mapper) :
IRequestHandler<GetStreamerListByNameQuery, List<StreamerBaseVm>>
{
private readonly IUnitOfWork unitOfWork = _unitOfWork;
private readonly IMapper mapper = _mapper;
public async Task<List<StreamerBaseVm>> Handle(GetStreamerListByNameQuery request, CancellationToken cancellationToken)
{
var streamerList = await unitOfWork.StreamerRepository.GetStreamerByNombre(request.Name);
return mapper.Map<List<StreamerBaseVm>>(streamerList);
}
}
}

View File

@@ -0,0 +1,17 @@
using CleanArchitecture.Application.Features.Streamers.Queries.DTOs;
using CleanArchitecture.Application.Features.Videos.Queries.GetVideosList;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CleanArchitecture.Application.Features.Streamers.Queries.GetStreamersListByUserName
{
public class GetStreamerByUserNameListQuery(string _UserName) :
IRequest<List<StreamerBaseVm>>
{
public string UserName { get; set; } = _UserName;
}
}

View File

@@ -0,0 +1,25 @@
using AutoMapper;
using CleanArchitecture.Application.Contracts.Persistence;
using CleanArchitecture.Application.Features.Streamers.Queries.DTOs;
using CleanArchitecture.Application.Features.Videos.Queries.DTOs;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CleanArchitecture.Application.Features.Streamers.Queries.GetStreamersListByUserName
{
public class GetStreamerListByUserNameQueryHandler(IUnitOfWork _unitOfWork, IMapper _mapper) :
IRequestHandler<GetStreamerByUserNameListQuery, List<StreamerBaseVm>>
{
private readonly IUnitOfWork unitOfWork = _unitOfWork;
private readonly IMapper mapper = _mapper;
public async Task<List<StreamerBaseVm>> Handle(GetStreamerByUserNameListQuery request, CancellationToken cancellationToken)
{
var streamerList = await unitOfWork.StreamerRepository.GetStreamerByUserName(request.UserName);
return mapper.Map<List<StreamerBaseVm>>(streamerList);
}
}
}

View File

@@ -1,8 +1,8 @@
namespace CleanArchitecture.Application.Features.Videos.Queries.GetVideosList
{
public class VideosVm
{
public string? Nombre { get; set; }
public Guid StreamerId { get; set; }
}
}
namespace CleanArchitecture.Application.Features.Videos.Queries.DTOs
{
public class VideosVm
{
public string? Nombre { get; set; }
public Guid StreamerId { get; set; }
}
}

View File

@@ -1,10 +1,11 @@
using MediatR;
namespace CleanArchitecture.Application.Features.Videos.Queries.GetVideosList
{
public class GetVideosListQuery(string _UserName) :
IRequest<List<VideosVm>>
{
public string UserName { get; set; } = _UserName;
}
}
using CleanArchitecture.Application.Features.Videos.Queries.DTOs;
using MediatR;
namespace CleanArchitecture.Application.Features.Videos.Queries.GetVideosList
{
public class GetVideosListByUserNameQuery(string _UserName) :
IRequest<List<VideosVm>>
{
public string UserName { get; set; } = _UserName;
}
}

View File

@@ -1,20 +1,21 @@
using AutoMapper;
using CleanArchitecture.Application.Contracts.Persistence;
using MediatR;
namespace CleanArchitecture.Application.Features.Videos.Queries.GetVideosList
{
public class GetVideosListQueryHandler(IUnitOfWork _unitOfWork, IMapper _mapper) :
IRequestHandler<GetVideosListQuery, List<VideosVm>>
{
private readonly IUnitOfWork unitOfWork = _unitOfWork;
private readonly IMapper mapper = _mapper;
public async Task<List<VideosVm>> Handle(GetVideosListQuery request, CancellationToken cancellationToken)
{
var videoList = await unitOfWork.VideoRepository.GetVideoByUserName(request.UserName);
return mapper.Map<List<VideosVm>>(videoList);
}
}
}
using AutoMapper;
using CleanArchitecture.Application.Contracts.Persistence;
using CleanArchitecture.Application.Features.Videos.Queries.DTOs;
using MediatR;
namespace CleanArchitecture.Application.Features.Videos.Queries.GetVideosList
{
public class GetVideosListByUserNameQueryHandler(IUnitOfWork _unitOfWork, IMapper _mapper) :
IRequestHandler<GetVideosListByUserNameQuery, List<VideosVm>>
{
private readonly IUnitOfWork unitOfWork = _unitOfWork;
private readonly IMapper mapper = _mapper;
public async Task<List<VideosVm>> Handle(GetVideosListByUserNameQuery request, CancellationToken cancellationToken)
{
var videoList = await unitOfWork.VideoRepository.GetVideoByUserName(request.UserName);
return mapper.Map<List<VideosVm>>(videoList);
}
}
}

View File

@@ -2,9 +2,10 @@
using CleanArchitecture.Application.Features.Directors.Commands.CreateDirector;
using CleanArchitecture.Application.Features.Streamers.Commands.CreateStreamer;
using CleanArchitecture.Application.Features.Streamers.Commands.UpdateStreamer;
using CleanArchitecture.Application.Features.Streamers.Queries.DTOs;
using CleanArchitecture.Application.Features.Videos.Commands.CreateVideo;
using CleanArchitecture.Application.Features.Videos.Commands.UpdateVideo;
using CleanArchitecture.Application.Features.Videos.Queries.GetVideosList;
using CleanArchitecture.Application.Features.Videos.Queries.DTOs;
using CleanArchitecture.Domain;
@@ -26,6 +27,9 @@ namespace CleanArchitecture.Application.Mappings
#endregion Video
#region Streamer
CreateMap<Streamer, StreamerBaseVm>();
CreateMap<StreamerBaseVm, Streamer>();
CreateMap<CreateStreamerCommand, Streamer>();
CreateMap<Streamer, CreateStreamerCommand>();

View File

@@ -33,5 +33,7 @@ namespace CleanArchitecture.Infrastructure
return services;
}
}
}

View File

@@ -1,6 +1,7 @@
using CleanArchitecture.Application.Contracts.Persistence;
using CleanArchitecture.Domain;
using CleanArchitecture.Infrastructure.Persistence;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -12,6 +13,14 @@ namespace CleanArchitecture.Infrastructure.Repositories
public class StreamerRepository: RepositoryBase<Streamer>, IStreamerRepository
{
public StreamerRepository(StreamerDbContext context) : base(context) { }
public async Task<IEnumerable<Streamer>> GetStreamerByNombre(string nombreVideo)
{
return await context.Streamers.Where(x => x.Nombre!.Contains(nombreVideo)).ToListAsync();
}
public async Task<IEnumerable<Streamer>> GetStreamerByUserName(string userName)
{
return await context.Streamers.Where(x => x.CreatedBy!.Equals(userName)).ToListAsync();
}
}
}

View File

@@ -10,9 +10,9 @@ namespace CleanArchitecture.Infrastructure.Repositories
public VideoRepository(StreamerDbContext context) : base(context) { }
public async Task<Video> GetVideoByNombre(string nombreVideo)
public async Task<IEnumerable<Video>> GetVideoByNombre(string nombreVideo)
{
return await context.Videos.Where(x => x.Nombre!.Equals(nombreVideo)).SingleOrDefaultAsync();
return await context.Videos.Where(x => x.Nombre!.Contains(nombreVideo)).ToListAsync();
}
public async Task<IEnumerable<Video>> GetVideoByUserName(string userName)

View File

@@ -5,7 +5,13 @@ USER app
WORKDIR /app
EXPOSE 80
ARG ENVIRONMENT Production
ENV ASPNETCORE_ENVIRONMENT Production
ENV ASPNETCORE_HTTP_PORTS 80
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["CleanArchitecture.API/CleanArchitecture.API.csproj", "CleanArchitecture.API/"]
@@ -16,11 +22,10 @@ COPY ["CleanArchitecture.Identity/CleanArchitecture.Identity.csproj", "CleanArch
RUN dotnet restore "./CleanArchitecture.API/CleanArchitecture.API.csproj"
COPY . .
WORKDIR "/src/CleanArchitecture.API"
RUN dotnet build "./CleanArchitecture.API.csproj" -c $BUILD_CONFIGURATION -o /app/build
RUN dotnet build "./CleanArchitecture.API.csproj" -c Release -o /app/build
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./CleanArchitecture.API.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
RUN dotnet publish "./CleanArchitecture.API.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app

View File

@@ -0,0 +1,26 @@
version: '3.8'
services:
mariadb:
container_name: mariadb
image: mariadb
environment:
- MYSQL_ROOT_PASSWORD=securePassword
volumes:
- mariadb-data:/var/lib/mysql
expose:
- 3306
myapp:
container_name: app
build:
context: .
dockerfile: Dockerfile
ports:
- "15500:80"
environment:
- ASPNETCORE_ENVIRONMENT = Production
volumes:
mariadb-data:
driver: local