diff --git a/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobContainerConfigurationExtensions.cs b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobContainerConfigurationExtensions.cs new file mode 100644 index 0000000000..24357554eb --- /dev/null +++ b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobContainerConfigurationExtensions.cs @@ -0,0 +1,24 @@ +using System; + +namespace Volo.Abp.BlobStoring.FileSystem +{ + public static class FileSystemBlobContainerConfigurationExtensions + { + public static FileSystemBlobProviderConfiguration GetFileSystemConfiguration( + this BlobContainerConfiguration containerConfiguration) + { + return new FileSystemBlobProviderConfiguration(containerConfiguration); + } + + public static BlobContainerConfiguration UseFileSystem( + this BlobContainerConfiguration containerConfiguration, + Action fileSystemConfigureAction) + { + containerConfiguration.ProviderType = typeof(FileSystemBlobProvider); + + fileSystemConfigureAction(new FileSystemBlobProviderConfiguration(containerConfiguration)); + + return containerConfiguration; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProvider.cs new file mode 100644 index 0000000000..55ed50a45b --- /dev/null +++ b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProvider.cs @@ -0,0 +1,79 @@ +using System.IO; +using System.Threading.Tasks; +using Volo.Abp.IO; + +namespace Volo.Abp.BlobStoring.FileSystem +{ + //TODO: What if the file is being used on create, delete or read? + + public class FileSystemBlobProvider : BlobProviderBase + { + public override async Task SaveAsync(BlobProviderSaveArgs args) + { + var filePath = CalculateBlobFilePath(args); + + DirectoryHelper.CreateIfNotExists(Path.GetDirectoryName(filePath)); + + var fileMode = args.OverrideExisting + ? FileMode.Create + : FileMode.CreateNew; + + using (var fileStream = File.Open(filePath, fileMode, FileAccess.Write)) + { + //TODO: Truely implement this (like this? http://writeasync.net/?p=2621 or https://www.infoworld.com/article/2995387/how-to-perform-asynchronous-file-operations-in-c.html) + + await args.BlobStream.CopyToAsync( + fileStream, + 81920, //this is already the default value, but needed to set to be able to pass the cancellationToken + args.CancellationToken + ); + + await fileStream.FlushAsync(); + } + } + + public override Task DeleteAsync(BlobProviderDeleteArgs args) + { + var filePath = CalculateBlobFilePath(args); + + return Task.FromResult(FileHelper.DeleteIfExists(filePath)); + } + + public override Task ExistsAsync(BlobProviderExistsArgs args) + { + var filePath = CalculateBlobFilePath(args); + + return Task.FromResult(File.Exists(filePath)); + } + + public override Task GetOrNullAsync(BlobProviderGetArgs args) + { + var filePath = CalculateBlobFilePath(args); + + if (!File.Exists(filePath)) + { + return Task.FromResult(null); + } + + return Task.FromResult(File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)); + } + + protected virtual string CalculateBlobFilePath(BlobProviderArgs args) + { + var blobPath = args.Configuration.GetFileSystemConfiguration().BasePath; + + if (args.TenantId == null) + { + blobPath = Path.Combine(blobPath, "host"); + } + else + { + blobPath = Path.Combine(blobPath, "tenants", args.TenantId.Value.ToString("D")); + } + + blobPath = Path.Combine(blobPath, args.ContainerName, args.BlobName); + + return blobPath; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProviderConfiguration.cs b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProviderConfiguration.cs new file mode 100644 index 0000000000..f6a700d09a --- /dev/null +++ b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProviderConfiguration.cs @@ -0,0 +1,19 @@ +namespace Volo.Abp.BlobStoring.FileSystem +{ + public class FileSystemBlobProviderConfiguration + { + + public string BasePath + { + get => _containerConfiguration.GetConfiguration(FileSystemBlobProviderConfigurationNames.BasePath); + set => _containerConfiguration.SetConfiguration(FileSystemBlobProviderConfigurationNames.BasePath, Check.NotNullOrWhiteSpace(value, nameof(value))); + } + + private readonly BlobContainerConfiguration _containerConfiguration; + + public FileSystemBlobProviderConfiguration(BlobContainerConfiguration containerConfiguration) + { + _containerConfiguration = containerConfiguration; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProviderConfigurationNames.cs b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProviderConfigurationNames.cs new file mode 100644 index 0000000000..6670f6f76e --- /dev/null +++ b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProviderConfigurationNames.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.BlobStoring.FileSystem +{ + public static class FileSystemBlobProviderConfigurationNames + { + public const string BasePath = "BasePath"; + + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.BlobStoring/Volo.Abp.BlobStoring.csproj b/framework/src/Volo.Abp.BlobStoring/Volo.Abp.BlobStoring.csproj index cbf13cea87..850f98b5f1 100644 --- a/framework/src/Volo.Abp.BlobStoring/Volo.Abp.BlobStoring.csproj +++ b/framework/src/Volo.Abp.BlobStoring/Volo.Abp.BlobStoring.csproj @@ -16,6 +16,8 @@ + + diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/AbpBlobStoringModule.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/AbpBlobStoringModule.cs index aec7b013e8..35970ea169 100644 --- a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/AbpBlobStoringModule.cs +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/AbpBlobStoringModule.cs @@ -1,15 +1,21 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Modularity; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Threading; namespace Volo.Abp.BlobStoring { + [DependsOn( + typeof(AbpMultiTenancyModule), + typeof(AbpThreadingModule) + )] public class AbpBlobStoringModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddTransient( typeof(IBlobContainer<>), - typeof(TypedBlobContainerWrapper<>) + typeof(BlobContainer<>) ); context.Services.AddTransient( diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainer.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainer.cs new file mode 100644 index 0000000000..859c5f85be --- /dev/null +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainer.cs @@ -0,0 +1,190 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Threading; + +namespace Volo.Abp.BlobStoring +{ + public class BlobContainer : IBlobContainer + where TContainer : class + { + private readonly IBlobContainer _container; + + public BlobContainer(IBlobContainerFactory blobContainerFactory) + { + _container = blobContainerFactory.Create(); + } + + public Task SaveAsync( + string name, + Stream stream, + bool overrideExisting = false, + CancellationToken cancellationToken = default) + { + return _container.SaveAsync( + name, + stream, + overrideExisting, + cancellationToken + ); + } + + public Task DeleteAsync( + string name, + CancellationToken cancellationToken = default) + { + return _container.DeleteAsync( + name, + cancellationToken + ); + } + + public Task ExistsAsync( + string name, + CancellationToken cancellationToken = default) + { + return _container.ExistsAsync( + name, + cancellationToken + ); + } + + public Task GetAsync( + string name, + CancellationToken cancellationToken = default) + { + return _container.GetAsync( + name, + cancellationToken + ); + } + + public Task GetOrNullAsync( + string name, + CancellationToken cancellationToken = default) + { + return _container.GetOrNullAsync( + name, + cancellationToken + ); + } + } + + public class BlobContainer : IBlobContainer + { + protected string ContainerName { get; } + + protected BlobContainerConfiguration Configuration { get; } + + protected IBlobProvider Provider { get; } + + protected ICurrentTenant CurrentTenant { get; } + + protected ICancellationTokenProvider CancellationTokenProvider { get; } + + public BlobContainer( + string containerName, + BlobContainerConfiguration configuration, + IBlobProvider provider, + ICurrentTenant currentTenant, + ICancellationTokenProvider cancellationTokenProvider) + { + ContainerName = containerName; + Configuration = configuration; + Provider = provider; + CurrentTenant = currentTenant; + CancellationTokenProvider = cancellationTokenProvider; + } + + public virtual Task SaveAsync( + string name, + Stream stream, + bool overrideExisting = false, + CancellationToken cancellationToken = default) + { + return Provider.SaveAsync( + new BlobProviderSaveArgs( + ContainerName, + Configuration, + name, + stream, + overrideExisting, + GetTenantIdOrNull(), + CancellationTokenProvider.FallbackToProvider(cancellationToken) + ) + ); + } + + public virtual Task DeleteAsync( + string name, + CancellationToken cancellationToken = default) + { + return Provider.DeleteAsync( + new BlobProviderDeleteArgs( + ContainerName, + Configuration, + name, + GetTenantIdOrNull(), + CancellationTokenProvider.FallbackToProvider(cancellationToken) + ) + ); + } + + public virtual Task ExistsAsync( + string name, + CancellationToken cancellationToken = default) + { + return Provider.ExistsAsync( + new BlobProviderExistsArgs( + ContainerName, + Configuration, + name, + GetTenantIdOrNull(), + CancellationTokenProvider.FallbackToProvider(cancellationToken) + ) + ); + } + + public virtual Task GetAsync( + string name, + CancellationToken cancellationToken = default) + { + return Provider.GetAsync( + new BlobProviderGetArgs( + ContainerName, + Configuration, + name, + GetTenantIdOrNull(), + CancellationTokenProvider.FallbackToProvider(cancellationToken) + ) + ); + } + + public virtual Task GetOrNullAsync( + string name, + CancellationToken cancellationToken = default) + { + return Provider.GetOrNullAsync( + new BlobProviderGetArgs( + ContainerName, + Configuration, + name, + GetTenantIdOrNull(), + CancellationTokenProvider.FallbackToProvider(cancellationToken) + ) + ); + } + + protected virtual Guid? GetTenantIdOrNull() + { + if (!Configuration.IsMultiTenant) + { + return null; + } + + return CurrentTenant.Id; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerConfiguration.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerConfiguration.cs index c649ea3ffa..46f13a1c3d 100644 --- a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerConfiguration.cs +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerConfiguration.cs @@ -6,14 +6,27 @@ namespace Volo.Abp.BlobStoring { public class BlobContainerConfiguration { + /// + /// The provider to be used to store BLOBs of this container. + /// public Type ProviderType { get; set; } - [NotNull] - private readonly Dictionary _properties; - - [CanBeNull] - private readonly BlobContainerConfiguration _fallbackConfiguration; - + /// + /// Indicates whether this container is multi-tenant or not. + /// + /// If this is false and your application is multi-tenant, + /// then the container is shared by all tenants in the system. + /// + /// This can be true even if your application is not multi-tenant. + /// + /// Default: true. + /// + public bool IsMultiTenant { get; set; } = true; + + [NotNull] private readonly Dictionary _properties; + + [CanBeNull] private readonly BlobContainerConfiguration _fallbackConfiguration; + public BlobContainerConfiguration(BlobContainerConfiguration fallbackConfiguration = null) { _fallbackConfiguration = fallbackConfiguration; @@ -25,7 +38,7 @@ namespace Volo.Abp.BlobStoring { return (T) GetConfigurationOrNull(name, defaultValue); } - + [CanBeNull] public object GetConfigurationOrNull(string name, object defaultValue = null) { @@ -33,25 +46,25 @@ namespace Volo.Abp.BlobStoring _fallbackConfiguration?.GetConfigurationOrNull(name, defaultValue) ?? defaultValue; } - + [NotNull] public BlobContainerConfiguration SetConfiguration([NotNull] string name, [CanBeNull] object value) { Check.NotNullOrWhiteSpace(name, nameof(name)); Check.NotNull(value, nameof(value)); - + _properties[name] = value; - + return this; } - + [NotNull] public BlobContainerConfiguration ClearConfiguration([NotNull] string name) { Check.NotNullOrWhiteSpace(name, nameof(name)); _properties.Remove(name); - + return this; } } diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerConfigurationExtensions.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerConfigurationExtensions.cs new file mode 100644 index 0000000000..ca437b0ad0 --- /dev/null +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerConfigurationExtensions.cs @@ -0,0 +1,27 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.BlobStoring +{ + public static class BlobContainerConfigurationExtensions + { + public static T GetConfiguration( + [NotNull] this BlobContainerConfiguration containerConfiguration, + [NotNull] string name) + { + return (T) containerConfiguration.GetConfiguration(name); + } + + public static object GetConfiguration( + [NotNull] this BlobContainerConfiguration containerConfiguration, + [NotNull] string name) + { + var value = containerConfiguration.GetConfigurationOrNull(name); + if (value == null) + { + throw new AbpException($"Could not find the configuration value for '{name}'!"); + } + + return value; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerFactory.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerFactory.cs index ee5341c1da..33b511fa55 100644 --- a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerFactory.cs +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerFactory.cs @@ -6,30 +6,42 @@ using JetBrains.Annotations; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; using Volo.Abp.DynamicProxy; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Threading; namespace Volo.Abp.BlobStoring { public class BlobContainerFactory : IBlobContainerFactory, ITransientDependency { - public IEnumerable BlobProviders { get; } - protected AbpBlobStoringOptions Options { get; } + protected IEnumerable BlobProviders { get; } + + protected ICurrentTenant CurrentTenant { get; } + + protected ICancellationTokenProvider CancellationTokenProvider { get; } + public BlobContainerFactory( IOptions options, - IEnumerable blobProviders) + IEnumerable blobProviders, + ICurrentTenant currentTenant, + ICancellationTokenProvider cancellationTokenProvider) { - BlobProviders = blobProviders; Options = options.Value; + BlobProviders = blobProviders; + CurrentTenant = currentTenant; + CancellationTokenProvider = cancellationTokenProvider; } public virtual IBlobContainer Create(string name, CancellationToken cancellationToken = default) { var configuration = Options.Containers.GetConfiguration(name); - return new BlobContainerToProviderAdapter( + return new BlobContainer( name, configuration, - GetProvider(name, configuration) + GetProvider(name, configuration), + CurrentTenant, + CancellationTokenProvider ); } diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerToProviderAdapter.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerToProviderAdapter.cs deleted file mode 100644 index 8ecd498a52..0000000000 --- a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerToProviderAdapter.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace Volo.Abp.BlobStoring -{ - public class BlobContainerToProviderAdapter : IBlobContainer - { - protected string ContainerName { get; } - - protected BlobContainerConfiguration ContainerConfiguration { get; } - - protected IBlobProvider Provider { get; } - - public BlobContainerToProviderAdapter( - string containerName, - BlobContainerConfiguration containerConfiguration, - IBlobProvider provider) - { - ContainerName = containerName; - ContainerConfiguration = containerConfiguration; - Provider = provider; - } - - public virtual Task SaveAsync( - string name, - Stream stream, - bool overrideExisting = false, - CancellationToken cancellationToken = default) - { - return Provider.SaveAsync( - new BlobProviderSaveArgs( - ContainerName, - ContainerConfiguration, - name, - stream, - overrideExisting, - cancellationToken - ) - ); - } - - public virtual Task DeleteAsync( - string name, - CancellationToken cancellationToken = default) - { - return Provider.DeleteAsync( - new BlobProviderDeleteArgs( - ContainerName, - ContainerConfiguration, - name, - cancellationToken - ) - ); - } - - public virtual Task ExistsAsync( - string name, - CancellationToken cancellationToken = default) - { - return Provider.ExistsAsync( - new BlobProviderExistsArgs( - ContainerName, - ContainerConfiguration, - name, - cancellationToken - ) - ); - } - - public virtual Task GetAsync( - string name, - CancellationToken cancellationToken = default) - { - return Provider.GetAsync( - new BlobProviderGetArgs( - ContainerName, - ContainerConfiguration, - name, - cancellationToken - ) - ); - } - - public virtual Task GetOrNullAsync( - string name, - CancellationToken cancellationToken = default) - { - return Provider.GetOrNullAsync( - new BlobProviderGetArgs( - ContainerName, - ContainerConfiguration, - name, - cancellationToken - ) - ); - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderArgs.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderArgs.cs index fcc264977a..e1ad228839 100644 --- a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderArgs.cs +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderArgs.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System; +using System.Threading; using JetBrains.Annotations; namespace Volo.Abp.BlobStoring @@ -15,16 +16,20 @@ namespace Volo.Abp.BlobStoring public string BlobName { get; } public CancellationToken CancellationToken { get; } + + public Guid? TenantId { get; } protected BlobProviderArgs( [NotNull] string containerName, [NotNull] BlobContainerConfiguration configuration, [NotNull] string blobName, + [CanBeNull] Guid? tenantId = null, CancellationToken cancellationToken = default) { ContainerName = Check.NotNullOrWhiteSpace(containerName, nameof(containerName)); Configuration = Check.NotNull(configuration, nameof(configuration)); BlobName = Check.NotNullOrWhiteSpace(blobName, nameof(blobName)); + TenantId = tenantId; CancellationToken = cancellationToken; } } diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderBase.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderBase.cs new file mode 100644 index 0000000000..eb047acf2d --- /dev/null +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderBase.cs @@ -0,0 +1,28 @@ +using System.IO; +using System.Threading.Tasks; + +namespace Volo.Abp.BlobStoring +{ + public abstract class BlobProviderBase : IBlobProvider + { + public abstract Task SaveAsync(BlobProviderSaveArgs args); + + public abstract Task DeleteAsync(BlobProviderDeleteArgs args); + + public abstract Task ExistsAsync(BlobProviderExistsArgs args); + + public virtual async Task GetAsync(BlobProviderGetArgs args) + { + var result = await GetOrNullAsync(args); + if (result == null) + { + //TODO: Consider to throw some type of "not found" exception and handle on the HTTP status side + throw new AbpException($"Could not found the requested BLOB '{args.BlobName}' in the container '{args.ContainerName}'!"); + } + + return result; + } + + public abstract Task GetOrNullAsync(BlobProviderGetArgs args); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderDeleteArgs.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderDeleteArgs.cs index 146074d444..aa4aae1eb2 100644 --- a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderDeleteArgs.cs +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderDeleteArgs.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System; +using System.Threading; using JetBrains.Annotations; namespace Volo.Abp.BlobStoring @@ -9,11 +10,13 @@ namespace Volo.Abp.BlobStoring [NotNull] string containerName, [NotNull] BlobContainerConfiguration configuration, [NotNull] string blobName, + [CanBeNull] Guid? tenantId = null, CancellationToken cancellationToken = default) : base( containerName, configuration, blobName, + tenantId, cancellationToken) { } diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderExistsArgs.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderExistsArgs.cs index dee2e144f7..a55b22a233 100644 --- a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderExistsArgs.cs +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderExistsArgs.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System; +using System.Threading; using JetBrains.Annotations; namespace Volo.Abp.BlobStoring @@ -9,11 +10,13 @@ namespace Volo.Abp.BlobStoring [NotNull] string containerName, [NotNull] BlobContainerConfiguration configuration, [NotNull] string blobName, + [CanBeNull] Guid? tenantId = null, CancellationToken cancellationToken = default) : base( containerName, configuration, blobName, + tenantId, cancellationToken) { } diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderGetArgs.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderGetArgs.cs index f3087e9805..94374698c7 100644 --- a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderGetArgs.cs +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderGetArgs.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System; +using System.Threading; using JetBrains.Annotations; namespace Volo.Abp.BlobStoring @@ -9,11 +10,13 @@ namespace Volo.Abp.BlobStoring [NotNull] string containerName, [NotNull] BlobContainerConfiguration configuration, [NotNull] string blobName, + [CanBeNull] Guid? tenantId = null, CancellationToken cancellationToken = default) : base( containerName, configuration, blobName, + tenantId, cancellationToken) { } diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderSaveArgs.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderSaveArgs.cs index d1a5f3845e..a81938fb7d 100644 --- a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderSaveArgs.cs +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobProviderSaveArgs.cs @@ -1,41 +1,34 @@ -using System.IO; +using System; +using System.IO; using System.Threading; using JetBrains.Annotations; namespace Volo.Abp.BlobStoring { - public class BlobProviderSaveArgs + public class BlobProviderSaveArgs : BlobProviderArgs { - [NotNull] - public string ContainerName { get; } - - [NotNull] - public BlobContainerConfiguration Configuration { get; } - - [NotNull] - public string BlobName { get; } - [NotNull] public Stream BlobStream { get; } public bool OverrideExisting { get; } - public CancellationToken CancellationToken { get; } - public BlobProviderSaveArgs( [NotNull] string containerName, [NotNull] BlobContainerConfiguration configuration, [NotNull] string blobName, [NotNull] Stream blobStream, bool overrideExisting = false, + [CanBeNull] Guid? tenantId = null, CancellationToken cancellationToken = default) + : base( + containerName, + configuration, + blobName, + tenantId, + cancellationToken) { - ContainerName = Check.NotNullOrWhiteSpace(containerName, nameof(containerName)); - Configuration = Check.NotNull(configuration, nameof(configuration)); - BlobName = Check.NotNullOrWhiteSpace(blobName, nameof(blobName)); BlobStream = Check.NotNull(blobStream, nameof(blobStream)); OverrideExisting = overrideExisting; - CancellationToken = cancellationToken; } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/IBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/IBlobProvider.cs index be6a2dd648..a1546e3159 100644 --- a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/IBlobProvider.cs +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/IBlobProvider.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; using System.Threading.Tasks; namespace Volo.Abp.BlobStoring diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/TypedBlobContainerWrapper.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/TypedBlobContainerWrapper.cs deleted file mode 100644 index 34d11bb46f..0000000000 --- a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/TypedBlobContainerWrapper.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace Volo.Abp.BlobStoring -{ - public class TypedBlobContainerWrapper : IBlobContainer - where TContainer: class - { - private readonly IBlobContainer _container; - - public TypedBlobContainerWrapper(IBlobContainerFactory blobContainerFactory) - { - _container = blobContainerFactory.Create(); - } - - public Task SaveAsync(string name, Stream stream, bool overrideExisting = false, CancellationToken cancellationToken = default) - { - return _container.SaveAsync(name, stream, overrideExisting, cancellationToken); - } - - public Task DeleteAsync(string name, CancellationToken cancellationToken = default) - { - return _container.DeleteAsync(name, cancellationToken); - } - - public Task ExistsAsync(string name, CancellationToken cancellationToken = default) - { - return _container.ExistsAsync(name, cancellationToken); - } - - public Task GetAsync(string name, CancellationToken cancellationToken = default) - { - return _container.GetAsync(name, cancellationToken); - } - - public Task GetOrNullAsync(string name, CancellationToken cancellationToken = default) - { - return _container.GetOrNullAsync(name, cancellationToken); - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/IO/DirectoryHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/IO/DirectoryHelper.cs index b864695430..23f8de610a 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/IO/DirectoryHelper.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/IO/DirectoryHelper.cs @@ -16,6 +16,14 @@ namespace Volo.Abp.IO Directory.CreateDirectory(directory); } } + + public static void CreateIfNotExists(DirectoryInfo directory) + { + if (!directory.Exists) + { + directory.Create(); + } + } public static bool IsSubDirectoryOf([NotNull] string parentDirectoryPath, [NotNull] string childDirectoryPath) { diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs index a945784352..8f4a15bdf5 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs @@ -17,12 +17,15 @@ namespace Volo.Abp.IO /// Checks and deletes given file if it does exists. /// /// Path of the file - public static void DeleteIfExists(string filePath) + public static bool DeleteIfExists(string filePath) { - if (File.Exists(filePath)) + if (!File.Exists(filePath)) { - File.Delete(filePath); + return false; } + + File.Delete(filePath); + return true; } /// diff --git a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/BlobContainer_Injection_Tests.cs b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/BlobContainer_Injection_Tests.cs index 7dc74fa14c..bd4ec2c47a 100644 --- a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/BlobContainer_Injection_Tests.cs +++ b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/BlobContainer_Injection_Tests.cs @@ -10,23 +10,23 @@ namespace Volo.Abp.BlobStoring public void Should_Inject_DefaultContainer_For_Non_Generic_Interface() { GetRequiredService() - .ShouldBeOfType>(); + .ShouldBeOfType>(); } [Fact] public void Should_Inject_Specified_Container_For_Generic_Interface() { GetRequiredService>() - .ShouldBeOfType>(); + .ShouldBeOfType>(); GetRequiredService>() - .ShouldBeOfType>(); + .ShouldBeOfType>(); GetRequiredService>() - .ShouldBeOfType>(); + .ShouldBeOfType>(); GetRequiredService>() - .ShouldBeOfType>(); + .ShouldBeOfType>(); } } } \ No newline at end of file