From e4e0fcf47a0b65a971acf4a584a41f69b1877ea4 Mon Sep 17 00:00:00 2001 From: pns-hassanzadeh Date: Fri, 5 Sep 2025 19:17:19 +0330 Subject: [PATCH 1/4] . --- .../Configuration/Assemblies.cs | 13 +++---- .../Application/IUnitOfWork.cs | 17 +++++++++ .../Controllers/FileController.cs | 2 +- .../Domain/Entities/Client.cs | 9 +++++ .../Domain/Entities/Media.cs | 14 +++++++ .../Domain/Entities/MediaClient.cs | 13 +++++++ .../Domain/Entities/MediaGroup.cs | 13 +++++++ .../Domain/Entities/MediaGroupMedia.cs | 11 ++++++ .../Domain/Repositories/IClientRepository.cs | 7 ++++ .../Repositories/IMediaClientRepository.cs | 7 ++++ .../IMediaGroupMediaRepository.cs | 7 ++++ .../Repositories/IMediaGroupRepository.cs | 7 ++++ .../Domain/Repositories/IMediaRepository.cs | 7 ++++ .../Domain/TypeIds/ClientId.cs | 10 +++++ .../Domain/TypeIds/MediaClientId.cs | 10 +++++ .../Domain/TypeIds/MediaGroupId.cs | 10 +++++ .../Domain/TypeIds/MediaGroupMediaId.cs | 10 +++++ .../Domain/TypeIds/MediaId.cs | 10 +++++ .../Domain/ValueObjects/ContentType.cs | 15 ++++++++ .../ValueObjects/MediaClientName.cs | 6 +-- .../ValueObjects/MediaGroupTitle.cs | 6 +-- .../Rules/ValidContentTypeRule.cs | 4 +- Vizhtalk.CDN.Presentation/Entities/Client.cs | 10 ----- Vizhtalk.CDN.Presentation/Entities/Media.cs | 15 -------- .../Entities/MediaClient.cs | 14 ------- .../Entities/MediaGroup.cs | 14 ------- .../Entities/MediaGroupMedia.cs | 12 ------ .../Infrastructure/CDNStartup.cs | 38 +++++++++++++++++++ .../Configuration/Assemblies.cs | 12 ++++++ .../Infrastructure/EF/CDNDbContext.cs | 24 ++++++++++++ .../EF/Configurations/ClientConfiguration.cs | 17 +++++++++ .../MediaClientConfiguration.cs | 17 +++++++++ .../EF/Configurations/MediaConfiguration.cs | 19 ++++++++++ .../Configurations/MediaGroupConfiguration.cs | 16 ++++++++ .../MediaGroupMediaConfiguration.cs | 16 ++++++++ .../Infrastructure/UnitOfWork.cs | 23 +++++++++++ Vizhtalk.CDN.Presentation/Program.cs | 10 +++++ Vizhtalk.CDN.Presentation/TypeIds/ClientId.cs | 11 ------ .../TypeIds/MediaClientId.cs | 11 ------ .../TypeIds/MediaGroupId.cs | 11 ------ .../TypeIds/MediaGroupMediaId.cs | 11 ------ Vizhtalk.CDN.Presentation/TypeIds/MediaId.cs | 11 ------ .../ValueObjects/ContentType.cs | 16 -------- .../Vizhtalk.CDN.Presentation.csproj | 9 ++++- Vizhtalk.CDN.Presentation/appsettings.json | 2 +- 45 files changed, 392 insertions(+), 155 deletions(-) create mode 100644 Vizhtalk.CDN.Presentation/Application/IUnitOfWork.cs create mode 100644 Vizhtalk.CDN.Presentation/Domain/Entities/Client.cs create mode 100644 Vizhtalk.CDN.Presentation/Domain/Entities/Media.cs create mode 100644 Vizhtalk.CDN.Presentation/Domain/Entities/MediaClient.cs create mode 100644 Vizhtalk.CDN.Presentation/Domain/Entities/MediaGroup.cs create mode 100644 Vizhtalk.CDN.Presentation/Domain/Entities/MediaGroupMedia.cs create mode 100644 Vizhtalk.CDN.Presentation/Domain/Repositories/IClientRepository.cs create mode 100644 Vizhtalk.CDN.Presentation/Domain/Repositories/IMediaClientRepository.cs create mode 100644 Vizhtalk.CDN.Presentation/Domain/Repositories/IMediaGroupMediaRepository.cs create mode 100644 Vizhtalk.CDN.Presentation/Domain/Repositories/IMediaGroupRepository.cs create mode 100644 Vizhtalk.CDN.Presentation/Domain/Repositories/IMediaRepository.cs create mode 100644 Vizhtalk.CDN.Presentation/Domain/TypeIds/ClientId.cs create mode 100644 Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaClientId.cs create mode 100644 Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaGroupId.cs create mode 100644 Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaGroupMediaId.cs create mode 100644 Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaId.cs create mode 100644 Vizhtalk.CDN.Presentation/Domain/ValueObjects/ContentType.cs rename Vizhtalk.CDN.Presentation/{ => Domain}/ValueObjects/MediaClientName.cs (61%) rename Vizhtalk.CDN.Presentation/{ => Domain}/ValueObjects/MediaGroupTitle.cs (59%) rename Vizhtalk.CDN.Presentation/{ => Domain}/ValueObjects/Rules/ValidContentTypeRule.cs (94%) delete mode 100644 Vizhtalk.CDN.Presentation/Entities/Client.cs delete mode 100644 Vizhtalk.CDN.Presentation/Entities/Media.cs delete mode 100644 Vizhtalk.CDN.Presentation/Entities/MediaClient.cs delete mode 100644 Vizhtalk.CDN.Presentation/Entities/MediaGroup.cs delete mode 100644 Vizhtalk.CDN.Presentation/Entities/MediaGroupMedia.cs create mode 100644 Vizhtalk.CDN.Presentation/Infrastructure/CDNStartup.cs create mode 100644 Vizhtalk.CDN.Presentation/Infrastructure/Configuration/Assemblies.cs create mode 100644 Vizhtalk.CDN.Presentation/Infrastructure/EF/CDNDbContext.cs create mode 100644 Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/ClientConfiguration.cs create mode 100644 Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaClientConfiguration.cs create mode 100644 Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaConfiguration.cs create mode 100644 Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaGroupConfiguration.cs create mode 100644 Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaGroupMediaConfiguration.cs create mode 100644 Vizhtalk.CDN.Presentation/Infrastructure/UnitOfWork.cs delete mode 100644 Vizhtalk.CDN.Presentation/TypeIds/ClientId.cs delete mode 100644 Vizhtalk.CDN.Presentation/TypeIds/MediaClientId.cs delete mode 100644 Vizhtalk.CDN.Presentation/TypeIds/MediaGroupId.cs delete mode 100644 Vizhtalk.CDN.Presentation/TypeIds/MediaGroupMediaId.cs delete mode 100644 Vizhtalk.CDN.Presentation/TypeIds/MediaId.cs delete mode 100644 Vizhtalk.CDN.Presentation/ValueObjects/ContentType.cs diff --git a/VizhTalk.Learning.Infrastructure/Configuration/Assemblies.cs b/VizhTalk.Learning.Infrastructure/Configuration/Assemblies.cs index a458a78..19811f4 100644 --- a/VizhTalk.Learning.Infrastructure/Configuration/Assemblies.cs +++ b/VizhTalk.Learning.Infrastructure/Configuration/Assemblies.cs @@ -7,12 +7,11 @@ using System.Threading.Tasks; using VizhTalk.Learning.Application; using VizhTalk.Learning.Domain.Entities; -namespace VizhTalk.Learning.Infrastructure.Configuration +namespace VizhTalk.Learning.Infrastructure.Configuration; + +public static class Assemblies { - public static class Assemblies - { - public static Assembly Infrastructure = typeof(LearningStartup).Assembly; - public static Assembly Application = typeof(ILearningModule).Assembly; - public static Assembly Domain = typeof(Language).Assembly; - } + public static Assembly Infrastructure = typeof(LearningStartup).Assembly; + public static Assembly Application = typeof(ILearningModule).Assembly; + public static Assembly Domain = typeof(Language).Assembly; } diff --git a/Vizhtalk.CDN.Presentation/Application/IUnitOfWork.cs b/Vizhtalk.CDN.Presentation/Application/IUnitOfWork.cs new file mode 100644 index 0000000..90312a6 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Application/IUnitOfWork.cs @@ -0,0 +1,17 @@ +using Vizhtalk.CDN.Presentation.Domain.Repositories; +using VizhTalk.BuildingBlocks.Application; + +namespace Vizhtalk.CDN.Presentation.Application +{ + internal interface IUnitOfWork : IUnitOfWorkBase + { + IMediaRepository Media { get; } + IClientRepository Client { get; } + IMediaClientRepository MediaClient { get; } + IMediaGroupRepository MediaGroup{ get; } + IMediaGroupMediaRepository MediaGroupMedia { get; } + + Task SaveChangeAsync(CancellationToken cancellationToken = default); + } + +} diff --git a/Vizhtalk.CDN.Presentation/Controllers/FileController.cs b/Vizhtalk.CDN.Presentation/Controllers/FileController.cs index a56ecbf..525c01b 100644 --- a/Vizhtalk.CDN.Presentation/Controllers/FileController.cs +++ b/Vizhtalk.CDN.Presentation/Controllers/FileController.cs @@ -1,5 +1,5 @@ using Microsoft.AspNetCore.Mvc; -using Vizhtalk.CDN.Presentation.TypeIds; +using Vizhtalk.CDN.Presentation.Domain.TypeIds; namespace Vizhtalk.CDN.Presentation.Controllers { diff --git a/Vizhtalk.CDN.Presentation/Domain/Entities/Client.cs b/Vizhtalk.CDN.Presentation/Domain/Entities/Client.cs new file mode 100644 index 0000000..872c254 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Domain/Entities/Client.cs @@ -0,0 +1,9 @@ +using Vizhtalk.CDN.Presentation.Domain.TypeIds; +using VizhTalk.BuildingBlocks.Domain; + +namespace Vizhtalk.CDN.Presentation.Domain.Entities; + +public class Client : Entity +{ + +} diff --git a/Vizhtalk.CDN.Presentation/Domain/Entities/Media.cs b/Vizhtalk.CDN.Presentation/Domain/Entities/Media.cs new file mode 100644 index 0000000..78250c1 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Domain/Entities/Media.cs @@ -0,0 +1,14 @@ +using VizhTalk.BuildingBlocks.Domain; +using Vizhtalk.CDN.Presentation.Domain.TypeIds; +using Vizhtalk.CDN.Presentation.Domain.ValueObjects; + +namespace Vizhtalk.CDN.Presentation.Domain.Entities; + +public class Media : Entity +{ + public ContentType ContentType { get; private set; } + public int Size { get; set; } + public string Path { get; private set; } + public string Hash { get; set; } + public List MediaGroupMedias { get; set; } +} diff --git a/Vizhtalk.CDN.Presentation/Domain/Entities/MediaClient.cs b/Vizhtalk.CDN.Presentation/Domain/Entities/MediaClient.cs new file mode 100644 index 0000000..911c975 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Domain/Entities/MediaClient.cs @@ -0,0 +1,13 @@ +using Vizhtalk.CDN.Presentation.Domain.TypeIds; +using Vizhtalk.CDN.Presentation.Domain.ValueObjects; +using VizhTalk.BuildingBlocks.Domain; + +namespace Vizhtalk.CDN.Presentation.Domain.Entities; + +public class MediaClient : Entity +{ + public MediaClientName Name { get; set; } + public MediaId MediaId { get; set; } + public ClientId ClientId { get; set; } + public MediaGroupMediaId MediaGroup { get; set; } +} diff --git a/Vizhtalk.CDN.Presentation/Domain/Entities/MediaGroup.cs b/Vizhtalk.CDN.Presentation/Domain/Entities/MediaGroup.cs new file mode 100644 index 0000000..f52184b --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Domain/Entities/MediaGroup.cs @@ -0,0 +1,13 @@ +using Vizhtalk.CDN.Presentation.Domain.TypeIds; +using Vizhtalk.CDN.Presentation.Domain.ValueObjects; +using VizhTalk.BuildingBlocks.Domain; + +namespace Vizhtalk.CDN.Presentation.Domain.Entities; + +public class MediaGroup : Entity +{ + public bool IsSecure { get; set; } + public MediaGroupTitle Title { get; set; } + public string Key { get; set; } + public List MediaGroupMedias { get; set; } +} diff --git a/Vizhtalk.CDN.Presentation/Domain/Entities/MediaGroupMedia.cs b/Vizhtalk.CDN.Presentation/Domain/Entities/MediaGroupMedia.cs new file mode 100644 index 0000000..14859b5 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Domain/Entities/MediaGroupMedia.cs @@ -0,0 +1,11 @@ +using Vizhtalk.CDN.Presentation.Domain.TypeIds; +using VizhTalk.BuildingBlocks.Domain; + +namespace Vizhtalk.CDN.Presentation.Domain.Entities; + +public class MediaGroupMedia : Entity +{ + public MediaId MediaId { get; set; } + public MediaGroupId MediaGroupId { get; set; } + public List MediaClients { get; set; } +} diff --git a/Vizhtalk.CDN.Presentation/Domain/Repositories/IClientRepository.cs b/Vizhtalk.CDN.Presentation/Domain/Repositories/IClientRepository.cs new file mode 100644 index 0000000..89e9af0 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Domain/Repositories/IClientRepository.cs @@ -0,0 +1,7 @@ +using Vizhtalk.CDN.Presentation.Domain.Entities; +using Vizhtalk.CDN.Presentation.Domain.TypeIds; +using VizhTalk.BuildingBlocks.Domain; + +namespace Vizhtalk.CDN.Presentation.Domain.Repositories; + +public interface IClientRepository : IRepositoryBase; diff --git a/Vizhtalk.CDN.Presentation/Domain/Repositories/IMediaClientRepository.cs b/Vizhtalk.CDN.Presentation/Domain/Repositories/IMediaClientRepository.cs new file mode 100644 index 0000000..2e30964 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Domain/Repositories/IMediaClientRepository.cs @@ -0,0 +1,7 @@ +using Vizhtalk.CDN.Presentation.Domain.Entities; +using Vizhtalk.CDN.Presentation.Domain.TypeIds; +using VizhTalk.BuildingBlocks.Domain; + +namespace Vizhtalk.CDN.Presentation.Domain.Repositories; + +public interface IMediaClientRepository : IRepositoryBase; diff --git a/Vizhtalk.CDN.Presentation/Domain/Repositories/IMediaGroupMediaRepository.cs b/Vizhtalk.CDN.Presentation/Domain/Repositories/IMediaGroupMediaRepository.cs new file mode 100644 index 0000000..fb21569 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Domain/Repositories/IMediaGroupMediaRepository.cs @@ -0,0 +1,7 @@ +using Vizhtalk.CDN.Presentation.Domain.Entities; +using Vizhtalk.CDN.Presentation.Domain.TypeIds; +using VizhTalk.BuildingBlocks.Domain; + +namespace Vizhtalk.CDN.Presentation.Domain.Repositories; + +public interface IMediaGroupMediaRepository : IRepositoryBase; diff --git a/Vizhtalk.CDN.Presentation/Domain/Repositories/IMediaGroupRepository.cs b/Vizhtalk.CDN.Presentation/Domain/Repositories/IMediaGroupRepository.cs new file mode 100644 index 0000000..0a3e18f --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Domain/Repositories/IMediaGroupRepository.cs @@ -0,0 +1,7 @@ +using Vizhtalk.CDN.Presentation.Domain.Entities; +using Vizhtalk.CDN.Presentation.Domain.TypeIds; +using VizhTalk.BuildingBlocks.Domain; + +namespace Vizhtalk.CDN.Presentation.Domain.Repositories; + +public interface IMediaGroupRepository : IRepositoryBase; diff --git a/Vizhtalk.CDN.Presentation/Domain/Repositories/IMediaRepository.cs b/Vizhtalk.CDN.Presentation/Domain/Repositories/IMediaRepository.cs new file mode 100644 index 0000000..6cab604 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Domain/Repositories/IMediaRepository.cs @@ -0,0 +1,7 @@ +using Vizhtalk.CDN.Presentation.Domain.Entities; +using Vizhtalk.CDN.Presentation.Domain.TypeIds; +using VizhTalk.BuildingBlocks.Domain; + +namespace Vizhtalk.CDN.Presentation.Domain.Repositories; + +public interface IMediaRepository : IRepositoryBase; diff --git a/Vizhtalk.CDN.Presentation/Domain/TypeIds/ClientId.cs b/Vizhtalk.CDN.Presentation/Domain/TypeIds/ClientId.cs new file mode 100644 index 0000000..db83b70 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Domain/TypeIds/ClientId.cs @@ -0,0 +1,10 @@ +using VizhTalk.BuildingBlocks.Domain; + +namespace Vizhtalk.CDN.Presentation.Domain.TypeIds; + +public class ClientId : TypedIdValueBase +{ + public ClientId(string value) : base(value) + { + } +} diff --git a/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaClientId.cs b/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaClientId.cs new file mode 100644 index 0000000..110be1b --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaClientId.cs @@ -0,0 +1,10 @@ +using VizhTalk.BuildingBlocks.Domain; + +namespace Vizhtalk.CDN.Presentation.Domain.TypeIds; + +public class MediaClientId : TypedIdValueBase +{ + public MediaClientId(long value) : base(value) + { + } +} diff --git a/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaGroupId.cs b/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaGroupId.cs new file mode 100644 index 0000000..75f5100 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaGroupId.cs @@ -0,0 +1,10 @@ +using VizhTalk.BuildingBlocks.Domain; + +namespace Vizhtalk.CDN.Presentation.Domain.TypeIds; + +public class MediaGroupId : TypedIdValueBase +{ + public MediaGroupId(long value) : base(value) + { + } +} diff --git a/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaGroupMediaId.cs b/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaGroupMediaId.cs new file mode 100644 index 0000000..adcd676 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaGroupMediaId.cs @@ -0,0 +1,10 @@ +using VizhTalk.BuildingBlocks.Domain; + +namespace Vizhtalk.CDN.Presentation.Domain.TypeIds; + +public class MediaGroupMediaId : TypedIdValueBase +{ + public MediaGroupMediaId(Guid value) : base(value) + { + } +} diff --git a/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaId.cs b/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaId.cs new file mode 100644 index 0000000..40fd700 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaId.cs @@ -0,0 +1,10 @@ +using VizhTalk.BuildingBlocks.Domain; + +namespace Vizhtalk.CDN.Presentation.Domain.TypeIds; + +public class MediaId : TypedIdValueBase +{ + public MediaId(long value) : base(value) + { + } +} diff --git a/Vizhtalk.CDN.Presentation/Domain/ValueObjects/ContentType.cs b/Vizhtalk.CDN.Presentation/Domain/ValueObjects/ContentType.cs new file mode 100644 index 0000000..f2d136c --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Domain/ValueObjects/ContentType.cs @@ -0,0 +1,15 @@ +using Vizhtalk.CDN.Presentation.Domain.ValueObjects.Rules; +using VizhTalk.BuildingBlocks.Domain; + +namespace Vizhtalk.CDN.Presentation.Domain.ValueObjects; + +public class ContentType : ValueObject +{ + public ContentType(string contentType, byte[] fileBytes) + { + CheckRule(new ValidContentTypeRule(contentType, fileBytes)); + + Value = contentType; + } + public string Value { get; set; } +} diff --git a/Vizhtalk.CDN.Presentation/ValueObjects/MediaClientName.cs b/Vizhtalk.CDN.Presentation/Domain/ValueObjects/MediaClientName.cs similarity index 61% rename from Vizhtalk.CDN.Presentation/ValueObjects/MediaClientName.cs rename to Vizhtalk.CDN.Presentation/Domain/ValueObjects/MediaClientName.cs index c48723a..85657f0 100644 --- a/Vizhtalk.CDN.Presentation/ValueObjects/MediaClientName.cs +++ b/Vizhtalk.CDN.Presentation/Domain/ValueObjects/MediaClientName.cs @@ -1,14 +1,14 @@ using VizhTalk.BuildingBlocks.Domain; using VizhTalk.BuildingBlocks.Domain.Guards; -namespace Vizhtalk.CDN.Presentation.ValueObjects +namespace Vizhtalk.CDN.Presentation.Domain.ValueObjects { public class MediaClientName : ValueObject { public MediaClientName(string value) { - Guard.NullOrEmpty(value, nameof(MediaClientName)); - Guard.MaxLength(value, nameof(MediaClientName), 150); + value.NullOrEmpty(nameof(MediaClientName)); + value.MaxLength(nameof(MediaClientName), 150); Value = value; } diff --git a/Vizhtalk.CDN.Presentation/ValueObjects/MediaGroupTitle.cs b/Vizhtalk.CDN.Presentation/Domain/ValueObjects/MediaGroupTitle.cs similarity index 59% rename from Vizhtalk.CDN.Presentation/ValueObjects/MediaGroupTitle.cs rename to Vizhtalk.CDN.Presentation/Domain/ValueObjects/MediaGroupTitle.cs index a820031..553e3f6 100644 --- a/Vizhtalk.CDN.Presentation/ValueObjects/MediaGroupTitle.cs +++ b/Vizhtalk.CDN.Presentation/Domain/ValueObjects/MediaGroupTitle.cs @@ -1,14 +1,14 @@ using VizhTalk.BuildingBlocks.Domain; using VizhTalk.BuildingBlocks.Domain.Guards; -namespace Vizhtalk.CDN.Presentation.ValueObjects; +namespace Vizhtalk.CDN.Presentation.Domain.ValueObjects; public class MediaGroupTitle : ValueObject { public MediaGroupTitle(string value) { - Guard.NullOrEmpty(value, nameof(MediaGroupTitle)); - Guard.MaxLength(value, nameof(MediaGroupTitle),150); + value.NullOrEmpty(nameof(MediaGroupTitle)); + value.MaxLength(nameof(MediaGroupTitle),150); Value = value; } diff --git a/Vizhtalk.CDN.Presentation/ValueObjects/Rules/ValidContentTypeRule.cs b/Vizhtalk.CDN.Presentation/Domain/ValueObjects/Rules/ValidContentTypeRule.cs similarity index 94% rename from Vizhtalk.CDN.Presentation/ValueObjects/Rules/ValidContentTypeRule.cs rename to Vizhtalk.CDN.Presentation/Domain/ValueObjects/Rules/ValidContentTypeRule.cs index 24cdd70..0beb6c7 100644 --- a/Vizhtalk.CDN.Presentation/ValueObjects/Rules/ValidContentTypeRule.cs +++ b/Vizhtalk.CDN.Presentation/Domain/ValueObjects/Rules/ValidContentTypeRule.cs @@ -2,7 +2,7 @@ using System.Text; using VizhTalk.BuildingBlocks.Domain.Exceptions; -namespace Vizhtalk.CDN.Presentation.ValueObjects.Rules; +namespace Vizhtalk.CDN.Presentation.Domain.ValueObjects.Rules; public class ValidContentTypeRule(string contentType, byte[] fileBytes) : IBusinessRule { @@ -81,7 +81,7 @@ public class ValidContentTypeRule(string contentType, byte[] fileBytes) : IBusin return true; if (contentType == "audio/mpeg" && (fileBytes.Take(3).SequenceEqual(new byte[] { 0x49, 0x44, 0x33 }) // ID3 - || (fileBytes[0] == 0xFF && (fileBytes[1] & 0xE0) == 0xE0))) // MPEG frame + || fileBytes[0] == 0xFF && (fileBytes[1] & 0xE0) == 0xE0)) // MPEG frame return true; if (contentType == "image/svg+xml") diff --git a/Vizhtalk.CDN.Presentation/Entities/Client.cs b/Vizhtalk.CDN.Presentation/Entities/Client.cs deleted file mode 100644 index 37d7a3c..0000000 --- a/Vizhtalk.CDN.Presentation/Entities/Client.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Vizhtalk.CDN.Presentation.TypeIds; -using VizhTalk.BuildingBlocks.Domain; - -namespace Vizhtalk.CDN.Presentation.Entities -{ - public class Client : Entity - { - - } -} diff --git a/Vizhtalk.CDN.Presentation/Entities/Media.cs b/Vizhtalk.CDN.Presentation/Entities/Media.cs deleted file mode 100644 index bdaf33c..0000000 --- a/Vizhtalk.CDN.Presentation/Entities/Media.cs +++ /dev/null @@ -1,15 +0,0 @@ -using VizhTalk.BuildingBlocks.Domain; -using Vizhtalk.CDN.Presentation.TypeIds; -using Vizhtalk.CDN.Presentation.ValueObjects; - -namespace Vizhtalk.CDN.Presentation.Entities -{ - public class Media : Entity - { - public ContentType ContentType { get; private set; } - public int Size { get; set; } - public string Path { get; private set; } - public string Hash { get; set; } - public List MediaGroupMedias { get; set; } - } -} diff --git a/Vizhtalk.CDN.Presentation/Entities/MediaClient.cs b/Vizhtalk.CDN.Presentation/Entities/MediaClient.cs deleted file mode 100644 index ce52191..0000000 --- a/Vizhtalk.CDN.Presentation/Entities/MediaClient.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Vizhtalk.CDN.Presentation.TypeIds; -using Vizhtalk.CDN.Presentation.ValueObjects; -using VizhTalk.BuildingBlocks.Domain; - -namespace Vizhtalk.CDN.Presentation.Entities -{ - public class MediaClient : Entity - { - public MediaClientName Name { get; set; } - public MediaId MediaId { get; set; } - public ClientId ClientId { get; set; } - public MediaGroupMediaId MediaGroup { get; set; } - } -} diff --git a/Vizhtalk.CDN.Presentation/Entities/MediaGroup.cs b/Vizhtalk.CDN.Presentation/Entities/MediaGroup.cs deleted file mode 100644 index 3d399e6..0000000 --- a/Vizhtalk.CDN.Presentation/Entities/MediaGroup.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Vizhtalk.CDN.Presentation.TypeIds; -using Vizhtalk.CDN.Presentation.ValueObjects; -using VizhTalk.BuildingBlocks.Domain; - -namespace Vizhtalk.CDN.Presentation.Entities -{ - public class MediaGroup : Entity - { - public bool IsSecure { get; set; } - public MediaGroupTitle Title { get; set; } - public string Key { get; set; } - public List MediaGroupMedias { get; set; } - } -} diff --git a/Vizhtalk.CDN.Presentation/Entities/MediaGroupMedia.cs b/Vizhtalk.CDN.Presentation/Entities/MediaGroupMedia.cs deleted file mode 100644 index 08418f4..0000000 --- a/Vizhtalk.CDN.Presentation/Entities/MediaGroupMedia.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Vizhtalk.CDN.Presentation.TypeIds; -using VizhTalk.BuildingBlocks.Domain; - -namespace Vizhtalk.CDN.Presentation.Entities -{ - public class MediaGroupMedia : Entity - { - public MediaId MediaId { get; set; } - public MediaGroupId MediaGroupId { get; set; } - public List MediaClients { get; set; } - } -} diff --git a/Vizhtalk.CDN.Presentation/Infrastructure/CDNStartup.cs b/Vizhtalk.CDN.Presentation/Infrastructure/CDNStartup.cs new file mode 100644 index 0000000..cea0495 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Infrastructure/CDNStartup.cs @@ -0,0 +1,38 @@ +using Microsoft.EntityFrameworkCore; +using MongoDB.Driver; +using Vizhtalk.CDN.Presentation.Application; +using Vizhtalk.CDN.Presentation.Infrastructure.Configuration; +using Vizhtalk.CDN.Presentation.Infrastructure.EF; +using VizhTalk.BuildingBlocks.Application; +using VizhTalk.BuildingBlocks.Application.Configuration.Commnad; +using VizhTalk.BuildingBlocks.Application.Configuration.Query; +using VizhTalk.BuildingBlocks.Application.Data; +using VizhTalk.BuildingBlocks.Application.Events; +using VizhTalk.BuildingBlocks.Application.Outbox; +using VizhTalk.BuildingBlocks.Infrastructure; +using VizhTalk.BuildingBlocks.Infrastructure.DomainEventsDispatching; + +namespace Vizhtalk.CDN.Presentation.Infrastructure; + +public static class CDNStartup +{ + public static void Initialize(this IServiceCollection services, string connectionString) + { + var domainNotificationsMap = new BiDictionary(); + + services.AddDbContext(op => + { + op.UseMongoDB(connectionString); + }); + services.AddScoped(sp => sp.GetService()); + } + + + + public static void UseCDNModule(this IApplicationBuilder app) + { + using var scope = app.ApplicationServices.CreateScope(); + var db = scope.ServiceProvider.GetRequiredService(); + db.Database.Migrate(); + } +} \ No newline at end of file diff --git a/Vizhtalk.CDN.Presentation/Infrastructure/Configuration/Assemblies.cs b/Vizhtalk.CDN.Presentation/Infrastructure/Configuration/Assemblies.cs new file mode 100644 index 0000000..7b49b39 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Infrastructure/Configuration/Assemblies.cs @@ -0,0 +1,12 @@ +using System.Reflection; +using Vizhtalk.CDN.Presentation.Application; +using Vizhtalk.CDN.Presentation.Domain.Entities; + +namespace Vizhtalk.CDN.Presentation.Infrastructure.Configuration; + +public static class Assemblies +{ + public static Assembly Infrastructure = typeof(UnitOfWork).Assembly; + public static Assembly Application = typeof(IUnitOfWork).Assembly; + public static Assembly Domain = typeof(Media).Assembly; +} \ No newline at end of file diff --git a/Vizhtalk.CDN.Presentation/Infrastructure/EF/CDNDbContext.cs b/Vizhtalk.CDN.Presentation/Infrastructure/EF/CDNDbContext.cs new file mode 100644 index 0000000..e139da9 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Infrastructure/EF/CDNDbContext.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore; +using Vizhtalk.CDN.Presentation.Infrastructure.Configuration; +using VizhTalk.BuildingBlocks.Infrastructure.EF.Helpers; + +namespace Vizhtalk.CDN.Presentation.Infrastructure.EF +{ + public class CDNDbContext : DbContext + { + + public CDNDbContext(DbContextOptions options) : base(options) + { + + } + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.FindEntities(Assemblies.Domain) + .ApplyConfigurationsFromAssembly(Assemblies.Infrastructure, x => x.FullName.Contains("EF.Configurations")) + .PluralizeEntities(); + } + + } +} diff --git a/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/ClientConfiguration.cs b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/ClientConfiguration.cs new file mode 100644 index 0000000..b066548 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/ClientConfiguration.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Vizhtalk.CDN.Presentation.Domain.Entities; + +namespace Vizhtalk.CDN.Presentation.Infrastructure.EF.Configurations; + +public class ClientConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable(nameof(Client)); + builder.HasKey(x => x.Id); + + builder.Property(x => x.Id) + .HasConversion(x => x.Value, x => new Domain.TypeIds.ClientId(x)); + } +} diff --git a/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaClientConfiguration.cs b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaClientConfiguration.cs new file mode 100644 index 0000000..4b99f32 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaClientConfiguration.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Vizhtalk.CDN.Presentation.Domain.Entities; + +namespace Vizhtalk.CDN.Presentation.Infrastructure.EF.Configurations; + +public class MediaClientConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable(nameof(MediaClient)); + builder.HasKey(x => x.Id); + + builder.Property(x => x.Id) + .HasConversion(x => x.Value, x => new Domain.TypeIds.MediaClientId(x)); + } +} diff --git a/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaConfiguration.cs b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaConfiguration.cs new file mode 100644 index 0000000..e4150ff --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaConfiguration.cs @@ -0,0 +1,19 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Vizhtalk.CDN.Presentation.Domain.Entities; + +namespace Vizhtalk.CDN.Presentation.Infrastructure.EF.Configurations; + +public class MediaConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable(nameof(Media)); + builder.HasKey(x => x.Id); + builder.Property(x => x.Id) + .HasConversion(x => x.Value, x => new Domain.TypeIds.MediaId(x)); + + builder.HasIndex(x => x.Hash); + + } +} diff --git a/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaGroupConfiguration.cs b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaGroupConfiguration.cs new file mode 100644 index 0000000..70bece1 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaGroupConfiguration.cs @@ -0,0 +1,16 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Vizhtalk.CDN.Presentation.Domain.Entities; + +namespace Vizhtalk.CDN.Presentation.Infrastructure.EF.Configurations; + +public class MediaGroupConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable(nameof(MediaGroup)); + builder.HasKey(x => x.Id); + builder.Property(x => x.Id) + .HasConversion(x => x.Value, x => new Domain.TypeIds.MediaGroupId(x)); + } +} diff --git a/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaGroupMediaConfiguration.cs b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaGroupMediaConfiguration.cs new file mode 100644 index 0000000..2061c75 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaGroupMediaConfiguration.cs @@ -0,0 +1,16 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Vizhtalk.CDN.Presentation.Domain.Entities; + +namespace Vizhtalk.CDN.Presentation.Infrastructure.EF.Configurations; + +public class MediaGroupMediaConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable(nameof(MediaGroupMedia)); + builder.HasKey(x => x.Id); + builder.Property(x => x.Id) + .HasConversion(x => x.Value, x => new Domain.TypeIds.MediaGroupMediaId(x)); + } +} diff --git a/Vizhtalk.CDN.Presentation/Infrastructure/UnitOfWork.cs b/Vizhtalk.CDN.Presentation/Infrastructure/UnitOfWork.cs new file mode 100644 index 0000000..6e4deb0 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Infrastructure/UnitOfWork.cs @@ -0,0 +1,23 @@ +using Vizhtalk.CDN.Presentation.Application; +using Vizhtalk.CDN.Presentation.Infrastructure.EF; +using Vizhtalk.CDN.Presentation.Domain.Repositories; +using VizhTalk.BuildingBlocks.Infrastructure; +using VizhTalk.BuildingBlocks.Infrastructure.DomainEventsDispatching; + +namespace Vizhtalk.CDN.Presentation.Infrastructure +{ + public class UnitOfWork(CDNDbContext cdnDbContext, IDomainEventsDispatcher domainEventsDispatcher) + : UnitOfWorkBase(cdnDbContext, domainEventsDispatcher) + { + public IMediaRepository Media => throw new NotImplementedException(); + + public IClientRepository Client => throw new NotImplementedException(); + + public IMediaClientRepository MediaClient => throw new NotImplementedException(); + + public IMediaGroupRepository MediaGroup => throw new NotImplementedException(); + + public IMediaGroupMediaRepository MediaGroupMedia => throw new NotImplementedException(); + + } +} diff --git a/Vizhtalk.CDN.Presentation/Program.cs b/Vizhtalk.CDN.Presentation/Program.cs index 3c95eda..f2048f4 100644 --- a/Vizhtalk.CDN.Presentation/Program.cs +++ b/Vizhtalk.CDN.Presentation/Program.cs @@ -1,13 +1,23 @@ +using MongoDB.Driver.Core.Configuration; +using Vizhtalk.CDN.Presentation.Infrastructure; using Vizhtalk.CDN.Presentation.Services; var builder = WebApplication.CreateBuilder(args); +var connectionString = builder.Configuration.GetConnectionString("VizhTalk.CDN")!; + + +builder.Services.Initialize(connectionString); builder.Services.AddGrpc(); + var app = builder.Build(); + + app.MapGet("/", () => "Hello World!"); app.MapGrpcService(); +app.UseCDNModule(); app.Run(); diff --git a/Vizhtalk.CDN.Presentation/TypeIds/ClientId.cs b/Vizhtalk.CDN.Presentation/TypeIds/ClientId.cs deleted file mode 100644 index 332c195..0000000 --- a/Vizhtalk.CDN.Presentation/TypeIds/ClientId.cs +++ /dev/null @@ -1,11 +0,0 @@ -using VizhTalk.BuildingBlocks.Domain; - -namespace Vizhtalk.CDN.Presentation.TypeIds -{ - public class ClientId : TypedIdValueBase - { - public ClientId(string value) : base(value) - { - } - } -} diff --git a/Vizhtalk.CDN.Presentation/TypeIds/MediaClientId.cs b/Vizhtalk.CDN.Presentation/TypeIds/MediaClientId.cs deleted file mode 100644 index 84f1fce..0000000 --- a/Vizhtalk.CDN.Presentation/TypeIds/MediaClientId.cs +++ /dev/null @@ -1,11 +0,0 @@ -using VizhTalk.BuildingBlocks.Domain; - -namespace Vizhtalk.CDN.Presentation.TypeIds -{ - public class MediaClientId : TypedIdValueBase - { - public MediaClientId(long value) : base(value) - { - } - } -} diff --git a/Vizhtalk.CDN.Presentation/TypeIds/MediaGroupId.cs b/Vizhtalk.CDN.Presentation/TypeIds/MediaGroupId.cs deleted file mode 100644 index a64914e..0000000 --- a/Vizhtalk.CDN.Presentation/TypeIds/MediaGroupId.cs +++ /dev/null @@ -1,11 +0,0 @@ -using VizhTalk.BuildingBlocks.Domain; - -namespace Vizhtalk.CDN.Presentation.TypeIds -{ - public class MediaGroupId : TypedIdValueBase - { - public MediaGroupId(long value) : base(value) - { - } - } -} diff --git a/Vizhtalk.CDN.Presentation/TypeIds/MediaGroupMediaId.cs b/Vizhtalk.CDN.Presentation/TypeIds/MediaGroupMediaId.cs deleted file mode 100644 index 5ed43ec..0000000 --- a/Vizhtalk.CDN.Presentation/TypeIds/MediaGroupMediaId.cs +++ /dev/null @@ -1,11 +0,0 @@ -using VizhTalk.BuildingBlocks.Domain; - -namespace Vizhtalk.CDN.Presentation.TypeIds -{ - public class MediaGroupMediaId : TypedIdValueBase - { - public MediaGroupMediaId(Guid value) : base(value) - { - } - } -} diff --git a/Vizhtalk.CDN.Presentation/TypeIds/MediaId.cs b/Vizhtalk.CDN.Presentation/TypeIds/MediaId.cs deleted file mode 100644 index 5e4e85a..0000000 --- a/Vizhtalk.CDN.Presentation/TypeIds/MediaId.cs +++ /dev/null @@ -1,11 +0,0 @@ -using VizhTalk.BuildingBlocks.Domain; - -namespace Vizhtalk.CDN.Presentation.TypeIds -{ - public class MediaId : TypedIdValueBase - { - public MediaId(long value) : base(value) - { - } - } -} diff --git a/Vizhtalk.CDN.Presentation/ValueObjects/ContentType.cs b/Vizhtalk.CDN.Presentation/ValueObjects/ContentType.cs deleted file mode 100644 index 16a7ac4..0000000 --- a/Vizhtalk.CDN.Presentation/ValueObjects/ContentType.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Vizhtalk.CDN.Presentation.ValueObjects.Rules; -using VizhTalk.BuildingBlocks.Domain; - -namespace Vizhtalk.CDN.Presentation.ValueObjects -{ - public class ContentType : ValueObject - { - public ContentType(string contentType, byte[] fileBytes) - { - CheckRule(new ValidContentTypeRule(contentType, fileBytes)); - - Value = contentType; - } - public string Value { get; set; } - } -} diff --git a/Vizhtalk.CDN.Presentation/Vizhtalk.CDN.Presentation.csproj b/Vizhtalk.CDN.Presentation/Vizhtalk.CDN.Presentation.csproj index 789b51e..0dd4562 100644 --- a/Vizhtalk.CDN.Presentation/Vizhtalk.CDN.Presentation.csproj +++ b/Vizhtalk.CDN.Presentation/Vizhtalk.CDN.Presentation.csproj @@ -8,13 +8,18 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + - - + + diff --git a/Vizhtalk.CDN.Presentation/appsettings.json b/Vizhtalk.CDN.Presentation/appsettings.json index 5844145..77f87d0 100644 --- a/Vizhtalk.CDN.Presentation/appsettings.json +++ b/Vizhtalk.CDN.Presentation/appsettings.json @@ -6,7 +6,7 @@ } }, "ConnectionStrings": { - "VizhTalk.CDN": "mongodb://localhost:27017/VizhTalk.CDN" + "VizhTalk.CDN": "mongodb://localhost:27017/VizhTalk_CDN" }, "AllowedHosts": "*" } From 80920e69abcede2903dd6221e4a79fc46d63536c Mon Sep 17 00:00:00 2001 From: pns-hassanzadeh Date: Sat, 6 Sep 2025 21:51:16 +0330 Subject: [PATCH 2/4] AplictionCDN --- .../CommandHandlers/MediaCommandHandler.cs | 25 ++++++++ .../MediaGroupKeyAlreadyExistsException.cs | 13 ++++ .../Exceptions/MediaNotFoundException.cs | 13 ++++ .../UnauthorizedForMediaException.cs | 13 ++++ .../Application/ICDNModule.cs | 5 ++ .../Application/IUnitOfWork.cs | 2 +- .../QueryHandlers/MediaQueryHandler.cs | 5 ++ .../Controllers/FileController.cs | 2 +- .../Domain/Entities/Client.cs | 3 +- .../Domain/Entities/Media.cs | 3 +- .../Domain/Entities/MediaClient.cs | 12 ++-- .../Domain/Entities/MediaGroup.cs | 15 ++++- .../Domain/Entities/MediaGroupMedia.cs | 5 +- .../Domain/TypeIds/ClientId.cs | 2 +- .../Domain/TypeIds/MediaClientId.cs | 2 +- .../Domain/TypeIds/MediaGroupId.cs | 2 +- .../Domain/TypeIds/MediaGroupMediaId.cs | 2 +- .../Domain/TypeIds/MediaId.cs | 2 +- .../Domain/ValueObjects/ContentType.cs | 6 +- .../Infrastructure/CDNStartup.cs | 17 ++---- .../Infrastructure/Configuration/CDNModule.cs | 61 +++++++++++++++++++ .../EF/Configurations/ClientConfiguration.cs | 3 + .../MediaClientConfiguration.cs | 19 ++++++ .../EF/Configurations/MediaConfiguration.cs | 13 +++- .../Configurations/MediaGroupConfiguration.cs | 4 ++ .../MediaGroupMediaConfiguration.cs | 16 +++++ Vizhtalk.CDN.Presentation/Program.cs | 6 +- .../Vizhtalk.CDN.Presentation.csproj | 3 +- Vizhtalk.CDN.Presentation/appsettings.json | 7 ++- 29 files changed, 244 insertions(+), 37 deletions(-) create mode 100644 Vizhtalk.CDN.Presentation/Application/CommandHandlers/MediaCommandHandler.cs create mode 100644 Vizhtalk.CDN.Presentation/Application/Exceptions/MediaGroupKeyAlreadyExistsException.cs create mode 100644 Vizhtalk.CDN.Presentation/Application/Exceptions/MediaNotFoundException.cs create mode 100644 Vizhtalk.CDN.Presentation/Application/Exceptions/UnauthorizedForMediaException.cs create mode 100644 Vizhtalk.CDN.Presentation/Application/ICDNModule.cs create mode 100644 Vizhtalk.CDN.Presentation/Application/QueryHandlers/MediaQueryHandler.cs create mode 100644 Vizhtalk.CDN.Presentation/Infrastructure/Configuration/CDNModule.cs diff --git a/Vizhtalk.CDN.Presentation/Application/CommandHandlers/MediaCommandHandler.cs b/Vizhtalk.CDN.Presentation/Application/CommandHandlers/MediaCommandHandler.cs new file mode 100644 index 0000000..e83a9b7 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Application/CommandHandlers/MediaCommandHandler.cs @@ -0,0 +1,25 @@ +using Mapster; +using Vizhtalk.CDN.Presentation.Application.Exceptions; +using Vizhtalk.CDN.Presentation.Domain.Entities; +using VizhTalk.BuildingBlocks.Application.Configuration.Commnad; +using VizhTalk.Grpc.CDN; + +namespace Vizhtalk.CDN.Presentation.Application.CommandHandlers; + +public class CreateMediaGroupCommandHandler(IUnitOfWork unitOfWork, CDNGrpc.CDNGrpcClient cdnClient) : ICommandHandler +{ + public async Task Handle(CreateMediaGroupCommand request, CancellationToken cancellationToken) + { + var title = request.Title.Trim(); + + if (await unitOfWork.MediaGroup.Exists(a => a.Key == request.Key)) + throw new MediaGroupKeyAlreadyExistsException(); + + + var mediaGroup = MediaGroup.CreateNew(title,request.Key,request.IsSecure); + await unitOfWork.MediaGroup.AddAsync(mediaGroup, cancellationToken); + await unitOfWork.SaveChangeAsync(cancellationToken); + return mediaGroup.Adapt(); + + } +} diff --git a/Vizhtalk.CDN.Presentation/Application/Exceptions/MediaGroupKeyAlreadyExistsException.cs b/Vizhtalk.CDN.Presentation/Application/Exceptions/MediaGroupKeyAlreadyExistsException.cs new file mode 100644 index 0000000..59e1f7c --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Application/Exceptions/MediaGroupKeyAlreadyExistsException.cs @@ -0,0 +1,13 @@ +using VizhTalk.BuildingBlocks.Application.Exceptions; + +namespace Vizhtalk.CDN.Presentation.Application.Exceptions; + +public class MediaGroupKeyAlreadyExistsException : BaseException +{ + + public MediaGroupKeyAlreadyExistsException() : base("Media groupKey already exists") + { + + } + +} diff --git a/Vizhtalk.CDN.Presentation/Application/Exceptions/MediaNotFoundException.cs b/Vizhtalk.CDN.Presentation/Application/Exceptions/MediaNotFoundException.cs new file mode 100644 index 0000000..16f417e --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Application/Exceptions/MediaNotFoundException.cs @@ -0,0 +1,13 @@ +using VizhTalk.BuildingBlocks.Application.Exceptions; + +namespace Vizhtalk.CDN.Presentation.Application.Exceptions; + +public class MediaNotFoundException : BaseException +{ + + public MediaNotFoundException() : base("Media not found") + { + + } + +} diff --git a/Vizhtalk.CDN.Presentation/Application/Exceptions/UnauthorizedForMediaException.cs b/Vizhtalk.CDN.Presentation/Application/Exceptions/UnauthorizedForMediaException.cs new file mode 100644 index 0000000..4b3bc34 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Application/Exceptions/UnauthorizedForMediaException.cs @@ -0,0 +1,13 @@ +using VizhTalk.BuildingBlocks.Application.Exceptions; + +namespace Vizhtalk.CDN.Presentation.Application.Exceptions; + +public class UnauthorizedForMediaException : BaseException +{ + + public UnauthorizedForMediaException() : base("Unauthorized for media") + { + + } + +} diff --git a/Vizhtalk.CDN.Presentation/Application/ICDNModule.cs b/Vizhtalk.CDN.Presentation/Application/ICDNModule.cs new file mode 100644 index 0000000..da032cd --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Application/ICDNModule.cs @@ -0,0 +1,5 @@ +using VizhTalk.BuildingBlocks.Application; + +namespace Vizhtalk.CDN.Presentation.Application; + +public interface ICDNModule : IExecutor; diff --git a/Vizhtalk.CDN.Presentation/Application/IUnitOfWork.cs b/Vizhtalk.CDN.Presentation/Application/IUnitOfWork.cs index 90312a6..c74b24e 100644 --- a/Vizhtalk.CDN.Presentation/Application/IUnitOfWork.cs +++ b/Vizhtalk.CDN.Presentation/Application/IUnitOfWork.cs @@ -3,7 +3,7 @@ using VizhTalk.BuildingBlocks.Application; namespace Vizhtalk.CDN.Presentation.Application { - internal interface IUnitOfWork : IUnitOfWorkBase + public interface IUnitOfWork : IUnitOfWorkBase { IMediaRepository Media { get; } IClientRepository Client { get; } diff --git a/Vizhtalk.CDN.Presentation/Application/QueryHandlers/MediaQueryHandler.cs b/Vizhtalk.CDN.Presentation/Application/QueryHandlers/MediaQueryHandler.cs new file mode 100644 index 0000000..032d38b --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Application/QueryHandlers/MediaQueryHandler.cs @@ -0,0 +1,5 @@ +namespace Vizhtalk.CDN.Presentation.Application.QueryHandlers; + +public class MediaQueryHandler +{ +} diff --git a/Vizhtalk.CDN.Presentation/Controllers/FileController.cs b/Vizhtalk.CDN.Presentation/Controllers/FileController.cs index 525c01b..3b53e83 100644 --- a/Vizhtalk.CDN.Presentation/Controllers/FileController.cs +++ b/Vizhtalk.CDN.Presentation/Controllers/FileController.cs @@ -12,7 +12,7 @@ namespace Vizhtalk.CDN.Presentation.Controllers public IActionResult Get(MediaGroupMediaId id) { - + return Unauthorized(); } diff --git a/Vizhtalk.CDN.Presentation/Domain/Entities/Client.cs b/Vizhtalk.CDN.Presentation/Domain/Entities/Client.cs index 872c254..67fce33 100644 --- a/Vizhtalk.CDN.Presentation/Domain/Entities/Client.cs +++ b/Vizhtalk.CDN.Presentation/Domain/Entities/Client.cs @@ -5,5 +5,6 @@ namespace Vizhtalk.CDN.Presentation.Domain.Entities; public class Client : Entity { - + private List _mediaClients = new(); + public IReadOnlyList MediaClients => _mediaClients; } diff --git a/Vizhtalk.CDN.Presentation/Domain/Entities/Media.cs b/Vizhtalk.CDN.Presentation/Domain/Entities/Media.cs index 78250c1..1f23e1a 100644 --- a/Vizhtalk.CDN.Presentation/Domain/Entities/Media.cs +++ b/Vizhtalk.CDN.Presentation/Domain/Entities/Media.cs @@ -6,9 +6,10 @@ namespace Vizhtalk.CDN.Presentation.Domain.Entities; public class Media : Entity { + private List _mediaGroupMedia = new(); public ContentType ContentType { get; private set; } public int Size { get; set; } public string Path { get; private set; } public string Hash { get; set; } - public List MediaGroupMedias { get; set; } + public IReadOnlyList MediaGroupMedias => _mediaGroupMedia; } diff --git a/Vizhtalk.CDN.Presentation/Domain/Entities/MediaClient.cs b/Vizhtalk.CDN.Presentation/Domain/Entities/MediaClient.cs index 911c975..8b7cb77 100644 --- a/Vizhtalk.CDN.Presentation/Domain/Entities/MediaClient.cs +++ b/Vizhtalk.CDN.Presentation/Domain/Entities/MediaClient.cs @@ -6,8 +6,12 @@ namespace Vizhtalk.CDN.Presentation.Domain.Entities; public class MediaClient : Entity { - public MediaClientName Name { get; set; } - public MediaId MediaId { get; set; } - public ClientId ClientId { get; set; } - public MediaGroupMediaId MediaGroup { get; set; } + public MediaClientName Name { get; private set; } + public MediaId MediaId { get; private set; } + public ClientId ClientId { get; private set; } + public MediaGroupMediaId MediaGroupMediaId { get; set; } + + public Client Client { get; private set; } + public Media Media { get; private set; } + public MediaGroupMedia MediaGroupMedia { get; private set; } } diff --git a/Vizhtalk.CDN.Presentation/Domain/Entities/MediaGroup.cs b/Vizhtalk.CDN.Presentation/Domain/Entities/MediaGroup.cs index f52184b..592e4f4 100644 --- a/Vizhtalk.CDN.Presentation/Domain/Entities/MediaGroup.cs +++ b/Vizhtalk.CDN.Presentation/Domain/Entities/MediaGroup.cs @@ -6,8 +6,21 @@ namespace Vizhtalk.CDN.Presentation.Domain.Entities; public class MediaGroup : Entity { + + private MediaGroup(MediaGroupTitle title, string key, bool isSecure) + { + Title = title; + Key = key; + IsSecure = isSecure; + } + + private List _mediaGroupMedia = new(); public bool IsSecure { get; set; } public MediaGroupTitle Title { get; set; } public string Key { get; set; } - public List MediaGroupMedias { get; set; } + public IReadOnlyList MediaGroupMedias => _mediaGroupMedia; + + public static MediaGroup CreateNew(string title, string Key, bool isSecure) + => new (new MediaGroupTitle(title), Key, isSecure); + } diff --git a/Vizhtalk.CDN.Presentation/Domain/Entities/MediaGroupMedia.cs b/Vizhtalk.CDN.Presentation/Domain/Entities/MediaGroupMedia.cs index 14859b5..6cbd2cb 100644 --- a/Vizhtalk.CDN.Presentation/Domain/Entities/MediaGroupMedia.cs +++ b/Vizhtalk.CDN.Presentation/Domain/Entities/MediaGroupMedia.cs @@ -5,7 +5,10 @@ namespace Vizhtalk.CDN.Presentation.Domain.Entities; public class MediaGroupMedia : Entity { + private List _mediaClient = new(); public MediaId MediaId { get; set; } public MediaGroupId MediaGroupId { get; set; } - public List MediaClients { get; set; } + public Media Media { get; set; } + public MediaGroup MediaGroup { get; set; } + public IReadOnlyList MediaClients => _mediaClient; } diff --git a/Vizhtalk.CDN.Presentation/Domain/TypeIds/ClientId.cs b/Vizhtalk.CDN.Presentation/Domain/TypeIds/ClientId.cs index db83b70..dba604f 100644 --- a/Vizhtalk.CDN.Presentation/Domain/TypeIds/ClientId.cs +++ b/Vizhtalk.CDN.Presentation/Domain/TypeIds/ClientId.cs @@ -2,7 +2,7 @@ namespace Vizhtalk.CDN.Presentation.Domain.TypeIds; -public class ClientId : TypedIdValueBase +public class ClientId : TypeIdValueBase { public ClientId(string value) : base(value) { diff --git a/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaClientId.cs b/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaClientId.cs index 110be1b..e63848b 100644 --- a/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaClientId.cs +++ b/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaClientId.cs @@ -2,7 +2,7 @@ namespace Vizhtalk.CDN.Presentation.Domain.TypeIds; -public class MediaClientId : TypedIdValueBase +public class MediaClientId : TypeIdValueBase { public MediaClientId(long value) : base(value) { diff --git a/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaGroupId.cs b/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaGroupId.cs index 75f5100..6ffeab7 100644 --- a/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaGroupId.cs +++ b/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaGroupId.cs @@ -2,7 +2,7 @@ namespace Vizhtalk.CDN.Presentation.Domain.TypeIds; -public class MediaGroupId : TypedIdValueBase +public class MediaGroupId : TypeIdValueBase { public MediaGroupId(long value) : base(value) { diff --git a/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaGroupMediaId.cs b/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaGroupMediaId.cs index adcd676..c693547 100644 --- a/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaGroupMediaId.cs +++ b/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaGroupMediaId.cs @@ -2,7 +2,7 @@ namespace Vizhtalk.CDN.Presentation.Domain.TypeIds; -public class MediaGroupMediaId : TypedIdValueBase +public class MediaGroupMediaId : TypeIdValueBase { public MediaGroupMediaId(Guid value) : base(value) { diff --git a/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaId.cs b/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaId.cs index 40fd700..5a0d08e 100644 --- a/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaId.cs +++ b/Vizhtalk.CDN.Presentation/Domain/TypeIds/MediaId.cs @@ -2,7 +2,7 @@ namespace Vizhtalk.CDN.Presentation.Domain.TypeIds; -public class MediaId : TypedIdValueBase +public class MediaId : TypeIdValueBase { public MediaId(long value) : base(value) { diff --git a/Vizhtalk.CDN.Presentation/Domain/ValueObjects/ContentType.cs b/Vizhtalk.CDN.Presentation/Domain/ValueObjects/ContentType.cs index f2d136c..556e6f1 100644 --- a/Vizhtalk.CDN.Presentation/Domain/ValueObjects/ContentType.cs +++ b/Vizhtalk.CDN.Presentation/Domain/ValueObjects/ContentType.cs @@ -5,11 +5,15 @@ namespace Vizhtalk.CDN.Presentation.Domain.ValueObjects; public class ContentType : ValueObject { + private ContentType() + { + + } public ContentType(string contentType, byte[] fileBytes) { CheckRule(new ValidContentTypeRule(contentType, fileBytes)); Value = contentType; } - public string Value { get; set; } + public string Value { get; private set; } } diff --git a/Vizhtalk.CDN.Presentation/Infrastructure/CDNStartup.cs b/Vizhtalk.CDN.Presentation/Infrastructure/CDNStartup.cs index cea0495..9fd7408 100644 --- a/Vizhtalk.CDN.Presentation/Infrastructure/CDNStartup.cs +++ b/Vizhtalk.CDN.Presentation/Infrastructure/CDNStartup.cs @@ -16,23 +16,16 @@ namespace Vizhtalk.CDN.Presentation.Infrastructure; public static class CDNStartup { - public static void Initialize(this IServiceCollection services, string connectionString) + public static void Initialize(this IServiceCollection services, string connectionString, string databaseName) { - var domainNotificationsMap = new BiDictionary(); - - services.AddDbContext(op => + services.AddDbContext(options => { - op.UseMongoDB(connectionString); + options.UseMongoDB(connectionString, databaseName); }); + services.AddScoped(sp => sp.GetService()); + } - - public static void UseCDNModule(this IApplicationBuilder app) - { - using var scope = app.ApplicationServices.CreateScope(); - var db = scope.ServiceProvider.GetRequiredService(); - db.Database.Migrate(); - } } \ No newline at end of file diff --git a/Vizhtalk.CDN.Presentation/Infrastructure/Configuration/CDNModule.cs b/Vizhtalk.CDN.Presentation/Infrastructure/Configuration/CDNModule.cs new file mode 100644 index 0000000..3dd7795 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Infrastructure/Configuration/CDNModule.cs @@ -0,0 +1,61 @@ +using Vizhtalk.CDN.Presentation.Application; +using VizhTalk.BuildingBlocks.Application.Configuration.Commnad; +using VizhTalk.BuildingBlocks.Application.Configuration.Query; +using VizhTalk.BuildingBlocks.Application.Contract; +using VizhTalk.BuildingBlocks.Domain; +using VizhTalk.BuildingBlocks.Domain.Contract; + +namespace Vizhtalk.CDN.Presentation.Infrastructure.Configuration; + +public class CDNModule(IServiceProvider serviceProvider) : ICDNModule +{ + public async Task Execute(ICommand command, CancellationToken cancellationToken = default) + { + var handlerType = typeof(ICommandHandler<>).MakeGenericType(command.GetType()); + var handler = serviceProvider.GetRequiredService(handlerType); + dynamic dynamicHandler = handler; + dynamic dynamicCommand = command; + await dynamicHandler.Handle(dynamicCommand, cancellationToken); + } + + public async Task Execute(ICommand command, CancellationToken cancellationToken = default) + { + var commandType = command.GetType(); // مثلا CreateUserCommand + var resultType = commandType.GetInterface(typeof(ICommand<>).Name)!.GetGenericArguments()[0]; + + // حالا handlerType میشه: + var handlerType = typeof(ICommandHandler<,>).MakeGenericType(commandType, resultType); + + var handler = serviceProvider.GetRequiredService(handlerType); + + dynamic dynamicHandler = handler; + dynamic dynamicCommand = command; + + return await dynamicHandler.Handle(dynamicCommand, cancellationToken); + } + + public async Task Execute(IQuery query, CancellationToken cancellationToken = default) + { + var queryType = query.GetType(); + var resultType = queryType.GetInterface(typeof(IQuery<>).Name)!.GetGenericArguments()[0]; + + // حالا handlerType میشه: + var handlerType = typeof(IQueryHandler<,>).MakeGenericType(queryType, resultType); + + var handler = serviceProvider.GetRequiredService(handlerType); + + dynamic dynamicHandler = handler; + dynamic dynamicQuery = query; + + return await dynamicHandler.Handle(dynamicQuery, cancellationToken); + } + + public async Task Execute(IDomainEvent notification, CancellationToken cancellationToken = default) + { + var handlerType = typeof(INotificationHandler<>).MakeGenericType(notification.GetType()); + var handler = serviceProvider.GetRequiredService(handlerType); + dynamic dynamicHandler = handler; + dynamic dynamicNotification = notification; + await dynamicHandler.Handle(dynamicNotification, cancellationToken); + } +} diff --git a/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/ClientConfiguration.cs b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/ClientConfiguration.cs index b066548..5758c5c 100644 --- a/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/ClientConfiguration.cs +++ b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/ClientConfiguration.cs @@ -13,5 +13,8 @@ public class ClientConfiguration : IEntityTypeConfiguration builder.Property(x => x.Id) .HasConversion(x => x.Value, x => new Domain.TypeIds.ClientId(x)); + + builder.Metadata.FindNavigation(nameof(Client.MediaClients))? + .SetPropertyAccessMode(PropertyAccessMode.Property); } } diff --git a/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaClientConfiguration.cs b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaClientConfiguration.cs index 4b99f32..74a8afc 100644 --- a/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaClientConfiguration.cs +++ b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaClientConfiguration.cs @@ -13,5 +13,24 @@ public class MediaClientConfiguration : IEntityTypeConfiguration builder.Property(x => x.Id) .HasConversion(x => x.Value, x => new Domain.TypeIds.MediaClientId(x)); + + builder.Property(x => x.Name) + .HasConversion(x => x.Value, x => new Domain.ValueObjects.MediaClientName(x)); + + builder.Property(x => x.ClientId) + .HasConversion(x => x.Value, x => new Domain.TypeIds.ClientId(x)); + + builder.Property(x => x.MediaGroupMediaId) + .HasConversion(x => x.Value, x => new Domain.TypeIds.MediaGroupMediaId(x)); + + builder.Property(x => x.MediaId) + .HasConversion(x => x.Value, x => new Domain.TypeIds.MediaId(x)); + + builder.Metadata.FindNavigation(nameof(MediaClient.Media))? + .SetPropertyAccessMode(PropertyAccessMode.Property); + builder.Metadata.FindNavigation(nameof(MediaClient.Client))? + .SetPropertyAccessMode(PropertyAccessMode.Property); + builder.Metadata.FindNavigation(nameof(MediaClient.MediaGroupMedia))? + .SetPropertyAccessMode(PropertyAccessMode.Property); } } diff --git a/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaConfiguration.cs b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaConfiguration.cs index e4150ff..aa68014 100644 --- a/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaConfiguration.cs +++ b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaConfiguration.cs @@ -11,9 +11,20 @@ public class MediaConfiguration : IEntityTypeConfiguration builder.ToTable(nameof(Media)); builder.HasKey(x => x.Id); builder.Property(x => x.Id) + .HasColumnName("MediaId") + .HasElementName("_id") .HasConversion(x => x.Value, x => new Domain.TypeIds.MediaId(x)); - builder.HasIndex(x => x.Hash); + builder.OwnsOne(x => x.ContentType, op => + { + op.Property(x => x.Value) + .HasColumnName("ContentType") + .HasMaxLength(50); + }); + builder.HasIndex(x => x.Hash); + + builder.Metadata.FindNavigation(nameof(Media.MediaGroupMedias))? + .SetPropertyAccessMode(PropertyAccessMode.Property); } } diff --git a/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaGroupConfiguration.cs b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaGroupConfiguration.cs index 70bece1..2465d59 100644 --- a/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaGroupConfiguration.cs +++ b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaGroupConfiguration.cs @@ -12,5 +12,9 @@ public class MediaGroupConfiguration : IEntityTypeConfiguration builder.HasKey(x => x.Id); builder.Property(x => x.Id) .HasConversion(x => x.Value, x => new Domain.TypeIds.MediaGroupId(x)); + + builder.Metadata.FindNavigation(nameof(MediaGroup.MediaGroupMedias))? + .SetPropertyAccessMode(PropertyAccessMode.Property); + } } diff --git a/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaGroupMediaConfiguration.cs b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaGroupMediaConfiguration.cs index 2061c75..b3f9082 100644 --- a/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaGroupMediaConfiguration.cs +++ b/Vizhtalk.CDN.Presentation/Infrastructure/EF/Configurations/MediaGroupMediaConfiguration.cs @@ -12,5 +12,21 @@ public class MediaGroupMediaConfiguration : IEntityTypeConfiguration x.Id); builder.Property(x => x.Id) .HasConversion(x => x.Value, x => new Domain.TypeIds.MediaGroupMediaId(x)); + + builder.Property(x => x.MediaId) + .HasConversion(x => x.Value, x => new Domain.TypeIds.MediaId(x)); + + builder.Property(x => x.MediaGroupId) + .HasConversion(x => x.Value, x => new Domain.TypeIds.MediaGroupId(x)); + + builder.Metadata.FindNavigation(nameof(MediaGroupMedia.Media))? + .SetPropertyAccessMode(PropertyAccessMode.Property); + + builder.Metadata.FindNavigation(nameof(MediaGroupMedia.MediaGroup))? + .SetPropertyAccessMode(PropertyAccessMode.Property); + + + builder.Metadata.FindNavigation(nameof(MediaGroupMedia.MediaClients))? + .SetPropertyAccessMode(PropertyAccessMode.Property); } } diff --git a/Vizhtalk.CDN.Presentation/Program.cs b/Vizhtalk.CDN.Presentation/Program.cs index f2048f4..6ae1e0d 100644 --- a/Vizhtalk.CDN.Presentation/Program.cs +++ b/Vizhtalk.CDN.Presentation/Program.cs @@ -5,9 +5,9 @@ using Vizhtalk.CDN.Presentation.Services; var builder = WebApplication.CreateBuilder(args); var connectionString = builder.Configuration.GetConnectionString("VizhTalk.CDN")!; +var databaseName = builder.Configuration.GetConnectionString("VizhTalk.CDN.DatabaseName")!; - -builder.Services.Initialize(connectionString); +builder.Services.Initialize(connectionString, databaseName); builder.Services.AddGrpc(); var app = builder.Build(); @@ -18,6 +18,6 @@ app.MapGet("/", () => "Hello World!"); app.MapGrpcService(); -app.UseCDNModule(); +//app.UseCDNModule(); app.Run(); diff --git a/Vizhtalk.CDN.Presentation/Vizhtalk.CDN.Presentation.csproj b/Vizhtalk.CDN.Presentation/Vizhtalk.CDN.Presentation.csproj index 0dd4562..da1dfff 100644 --- a/Vizhtalk.CDN.Presentation/Vizhtalk.CDN.Presentation.csproj +++ b/Vizhtalk.CDN.Presentation/Vizhtalk.CDN.Presentation.csproj @@ -18,8 +18,7 @@ - - + diff --git a/Vizhtalk.CDN.Presentation/appsettings.json b/Vizhtalk.CDN.Presentation/appsettings.json index 77f87d0..0eff2bd 100644 --- a/Vizhtalk.CDN.Presentation/appsettings.json +++ b/Vizhtalk.CDN.Presentation/appsettings.json @@ -5,8 +5,9 @@ "Microsoft.AspNetCore": "Warning" } }, - "ConnectionStrings": { - "VizhTalk.CDN": "mongodb://localhost:27017/VizhTalk_CDN" - }, + "ConnectionStrings": { + "VizhTalk.CDN": "mongodb://localhost:27017", + "VizhTalk.CDN.DatabaseName": "VizhTalk.CDN" + }, "AllowedHosts": "*" } From ef7722cce41f454f375392fd36ce8965a8ce360e Mon Sep 17 00:00:00 2001 From: pns-hassanzadeh Date: Sat, 6 Sep 2025 22:03:06 +0330 Subject: [PATCH 3/4] UplodFile --- .../CommandHandlers/MediaCommandHandler.cs | 11 ++++++++- .../Application/Mappers/MapperConfig.cs | 23 +++++++++++++++++++ .../Services/CDNService.cs | 11 +++++---- .../Vizhtalk.CDN.Presentation.csproj | 4 ---- 4 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 Vizhtalk.CDN.Presentation/Application/Mappers/MapperConfig.cs diff --git a/Vizhtalk.CDN.Presentation/Application/CommandHandlers/MediaCommandHandler.cs b/Vizhtalk.CDN.Presentation/Application/CommandHandlers/MediaCommandHandler.cs index e83a9b7..9f29737 100644 --- a/Vizhtalk.CDN.Presentation/Application/CommandHandlers/MediaCommandHandler.cs +++ b/Vizhtalk.CDN.Presentation/Application/CommandHandlers/MediaCommandHandler.cs @@ -1,4 +1,5 @@ -using Mapster; +using Grpc.Core; +using Mapster; using Vizhtalk.CDN.Presentation.Application.Exceptions; using Vizhtalk.CDN.Presentation.Domain.Entities; using VizhTalk.BuildingBlocks.Application.Configuration.Commnad; @@ -23,3 +24,11 @@ public class CreateMediaGroupCommandHandler(IUnitOfWork unitOfWork, CDNGrpc.CDNG } } + +public class UploadFileCommandHandler(IUnitOfWork unitOfWork, CDNGrpc.CDNGrpcClient cdnClient) : ICommandHandler +{ + public Task Handle(UploadFileCommand request, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/Vizhtalk.CDN.Presentation/Application/Mappers/MapperConfig.cs b/Vizhtalk.CDN.Presentation/Application/Mappers/MapperConfig.cs new file mode 100644 index 0000000..04c95c7 --- /dev/null +++ b/Vizhtalk.CDN.Presentation/Application/Mappers/MapperConfig.cs @@ -0,0 +1,23 @@ +using Mapster; +using Vizhtalk.CDN.Presentation.Domain.Entities; +using VizhTalk.Grpc.CDN; + +namespace Vizhtalk.CDN.Presentation.Application.Mappers; + +public class MapperConfig +{ + + public static void Process() + { + + var config = TypeAdapterConfig.NewConfig() + .MapWith(lan => new MediaGroupDTO() + { + Id = lan.Id.Value + }); + + + config.Compile(); + } + +} diff --git a/Vizhtalk.CDN.Presentation/Services/CDNService.cs b/Vizhtalk.CDN.Presentation/Services/CDNService.cs index 859be08..10a5bb8 100644 --- a/Vizhtalk.CDN.Presentation/Services/CDNService.cs +++ b/Vizhtalk.CDN.Presentation/Services/CDNService.cs @@ -1,16 +1,17 @@ using Grpc.Core; +using Vizhtalk.CDN.Presentation.Application; using VizhTalk.Grpc.CDN; namespace Vizhtalk.CDN.Presentation.Services; -public class CDNService : CDNGrpc.CDNGrpcBase +public class CDNService(ICDNModule cDNModule) : CDNGrpc.CDNGrpcBase { - public override Task CreateMediaGroup(CreateMediaGroupCommand request, ServerCallContext context) + public override async Task CreateMediaGroup(CreateMediaGroupCommand request, ServerCallContext context) { - return base.CreateMediaGroup(request, context); + return await cDNModule.Execute(request, context.CancellationToken); } - public override Task UploadFile(UploadFileCommand request, ServerCallContext context) + public override async Task UploadFile(UploadFileCommand request, ServerCallContext context) { - return base.UploadFile(request, context); + return await cDNModule.Execute(request, context.CancellationToken); } } diff --git a/Vizhtalk.CDN.Presentation/Vizhtalk.CDN.Presentation.csproj b/Vizhtalk.CDN.Presentation/Vizhtalk.CDN.Presentation.csproj index da1dfff..b2f8fe4 100644 --- a/Vizhtalk.CDN.Presentation/Vizhtalk.CDN.Presentation.csproj +++ b/Vizhtalk.CDN.Presentation/Vizhtalk.CDN.Presentation.csproj @@ -17,8 +17,4 @@ - - - - From 2b3e4d3263872af0fe4d252423568ae2b33fbb79 Mon Sep 17 00:00:00 2001 From: pns-hassanzadeh Date: Sun, 7 Sep 2025 22:47:57 +0330 Subject: [PATCH 4/4] UplodFile --- .../IRepositoryBase.cs | 1 + .../RepositoryBase.cs | 3 ++ .../CommandHandlers/MediaCommandHandler.cs | 35 +++++++++++++++++-- .../Domain/Entities/Media.cs | 20 +++++++++-- 4 files changed, 55 insertions(+), 4 deletions(-) diff --git a/VizhTalk.BuildingBlocks.Domain/IRepositoryBase.cs b/VizhTalk.BuildingBlocks.Domain/IRepositoryBase.cs index 7771d3d..9da2e2e 100644 --- a/VizhTalk.BuildingBlocks.Domain/IRepositoryBase.cs +++ b/VizhTalk.BuildingBlocks.Domain/IRepositoryBase.cs @@ -11,4 +11,5 @@ public interface IRepositoryBase Task DeleteById(TId id, CancellationToken cancellationToken = default); Task GetById(TId id, CancellationToken cancellationToken = default); Task Exists(Expression> predicate, CancellationToken cancellationToken = default); + Task Get(Expression> predicate, CancellationToken cancellationToken = default); } diff --git a/VizhTalk.BuildingBlocks.Infrastructure/RepositoryBase.cs b/VizhTalk.BuildingBlocks.Infrastructure/RepositoryBase.cs index 44071af..eeb434d 100644 --- a/VizhTalk.BuildingBlocks.Infrastructure/RepositoryBase.cs +++ b/VizhTalk.BuildingBlocks.Infrastructure/RepositoryBase.cs @@ -52,6 +52,9 @@ namespace VizhTalk.BuildingBlocks.Infrastructure public async Task Exists(Expression> predicate, CancellationToken cancellationToken = default) => await _dbContext.Set().Where(predicate).AnyAsync(cancellationToken); + public async Task Get(Expression> predicate, CancellationToken cancellationToken = default) + => await _dbContext.Set().Where(predicate).FirstOrDefaultAsync(predicate, cancellationToken); + public async Task GetById(TId id, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); diff --git a/Vizhtalk.CDN.Presentation/Application/CommandHandlers/MediaCommandHandler.cs b/Vizhtalk.CDN.Presentation/Application/CommandHandlers/MediaCommandHandler.cs index 9f29737..375d0e2 100644 --- a/Vizhtalk.CDN.Presentation/Application/CommandHandlers/MediaCommandHandler.cs +++ b/Vizhtalk.CDN.Presentation/Application/CommandHandlers/MediaCommandHandler.cs @@ -1,9 +1,13 @@ -using Grpc.Core; +using System.Security.Cryptography; +using Grpc.Core; using Mapster; +using Microsoft.AspNetCore.StaticFiles; using Vizhtalk.CDN.Presentation.Application.Exceptions; using Vizhtalk.CDN.Presentation.Domain.Entities; +using Vizhtalk.CDN.Presentation.Domain.ValueObjects; using VizhTalk.BuildingBlocks.Application.Configuration.Commnad; using VizhTalk.Grpc.CDN; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace Vizhtalk.CDN.Presentation.Application.CommandHandlers; @@ -27,8 +31,35 @@ public class CreateMediaGroupCommandHandler(IUnitOfWork unitOfWork, CDNGrpc.CDNG public class UploadFileCommandHandler(IUnitOfWork unitOfWork, CDNGrpc.CDNGrpcClient cdnClient) : ICommandHandler { - public Task Handle(UploadFileCommand request, CancellationToken cancellationToken) + public async Task Handle(UploadFileCommand request, CancellationToken cancellationToken) { + + var fileBytes = request.File.ToByteArray(); + + var hash = ToSHA512Hash(fileBytes); + + var media = await unitOfWork.Media.Get(a => a.Hash == hash); + + if (media is null) + { + + using MemoryStream stream = new MemoryStream(fileBytes); + + } + throw new NotImplementedException(); } + + public string ToSHA512Hash(byte[] data) + { + if (data == null) + throw new ArgumentNullException(nameof(data)); + + using (SHA512 sha512 = SHA512.Create()) + { + byte[] hashBytes = sha512.ComputeHash(data); + return BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant(); + } + } + } \ No newline at end of file diff --git a/Vizhtalk.CDN.Presentation/Domain/Entities/Media.cs b/Vizhtalk.CDN.Presentation/Domain/Entities/Media.cs index 1f23e1a..5037b24 100644 --- a/Vizhtalk.CDN.Presentation/Domain/Entities/Media.cs +++ b/Vizhtalk.CDN.Presentation/Domain/Entities/Media.cs @@ -1,15 +1,31 @@ -using VizhTalk.BuildingBlocks.Domain; +using System.Text; using Vizhtalk.CDN.Presentation.Domain.TypeIds; using Vizhtalk.CDN.Presentation.Domain.ValueObjects; +using VizhTalk.BuildingBlocks.Domain; namespace Vizhtalk.CDN.Presentation.Domain.Entities; public class Media : Entity { + + private Media(ContentType contentType, int size , string hash , string path) + { + + ContentType = contentType; + Size = size; + Hash = hash; + Path = path; + + } + private List _mediaGroupMedia = new(); public ContentType ContentType { get; private set; } public int Size { get; set; } public string Path { get; private set; } public string Hash { get; set; } public IReadOnlyList MediaGroupMedias => _mediaGroupMedia; -} + + + public static Media Create(ContentType contentType, int size, string hash, string path) + => new (contentType, size, hash, path); +} \ No newline at end of file