Skip to content

Commit 29630f8

Browse files
authored
Merge pull request #7 from yazilimacademy/Application
[Feature]: Category/GetAll and Create operations completed.
2 parents dbbaab1 + aaffc9c commit 29630f8

23 files changed

+408
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System;
2+
3+
namespace YazilimAcademy.Application.Common.Interfaces;
4+
5+
public interface ICurrentUserService
6+
{
7+
Guid UserId { get; }
8+
string IpAddress { get; }
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System.Reflection;
2+
using FluentValidation;
3+
using Microsoft.Extensions.DependencyInjection;
4+
5+
namespace YazilimAcademy.Application;
6+
7+
public static class DependencyInjection
8+
{
9+
public static IServiceCollection AddApplication(this IServiceCollection services)
10+
{
11+
12+
services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
13+
14+
services.AddMediatR(config =>
15+
{
16+
config.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
17+
18+
// config.AddBehavior(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
19+
20+
// config.AddBehavior(typeof(IPipelineBehavior<,>), typeof(CachingBehavior<,>));
21+
22+
});
23+
24+
return services;
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using MediatR;
2+
using YazilimAcademy.Application.Common.Models.Responses;
23

34
namespace YazilimAcademy.Application.Features.Categories.Commands.Create;
45

5-
public sealed record CreateCategoryCommand(string Name, string Description) : IRequest<Guid>;
6+
public sealed record CreateCategoryCommand(string Name, string Description) : IRequest<ResponseDto<Guid>>;
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
using System;
22
using MediatR;
33
using YazilimAcademy.Application.Common.Interfaces;
4+
using YazilimAcademy.Application.Common.Models.Responses;
45
using YazilimAcademy.Domain.Entities;
56

67
namespace YazilimAcademy.Application.Features.Categories.Commands.Create;
78

8-
public sealed class CreateCategoryCommandHandler : IRequestHandler<CreateCategoryCommand, Guid>
9+
public sealed class CreateCategoryCommandHandler : IRequestHandler<CreateCategoryCommand, ResponseDto<Guid>>
910
{
1011
private readonly IApplicationDbContext _dbContext;
1112

@@ -14,14 +15,14 @@ public CreateCategoryCommandHandler(IApplicationDbContext dbContext)
1415
_dbContext = dbContext;
1516
}
1617

17-
public async Task<Guid> Handle(CreateCategoryCommand request, CancellationToken cancellationToken)
18+
public async Task<ResponseDto<Guid>> Handle(CreateCategoryCommand request, CancellationToken cancellationToken)
1819
{
1920
var category = Category.Create(request.Name, request.Description);
2021

2122
_dbContext.Categories.Add(category);
2223

2324
await _dbContext.SaveChangesAsync(cancellationToken);
2425

25-
return category.Id;
26+
return ResponseDto<Guid>.Success(category.Id, "Kategori başarıyla oluşturuldu.");
2627
}
2728
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using YazilimAcademy.Domain.Common;
2+
3+
namespace YazilimAcademy.Domain.Entities
4+
{
5+
public class City : EntityBase
6+
{
7+
public int Id { get; set; }
8+
public string Name { get; set; }
9+
public double? Latitude { get; set; }
10+
public double? Longitude { get; set; }
11+
12+
public int CountryId { get; set; }
13+
public Country Country { get; set; }
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using YazilimAcademy.Domain.Common;
2+
using System.Text.Json.Serialization;
3+
using YazilimAcademy.Domain.ValueObjects;
4+
5+
namespace YazilimAcademy.Domain.Entities
6+
{
7+
public class Country : EntityBase
8+
{
9+
public int Id { get; set; }
10+
public string Name { get; set; }
11+
public string? Iso3 { get; set; } //ASK: ISO3 or ISO2 required?
12+
public string Iso2 { get; set; }
13+
public string? NumericCode { get; set; }
14+
public string? PhoneCode { get; set; }
15+
public string? Capital { get; set; }
16+
public string? Currency { get; set; }
17+
public string? CurrencyName { get; set; }
18+
public string? CurrencySymbol { get; set; }
19+
public string? Tld { get; set; }
20+
public string? Native { get; set; }
21+
public string? Region { get; set; }
22+
public string? RegionId { get; set; }
23+
public string? Subregion { get; set; }
24+
public string? SubregionId { get; set; }
25+
public string? Nationality { get; set; }
26+
public double? Latitude { get; set; }
27+
public double? Longitude { get; set; }
28+
public string? Emoji { get; set; }
29+
public string? EmojiU { get; set; }
30+
public List<CountryTimeZone> Timezones { get; set; } = new List<CountryTimeZone>();
31+
public CountryTranslation Translations { get; set; }
32+
public ICollection<City> Cities { get; set; }
33+
}
34+
}

src/YazilimAcademy.Domain/Entities/CourseCategory.cs

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
using System;
2-
using YazilimAcademy.Domain.Common;
3-
41
namespace YazilimAcademy.Domain.Entities;
52

6-
public sealed class CourseCategory : EntityBase
3+
public sealed class CourseCategory
74
{
85
public Guid CourseId { get; set; }
96
public Course Course { get; set; }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using YazilimAcademy.Domain.Common;
2+
using YazilimAcademy.Domain.Identity;
3+
4+
namespace YazilimAcademy.Domain.Entities
5+
{
6+
public class CourseComment:EntityBase<Guid>
7+
{
8+
public Guid UserId { get; set; }
9+
public User User { get; set; }
10+
11+
public string CourseId { get; set; }
12+
public Course Course { get; set; }
13+
14+
public string Text { get; set; }
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace YazilimAcademy.Domain.Entities
2+
{
3+
public sealed class CourseInstructor
4+
{
5+
public Guid CourseId { get; set; }
6+
public Course Course { get; set; }
7+
8+
public Guid InstructorId { get; set; }
9+
public Instructor Instructor { get; set; }
10+
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using YazilimAcademy.Domain.Common;
2+
using YazilimAcademy.Domain.ValueObjects;
3+
4+
namespace YazilimAcademy.Domain.Entities
5+
{
6+
public class Instructor : EntityBase
7+
{
8+
public FullName FullName { get; set; }
9+
public string? Headline { get; set; }
10+
public Email Email { get; set; }
11+
public string? Bio { get; set; }
12+
public string? ProfilePicturePath { get; set; }
13+
public ICollection<InstructorSocialMediaLink> SocialMediaLinks { get; set; } = [];
14+
15+
public ICollection<CourseInstructor> Courses { get; set; }
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using YazilimAcademy.Domain.Common;
2+
using YazilimAcademy.Domain.Enums;
3+
4+
namespace YazilimAcademy.Domain.Entities;
5+
6+
public sealed class InstructorSocialMediaLink : EntityBase
7+
{
8+
public Guid InstructorId { get; set; }
9+
public Instructor Instructor { get; set; }
10+
public string Url { get; set; }
11+
public SocialMediaLinkType Type { get; set; }
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace YazilimAcademy.Domain.Enums;
2+
3+
public enum SocialMediaLinkType
4+
{
5+
LinkedIn = 1,
6+
X = 2,
7+
Github = 3,
8+
Youtube = 4,
9+
Instagram = 5,
10+
Facebook = 6,
11+
Tiktok = 7,
12+
Website = 8,
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System.Net;
2+
using System.Net.Sockets;
3+
4+
namespace YazilimAcademy.Domain.Helpers;
5+
6+
public static class IpHelper
7+
{
8+
public static string GetIpAddress()
9+
{
10+
var host = Dns.GetHostEntry(Dns.GetHostName());
11+
12+
foreach (var ip in host.AddressList)
13+
{
14+
if (ip.AddressFamily == AddressFamily.InterNetwork)
15+
{
16+
return ip.ToString();
17+
}
18+
}
19+
return string.Empty;
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace YazilimAcademy.Domain.ValueObjects;
2+
3+
public sealed class CountryTimeZone
4+
{
5+
public string ZoneName { get; set; }
6+
public int GmtOffset { get; set; }
7+
public string GmtOffsetName { get; set; }
8+
public string Abbreviation { get; set; }
9+
public string TzName { get; set; }
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace YazilimAcademy.Domain.ValueObjects;
2+
3+
public sealed class CountryTranslation
4+
{
5+
public string Kr { get; set; }
6+
public string PtBR { get; set; }
7+
public string Pt { get; set; }
8+
public string Nl { get; set; }
9+
public string Hr { get; set; }
10+
public string Fa { get; set; }
11+
public string De { get; set; }
12+
public string Es { get; set; }
13+
public string Fr { get; set; }
14+
public string Ja { get; set; }
15+
public string It { get; set; }
16+
public string Cn { get; set; }
17+
public string Tr { get; set; }
18+
}

src/YazilimAcademy.Domain/YazilimAcademy.Domain.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10+
<Folder Include="Helpers\" />
1011
<Folder Include="Settings\" />
1112
<Folder Include="ValueObjects\" />
1213
</ItemGroup>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Microsoft.Extensions.Configuration;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using YazilimAcademy.Application.Common.Interfaces;
5+
using YazilimAcademy.Infrastructure.Persistence.Dapper;
6+
using YazilimAcademy.Infrastructure.Persistence.EntityFramework.Contexts;
7+
using YazilimAcademy.Infrastructure.Persistence.EntityFramework.Interceptors;
8+
9+
namespace YazilimAcademy.Infrastructure;
10+
11+
public static class DependencyInjection
12+
{
13+
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
14+
{
15+
services.AddScoped<ISqlConnectionFactory, SqlConnectionFactory>(provider => new SqlConnectionFactory(configuration.GetConnectionString("DefaultConnection")));
16+
17+
services.AddScoped<EntityInterceptor>();
18+
19+
services.AddDbContext<ApplicationDbContext>((provider, options) =>
20+
{
21+
var entityInterceptor = provider.GetRequiredService<EntityInterceptor>();
22+
23+
options.AddInterceptors(entityInterceptor);
24+
25+
options.UseNpgsql(configuration.GetConnectionString("DefaultConnection"));
26+
27+
options.UseSnakeCaseNamingConvention();
28+
});
29+
30+
services.AddScoped<IApplicationDbContext, ApplicationDbContext>();
31+
32+
33+
return services;
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using System.Data;
3+
using Npgsql;
4+
using YazilimAcademy.Application.Common.Interfaces;
5+
6+
namespace YazilimAcademy.Infrastructure.Persistence.Dapper;
7+
8+
public sealed class SqlConnectionFactory : ISqlConnectionFactory
9+
{
10+
private readonly string _connectionString;
11+
12+
public SqlConnectionFactory(string connectionString)
13+
{
14+
_connectionString = connectionString;
15+
}
16+
17+
public IDbConnection CreateConnection()
18+
{
19+
var connection = new NpgsqlConnection(_connectionString);
20+
21+
connection.Open();
22+
23+
return connection;
24+
}
25+
}

0 commit comments

Comments
 (0)