This commit is contained in:
2025-09-12 14:18:08 +04:30
parent ad4c92f4c0
commit 338895a1ad
48 changed files with 361 additions and 357 deletions
@@ -14,25 +14,24 @@ using VizhTalk.Grpc.CDN;
namespace Vizhtalk.CDN.Presentation.Application.CommandHandlers;
public class CreateMediaGroupCommandHandler(IUnitOfWork unitOfWork, CDNGrpc.CDNGrpcClient cdnClient) : ICommandHandler<CreateMediaGroupCommand, MediaGroupDTO>
public class CreateMediaGroupCommandHandler(IUnitOfWork unitOfWork) : ICommandHandler<CreateMediaGroupCommand, MediaGroupDTO>
{
public async Task<MediaGroupDTO> Handle(CreateMediaGroupCommand request, CancellationToken cancellationToken)
{
var title = request.Title.Trim();
if (await unitOfWork.MediaGroup.ExistsAsync(a => a.Key == request.Key))
throw new MediaGroupKeyAlreadyExistsException();
var mediaGroup = await unitOfWork.MediaGroup.GetAsync(a => a.Key == request.Key);
if (mediaGroup != null)
return mediaGroup.Adapt<MediaGroupDTO>();
var mediaGroup = MediaGroup.CreateNew(title, request.Key, request.IsSecure);
mediaGroup = MediaGroup.CreateNew(title, request.Key, request.IsSecure);
await unitOfWork.MediaGroup.AddAsync(mediaGroup, cancellationToken);
await unitOfWork.SaveChangeAsync(cancellationToken);
return mediaGroup.Adapt<MediaGroupDTO>();
}
}
public class UploadFileCommandHandler(IUnitOfWork unitOfWork, CDNGrpc.CDNGrpcClient cdnClient, IFileManagerService fileManager) : ICommandHandler<UploadFileCommand, UploadFileDTO>
public class UploadFileCommandHandler(IUnitOfWork unitOfWork, IFileManagerService fileManager) : ICommandHandler<UploadFileCommand, UploadFileDTO>
{
public async Task<UploadFileDTO> Handle(UploadFileCommand request, CancellationToken cancellationToken)
{
@@ -57,11 +56,11 @@ public class UploadFileCommandHandler(IUnitOfWork unitOfWork, CDNGrpc.CDNGrpcCli
var path = await fileManager.SaveFile(fileBytes, extension, mediaGroup.Id);
media = Media.CreateNew(new ContentType(request.File.ContentType, fileBytes), fileBytes.Length, hash, path);
}
var mediaGroupMedia = mediaGroup.AddMedia(new FileName(request.File.Name), media);
var mediaGroupMedia = mediaGroup.AddMedia(new FileName(request.File.Name), media);
if (!string.IsNullOrEmpty(request.ClientId))
mediaGroupMedia.AddMediaPermission(media, Client.CreateNew(new ClientId(request.ClientId)));
await unitOfWork.MediaGroup.AddAsync(mediaGroup, cancellationToken);
await unitOfWork.MediaGroup.UpdateAsync(mediaGroup, cancellationToken);
await unitOfWork.SaveChangeAsync(cancellationToken);
return new UploadFileDTO()
@@ -7,7 +7,7 @@ namespace Vizhtalk.CDN.Presentation.Application
{
IMediaRepository Media { get; }
IClientRepository Client { get; }
IMediaClientRepository MediaClient { get; }
IMediaPermissionRepository MediaClient { get; }
IMediaGroupRepository MediaGroup{ get; }
IMediaGroupMediaRepository MediaGroupMedia { get; }
@@ -7,10 +7,13 @@ namespace Vizhtalk.CDN.Presentation.Domain.Entities;
public class Media : Entity<MediaId>
{
private Media(ContentType contentType, int size , string hash , string path)
private Media()
{
}
private Media(ContentType contentType, int size , string hash , string path)
{
Id = new MediaId(Guid.NewGuid());
ContentType = contentType;
Size = size;
Hash = hash;
@@ -6,9 +6,13 @@ namespace Vizhtalk.CDN.Presentation.Domain.Entities;
public class MediaGroup : Entity<MediaGroupId>
{
private MediaGroup()
{
}
private MediaGroup(MediaGroupTitle title, string key, bool isSecure)
{
Id = new MediaGroupId(Guid.NewGuid());
Title = title;
Key = key;
IsSecure = isSecure;
@@ -7,11 +7,15 @@ namespace Vizhtalk.CDN.Presentation.Domain.Entities;
public class MediaGroupMedia : Entity<MediaGroupMediaId>
{
private List<MediaPermission> _mediaPermissions = new();
private MediaGroupMedia()
{
}
private MediaGroupMedia(FileName fileName,
Media media,
MediaGroup mediaGroup)
{
Id = new MediaGroupMediaId(Guid.NewGuid());
Name = fileName;
Media = media;
MediaGroup = mediaGroup;
@@ -3,7 +3,7 @@ using VizhTalk.BuildingBlocks.Domain;
namespace Vizhtalk.CDN.Presentation.Domain.Entities;
public class MediaPermission : Entity<MediaClientId>
public class MediaPermission : Entity<MediaPermissionId>
{
private MediaPermission()
{
@@ -11,6 +11,7 @@ public class MediaPermission : Entity<MediaClientId>
}
private MediaPermission(Media media, Client client, MediaGroupMedia mediaGroupMedia)
{
Id = new MediaPermissionId(Guid.NewGuid());
Media = media;
Client = client;
MediaGroupMedia = mediaGroupMedia;
@@ -4,4 +4,4 @@ using VizhTalk.BuildingBlocks.Domain;
namespace Vizhtalk.CDN.Presentation.Domain.Repositories;
public interface IMediaClientRepository : IRepositoryBase<MediaPermission, MediaClientId>;
public interface IMediaPermissionRepository : IRepositoryBase<MediaPermission, MediaPermissionId>;
@@ -2,9 +2,9 @@
namespace Vizhtalk.CDN.Presentation.Domain.TypeIds;
public class MediaId : TypeIdValueBase<long>
public class MediaId : TypeIdValueBase<Guid>
{
public MediaId(long value) : base(value)
public MediaId(Guid value) : base(value)
{
}
}
@@ -2,9 +2,9 @@
namespace Vizhtalk.CDN.Presentation.Domain.TypeIds;
public class MediaClientId : TypeIdValueBase<long>
public class MediaPermissionId : TypeIdValueBase<Guid>
{
public MediaClientId(long value) : base(value)
public MediaPermissionId(Guid value) : base(value)
{
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 MiB

@@ -1,6 +1,8 @@
using Microsoft.EntityFrameworkCore;
using MongoDB.Driver;
using Vizhtalk.CDN.Presentation.Application;
using Vizhtalk.CDN.Presentation.Application.Mappers;
using Vizhtalk.CDN.Presentation.FileManagerServices;
using Vizhtalk.CDN.Presentation.Infrastructure.Configuration;
using Vizhtalk.CDN.Presentation.Infrastructure.EF;
using VizhTalk.BuildingBlocks.Application;
@@ -18,6 +20,9 @@ public static class CDNStartup
{
public static void Initialize(this IServiceCollection services, string connectionString, string databaseName)
{
var domainNotificationsMap = new BiDictionary<string, Type>();
services.AddDbContext<CDNDbContext>(options =>
{
options.UseMongoDB(connectionString, databaseName);
@@ -25,6 +30,46 @@ public static class CDNStartup
services.AddScoped<DbContext>(sp => sp.GetService<CDNDbContext>());
services.Scan(scan => scan.
FromAssemblies(Assemblies.Application, Assemblies.Infrastructure)
.AddClasses(classes => classes.AssignableTo(typeof(ICommandHandler<>)), publicOnly: false)
.AsImplementedInterfaces()
.WithScopedLifetime()
.AddClasses(classes => classes.AssignableTo(typeof(ICommandHandler<,>)), publicOnly: false)
.AsImplementedInterfaces()
.WithScopedLifetime()
.AddClasses(classes => classes.AssignableTo(typeof(IQueryHandler<,>)), publicOnly: false)
.AsImplementedInterfaces()
.WithScopedLifetime()
.AddClasses(classes => classes.AssignableTo(typeof(ICommandHandler<>)), publicOnly: false)
.AsImplementedInterfaces()
.WithScopedLifetime());
services.AddScoped<IFileManagerService, FileManagerService>();
services.AddScoped<DbContext>(sp => sp.GetService<CDNDbContext>());
services.AddScoped<ICDNModule, CDNModule>();
services.AddScoped<IExecutor, CDNModule>();
services.AddScoped<IUnitOfWork, UnitOfWork>();
services.AddScoped<IDomainEventsAccessor, DomainEventsAccessor>();
services.AddScoped<IDomainEventsDispatcher, DomainEventsDispatcher>();
services.AddScoped<IDomainNotificationsMapper, DomainNotificationsMapper>();
services.AddScoped(sp => domainNotificationsMap);
MapperConfig.Process();
services.AddScoped(sa =>
{
var notifications = sa.GetServices<IDomainEventNotification>();
var notificationDic = new BiDictionary<string, Type>();
foreach (var notification in notifications)
notificationDic.Add(notification!.ToString()!, notification!.GetType());
return notificationDic;
});
services.AddScoped<IOutbox>(sa =>
{
return null; // ToDo
});
}
@@ -9,7 +9,7 @@ namespace Vizhtalk.CDN.Presentation.Infrastructure.EF
public CDNDbContext(DbContextOptions<CDNDbContext> options) : base(options)
{
Database.AutoTransactionBehavior = AutoTransactionBehavior.Never;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
@@ -19,6 +19,5 @@ namespace Vizhtalk.CDN.Presentation.Infrastructure.EF
.ApplyConfigurationsFromAssembly(Assemblies.Infrastructure, x => x.FullName.Contains("EF.Configurations"))
.PluralizeEntities();
}
}
}
@@ -12,7 +12,7 @@ public class MediaClientConfiguration : IEntityTypeConfiguration<MediaPermission
builder.HasKey(x => x.Id);
builder.Property(x => x.Id)
.HasConversion(x => x.Value, x => new Domain.TypeIds.MediaClientId(x));
.HasConversion(x => x.Value, x => new Domain.TypeIds.MediaPermissionId(x));
builder.Property(x => x.ClientId)
@@ -0,0 +1,16 @@
using Microsoft.EntityFrameworkCore;
using Vizhtalk.CDN.Presentation.Domain.Entities;
using Vizhtalk.CDN.Presentation.Domain.Repositories;
using Vizhtalk.CDN.Presentation.Domain.TypeIds;
using Vizhtalk.CDN.Presentation.Infrastructure.EF;
using VizhTalk.BuildingBlocks.Infrastructure;
namespace Vizhtalk.CDN.Presentation.Infrastructure.Repositories
{
public class ClientRepository : RepositoryBase<Client, ClientId>, IClientRepository
{
public ClientRepository(CDNDbContext dbContext) : base(dbContext)
{
}
}
}
@@ -0,0 +1,16 @@
using Microsoft.EntityFrameworkCore;
using Vizhtalk.CDN.Presentation.Domain.Entities;
using Vizhtalk.CDN.Presentation.Domain.Repositories;
using Vizhtalk.CDN.Presentation.Domain.TypeIds;
using Vizhtalk.CDN.Presentation.Infrastructure.EF;
using VizhTalk.BuildingBlocks.Infrastructure;
namespace Vizhtalk.CDN.Presentation.Infrastructure.Repositories
{
public class MediaGroupMediaRepository : RepositoryBase<MediaGroupMedia, MediaGroupMediaId>, IMediaGroupMediaRepository
{
public MediaGroupMediaRepository(CDNDbContext dbContext) : base(dbContext)
{
}
}
}
@@ -0,0 +1,16 @@
using Microsoft.EntityFrameworkCore;
using Vizhtalk.CDN.Presentation.Domain.Entities;
using Vizhtalk.CDN.Presentation.Domain.Repositories;
using Vizhtalk.CDN.Presentation.Domain.TypeIds;
using Vizhtalk.CDN.Presentation.Infrastructure.EF;
using VizhTalk.BuildingBlocks.Infrastructure;
namespace Vizhtalk.CDN.Presentation.Infrastructure.Repositories
{
public class MediaGroupRepository : RepositoryBase<MediaGroup, MediaGroupId>, IMediaGroupRepository
{
public MediaGroupRepository(CDNDbContext dbContext) : base(dbContext)
{
}
}
}
@@ -0,0 +1,16 @@
using Microsoft.EntityFrameworkCore;
using Vizhtalk.CDN.Presentation.Domain.Entities;
using Vizhtalk.CDN.Presentation.Domain.Repositories;
using Vizhtalk.CDN.Presentation.Domain.TypeIds;
using Vizhtalk.CDN.Presentation.Infrastructure.EF;
using VizhTalk.BuildingBlocks.Infrastructure;
namespace Vizhtalk.CDN.Presentation.Infrastructure.Repositories
{
public class MediaPermissionRepository : RepositoryBase<MediaPermission, MediaPermissionId>, IMediaPermissionRepository
{
public MediaPermissionRepository(CDNDbContext dbContext) : base(dbContext)
{
}
}
}
@@ -0,0 +1,16 @@
using Microsoft.EntityFrameworkCore;
using Vizhtalk.CDN.Presentation.Domain.Entities;
using Vizhtalk.CDN.Presentation.Domain.Repositories;
using Vizhtalk.CDN.Presentation.Domain.TypeIds;
using Vizhtalk.CDN.Presentation.Infrastructure.EF;
using VizhTalk.BuildingBlocks.Infrastructure;
namespace Vizhtalk.CDN.Presentation.Infrastructure.Repositories
{
public class MediaRepository : RepositoryBase<Media, MediaId>, IMediaRepository
{
public MediaRepository(CDNDbContext dbContext) : base(dbContext)
{
}
}
}
@@ -3,21 +3,73 @@ using Vizhtalk.CDN.Presentation.Infrastructure.EF;
using Vizhtalk.CDN.Presentation.Domain.Repositories;
using VizhTalk.BuildingBlocks.Infrastructure;
using VizhTalk.BuildingBlocks.Infrastructure.DomainEventsDispatching;
using Vizhtalk.CDN.Presentation.Infrastructure.Repositories;
namespace Vizhtalk.CDN.Presentation.Infrastructure
{
public class UnitOfWork(CDNDbContext cdnDbContext, IDomainEventsDispatcher domainEventsDispatcher)
: UnitOfWorkBase(cdnDbContext, domainEventsDispatcher)
: UnitOfWorkBase(cdnDbContext, domainEventsDispatcher), IUnitOfWork
{
public IMediaRepository Media => throw new NotImplementedException();
private IMediaRepository _mediaRepository;
public IMediaRepository Media
{
get
{
if (_mediaRepository == null)
_mediaRepository = new MediaRepository(cdnDbContext);
public IClientRepository Client => throw new NotImplementedException();
return _mediaRepository;
}
}
public IMediaClientRepository MediaClient => throw new NotImplementedException();
private IClientRepository _clientRepository;
public IClientRepository Client
{
get
{
if(_clientRepository == null)
_clientRepository = new ClientRepository(cdnDbContext);
return _clientRepository;
}
}
public IMediaGroupRepository MediaGroup => throw new NotImplementedException();
private IMediaPermissionRepository _mediaPermissionRepository;
public IMediaPermissionRepository MediaClient
{
get
{
if( _mediaPermissionRepository == null)
_mediaPermissionRepository = new MediaPermissionRepository(cdnDbContext);
public IMediaGroupMediaRepository MediaGroupMedia => throw new NotImplementedException();
return _mediaPermissionRepository;
}
}
private IMediaGroupRepository _mediaGroupRepository;
public IMediaGroupRepository MediaGroup
{
get
{
if(_mediaGroupRepository == null)
_mediaGroupRepository = new MediaGroupRepository(cdnDbContext);
return _mediaGroupRepository;
}
}
private IMediaGroupMediaRepository _mediaGroupMediaRepository;
public IMediaGroupMediaRepository MediaGroupMedia
{
get
{
if(_mediaGroupMediaRepository == null)
_mediaGroupMediaRepository = new MediaGroupMediaRepository(cdnDbContext);
return _mediaGroupMediaRepository;
}
}
public async Task SaveChangeAsync(CancellationToken cancellationToken = default)
=> await cdnDbContext.SaveChangesAsync(cancellationToken);
}
}
+4 -2
View File
@@ -8,9 +8,11 @@ var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("VizhTalk.CDN")!;
var databaseName = builder.Configuration.GetConnectionString("VizhTalk.CDN.DatabaseName")!;
builder.Services.AddScoped<IFileManagerService, FileManagerService>();
builder.Services.Initialize(connectionString, databaseName);
builder.Services.AddGrpc();
builder.Services.AddGrpc(op =>
{
op.MaxReceiveMessageSize = 500 * 1024 * 1024;
});
var app = builder.Build();
+1 -1
View File
@@ -7,7 +7,7 @@
},
"ConnectionStrings": {
"VizhTalk.CDN": "mongodb://localhost:27017",
"VizhTalk.CDN.DatabaseName": "VizhTalk.CDN"
"VizhTalk.CDN.DatabaseName": "VizhTalk_CDN"
},
"AllowedHosts": "*"
}