CDN
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 7.0 MiB |
|
After Width: | Height: | Size: 7.0 MiB |
|
After Width: | Height: | Size: 7.0 MiB |
|
After Width: | Height: | Size: 7.0 MiB |
|
After Width: | Height: | Size: 7.0 MiB |
|
After Width: | Height: | Size: 7.0 MiB |
|
After Width: | Height: | Size: 7.0 MiB |
|
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"VizhTalk.CDN": "mongodb://localhost:27017",
|
||||
"VizhTalk.CDN.DatabaseName": "VizhTalk.CDN"
|
||||
"VizhTalk.CDN.DatabaseName": "VizhTalk_CDN"
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
|
||||