Skip to content

Commit

Permalink
config: @CCT-21 Configure Swagger, Logging, Exception Handler Middlew…
Browse files Browse the repository at this point in the history
  • Loading branch information
leesoonduck3009 authored Sep 16, 2024
1 parent 88e8a05 commit 7d7f57d
Show file tree
Hide file tree
Showing 33 changed files with 777 additions and 32 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -396,3 +396,4 @@ FodyWeavers.xsd

# JetBrains Rider
*.sln.iml
.idea/
2 changes: 1 addition & 1 deletion ChitChatSolution.sln
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A796AB91-F
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChitChat.Test", "test\ChitChat.Test\ChitChat.Test.csproj", "{D21CB7BF-1E5E-42C6-B549-79D0A850B351}"
EndProject
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{37FE7C74-3803-4E83-A00F-09A51F680D0A}"
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker\DockerCompose\docker-compose.dcproj", "{37FE7C74-3803-4E83-A00F-09A51F680D0A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ services:
chitchat.webapi:
image: ${DOCKER_REGISTRY-}chitchatwebapi
build:
context: .
context: ../../
dockerfile: src/ChitChat.WebAPI/Dockerfile
ports:
- "8080:8080"
Expand Down
File renamed without changes.
4 changes: 4 additions & 0 deletions src/ChitChat.Application/ChitChat.Application.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,9 @@
<ItemGroup>
<ProjectReference Include="..\ChitChat.DataAccess\ChitChat.DataAccess.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Services\Caching\CacheKey\" />
</ItemGroup>

</Project>
29 changes: 29 additions & 0 deletions src/ChitChat.Application/DependencyInjection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using ChitChat.Application.Mapping;
using ChitChat.Application.Services;
using FluentValidation;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Reflection;
namespace ChitChat.Application
{
public static class DependencyInjection
{
public static IServiceCollection AddApplicationServices(this IServiceCollection services)
{
services.AddAutoMapper(Assembly.GetExecutingAssembly());
services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
services.AddMediatR(cfg =>
{
cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
});
services.AddAutoMapper(typeof(IMappingProfileMarker));
services.AddService();
return services;
}
public static IServiceCollection AddService(this IServiceCollection services) {

return services;
}
}
}
21 changes: 21 additions & 0 deletions src/ChitChat.Application/Exceptions/ApplicationException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using ChitChat.Application.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChitChat.Application.Exceptions
{
[Serializable]
public abstract class ApplicationException : Exception
{
public ApiResultErrorCodes Code { get; protected set; }

public bool TransactionRollback { get; protected set; } = true;

public ApplicationException(string message) : base(message)
{
}
}
}
11 changes: 11 additions & 0 deletions src/ChitChat.Application/Exceptions/ConflictException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
 using ChitChat.Application.Models;

namespace ChitChat.Application.Exceptions;
public class ConflictException : ApplicationException
{
public ConflictException(string message, bool transactionRollback = true) : base(message)
{
Code = ApiResultErrorCodes.Conflict;
TransactionRollback = transactionRollback;
}
}
12 changes: 12 additions & 0 deletions src/ChitChat.Application/Exceptions/ForbiddenException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using ChitChat.Application.Models;

namespace ChitChat.Application.Exceptions
{
public class ForbiddenException : ApplicationException
{
public ForbiddenException(string message) : base(message)
{
Code = ApiResultErrorCodes.Forbidden;
}
}
}
13 changes: 13 additions & 0 deletions src/ChitChat.Application/Exceptions/InvalidModelException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using ChitChat.Application.Models;

namespace ChitChat.Application.Exceptions;

[Serializable]
public class InvalidModelException : ApplicationException
{
public InvalidModelException(string message, bool transactionRollback = true) : base(message)
{
Code = ApiResultErrorCodes.ModelValidation;
TransactionRollback = transactionRollback;
}
}
28 changes: 28 additions & 0 deletions src/ChitChat.Application/Exceptions/NotFoundException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using ChitChat.Application.Localization;
using ChitChat.Application.Models;

namespace ChitChat.Application.Exceptions
{
public class NotFoundException : ApplicationException
{
public NotFoundException(Guid id, Type type) : base(ValidationTexts.NotFound.Format(type.Name, id.ToString()))
{
Code = ApiResultErrorCodes.NotFound;
}

public NotFoundException(string code, Type type) : base(ValidationTexts.NotFound.Format(type.Name, code))
{
Code = ApiResultErrorCodes.NotFound;
}

public NotFoundException(string message): base(message)
{
Code = ApiResultErrorCodes.NotFound;
}

public NotFoundException(int count, Type type) : base(ValidationTexts.NotFound.Format(count, type.Name))
{
Code = ApiResultErrorCodes.NotFound;
}
}
}
10 changes: 10 additions & 0 deletions src/ChitChat.Application/Exceptions/UnauthorizeException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace ChitChat.Application.Exceptions
{
public class UnauthorizeException : ApplicationException
{
public UnauthorizeException(string message) : base(message)
{
Code = Models.ApiResultErrorCodes.Unauthorize;
}
}
}
17 changes: 17 additions & 0 deletions src/ChitChat.Application/Localization/ValidationText.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using ChitChat.Domain.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChitChat.Application.Localization
{
public static class ValidationTexts
{
public static readonly LocalizedText NotFound = LocalizedText.New("{0} {1} not found").AddDefaultText("{0} {1} không tồn tại.");
public static readonly LocalizedText Conflict = LocalizedText.New("{0} {1} is already existed").AddDefaultText("{0} với {1} đã tồn tại.");
public static readonly LocalizedText NotValidate = LocalizedText.New("{0} {1} is not validated").AddDefaultText("{0} với {1} không hợp lệ.");

}
}
12 changes: 12 additions & 0 deletions src/ChitChat.Application/Mapping/IMappingProfileMarker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChitChat.Application.Mapping
{
public interface IMappingProfileMarker
{
}
}
60 changes: 60 additions & 0 deletions src/ChitChat.Application/Models/ApiResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChitChat.Application.Models
{
public class ApiResult<T>
{
private ApiResult() { }

private ApiResult(bool succeeded, T result, IEnumerable<ApiResultError> errors)
{
Succeeded = succeeded;
Result = result;
Errors = errors;
}

public bool Succeeded { get; set; }

public T Result { get; set; }

public IEnumerable<ApiResultError> Errors { get; set; }

public static ApiResult<T> Success(T result)
{
return new ApiResult<T>(true, result, new List<ApiResultError>());
}

public static ApiResult<T> Failure(IEnumerable<ApiResultError> errors)
{
return new ApiResult<T>(false, default, errors);
}
}

public class ApiResultError
{
public string Code { get; set; }

public string Message { get; set; }

public ApiResultError(ApiResultErrorCodes code, string message)
{
Code = code.ToString();
Message = message;
}
}

public enum ApiResultErrorCodes
{
InternalServerError,
ModelValidation,
PermissionValidation,
NotFound,
Unauthorize,
Forbidden,
Conflict
}
}
13 changes: 13 additions & 0 deletions src/ChitChat.Application/Models/Dtos/BaseResponseDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChitChat.Application.Models.Dtos
{
public class BaseResponseDto
{
public Guid Id;
}
}
21 changes: 21 additions & 0 deletions src/ChitChat.Application/Services/Caching/CacheEntryOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChitChat.Application.Services.Caching
{
public class CacheEntryOptions
{
public TimeSpan SlidingExpiration { get; set; }
public TimeSpan AbsoluteExpirationRelativeToNow { get; set; }

public static CacheEntryOptions Default = new()
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1),
SlidingExpiration = TimeSpan.FromHours(1)
};
}

}
16 changes: 16 additions & 0 deletions src/ChitChat.Application/Services/Caching/ICachingService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChitChat.Application.Services.Caching
{
public interface ICachingService
{
Task Set<T>(string key, T value);
Task<T> Get<T>(string key);
Task<T> GetOrSetAsync<T>(string key, Func<Task<T>> func);
Task Remove(string key);
}
}
23 changes: 23 additions & 0 deletions src/ChitChat.Infrastructure/Caching/CachingRegistrations.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using ChitChat.Application.Services.Caching;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChitChat.Infrastructure.Caching
{
public static class CachingRegistrations
{
public static WebApplicationBuilder AddCaching(this WebApplicationBuilder builder)
{
builder.Services
.AddMemoryCache()
.AddSingleton<ICachingService, MemoryCacheService>();
return builder;
}
}

}
60 changes: 60 additions & 0 deletions src/ChitChat.Infrastructure/Caching/MemoryCacheService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using ChitChat.Application.Services.Caching;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChitChat.Infrastructure.Caching
{
public class MemoryCacheService : ICachingService
{
private readonly IMemoryCache _memoryCache;

private MemoryCacheEntryOptions MemoryCacheEntryOptions = new()
{
AbsoluteExpirationRelativeToNow = CacheEntryOptions.Default.AbsoluteExpirationRelativeToNow,
SlidingExpiration = CacheEntryOptions.Default.SlidingExpiration
};

public MemoryCacheService(IMemoryCache memoryCache)
{
this._memoryCache = memoryCache;
}

public async Task Set<T>(string key, T value)
{
await Task.Yield();
this._memoryCache.Set(key, value, this.MemoryCacheEntryOptions);
}

public async Task<T> Get<T>(string key)
{
await Task.Yield();
this._memoryCache.TryGetValue<T>(key, out var cacheEntry);
return cacheEntry;
}

public async Task<T> GetOrSetAsync<T>(string key, Func<Task<T>> func)
{
var cacheEntry = await this._memoryCache.GetOrCreateAsync(key, async entry =>
{
entry
.SetSlidingExpiration(this.MemoryCacheEntryOptions.SlidingExpiration!.Value)
.SetAbsoluteExpiration(this.MemoryCacheEntryOptions.AbsoluteExpirationRelativeToNow!.Value);

return await func();
});

return cacheEntry;
}

public async Task Remove(string key)
{
this._memoryCache.Remove(key);
await Task.CompletedTask;
}
}

}
Loading

0 comments on commit 7d7f57d

Please sign in to comment.