From f5caaaaa85bdf412352d63c600551541cce0cda5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 26 May 2020 06:11:13 +0300 Subject: [PATCH] Implemented basic BlobContainerFactory. --- .../BlobStoring/BlobContainerConfiguration.cs | 12 ++- .../BlobContainerConfigurationDictionary.cs | 36 ++++++- .../Abp/BlobStoring/BlobContainerFactory.cs | 58 +++++++++++ .../BlobContainerToProviderAdapter.cs | 99 +++++++++++++++++++ .../BlobStoring/Providers/BlobProviderArgs.cs | 31 ++++++ .../Providers/BlobProviderDeleteArgs.cs | 21 ++++ .../Providers/BlobProviderExistsArgs.cs | 21 ++++ .../Providers/BlobProviderGetArgs.cs | 21 ++++ .../Providers/BlobProviderSaveArgs.cs | 41 ++++++++ .../BlobStoring/Providers/IBlobProvider.cs | 18 ++++ .../Volo/Abp/DynamicProxy/ProxyHelper.cs | 9 +- .../Volo.Abp.BlobStoring.Tests.csproj | 1 + .../AbpBlobStoringOptions_Tests.cs | 5 +- .../Abp/BlobStoring/AbpBlobStoringTestBase.cs | 5 +- .../BlobStoring/AbpBlobStoringTestModule.cs | 21 +++- .../BlobStoring/BlobContainerFactory_Tests.cs | 78 +++++++++++++++ .../BlobContainerNameAttribute_Tests.cs | 20 +--- .../BlobStoring/Fakes/FakeBlobProvider1.cs | 34 +++++++ .../BlobStoring/Fakes/FakeBlobProvider2.cs | 34 +++++++ .../Abp/BlobStoring/Fakes/FakeProviders.cs | 20 ++++ .../Volo/Abp/BlobStoring/TestContainer1.cs | 12 --- .../BlobStoring/TestObjects/TestContainer1.cs | 7 ++ .../BlobStoring/TestObjects/TestContainer2.cs | 8 ++ .../BlobStoring/TestObjects/TestContainer3.cs | 7 ++ 24 files changed, 581 insertions(+), 38 deletions(-) create mode 100644 framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerFactory.cs create mode 100644 framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobContainerToProviderAdapter.cs create mode 100644 framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderArgs.cs create mode 100644 framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderDeleteArgs.cs create mode 100644 framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderExistsArgs.cs create mode 100644 framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderGetArgs.cs create mode 100644 framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderSaveArgs.cs create mode 100644 framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/IBlobProvider.cs create mode 100644 framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/BlobContainerFactory_Tests.cs create mode 100644 framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/Fakes/FakeBlobProvider1.cs create mode 100644 framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/Fakes/FakeBlobProvider2.cs create mode 100644 framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/Fakes/FakeProviders.cs delete mode 100644 framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/TestContainer1.cs create mode 100644 framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/TestObjects/TestContainer1.cs create mode 100644 framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/TestObjects/TestContainer2.cs create mode 100644 framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/TestObjects/TestContainer3.cs 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 096e5f9a67..3974fe4d98 100644 --- a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerConfiguration.cs +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerConfiguration.cs @@ -1,9 +1,19 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using JetBrains.Annotations; namespace Volo.Abp.BlobStoring { public class BlobContainerConfiguration : Dictionary { + [NotNull] + public string Name { get; } + public Type ProviderType { get; set; } + + public BlobContainerConfiguration([NotNull] string name) + { + Name = Check.NotNullOrWhiteSpace(name, nameof(name)); + } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerConfigurationDictionary.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerConfigurationDictionary.cs index 4ea2d2ba6e..391d0c51a1 100644 --- a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerConfigurationDictionary.cs +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerConfigurationDictionary.cs @@ -1,22 +1,50 @@ using System; using System.Collections.Generic; +using System.IO; +using JetBrains.Annotations; namespace Volo.Abp.BlobStoring { public class BlobContainerConfigurationDictionary : Dictionary { - public BlobContainerConfigurationDictionary Configure(Action configureAction) + public BlobContainerConfiguration Default { get; } + + public BlobContainerConfigurationDictionary() + { + Default = new BlobContainerConfiguration("_default"); + } + + public BlobContainerConfigurationDictionary Configure( + Action configureAction) { return Configure( BlobContainerNameAttribute.GetContainerName(), configureAction ); } - - public BlobContainerConfigurationDictionary Configure(string name, Action configureAction) + + public BlobContainerConfigurationDictionary Configure( + [NotNull] string name, + [NotNull] Action configureAction) + { + Check.NotNullOrWhiteSpace(name, nameof(name)); + Check.NotNull(configureAction, nameof(configureAction)); + + configureAction(this.GetOrAdd(name, () => new BlobContainerConfiguration(name))); + + return this; + } + + public BlobContainerConfigurationDictionary ConfigureDefault(Action configureAction) { - configureAction(this.GetOrAdd(name, () => new BlobContainerConfiguration())); + configureAction(Default); return this; } + + public BlobContainerConfiguration GetOrDefaultConfiguration(string name) + { + return AbpDictionaryExtensions.GetOrDefault(this, name) ?? + Default; + } } } \ 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 new file mode 100644 index 0000000000..731012a3b2 --- /dev/null +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerFactory.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using JetBrains.Annotations; +using Microsoft.Extensions.Options; +using Volo.Abp.BlobStoring.Providers; +using Volo.Abp.DependencyInjection; +using Volo.Abp.DynamicProxy; + +namespace Volo.Abp.BlobStoring +{ + public class BlobContainerFactory : IBlobContainerFactory, ITransientDependency + { + public IEnumerable BlobProviders { get; } + + protected AbpBlobStoringOptions Options { get; } + + public BlobContainerFactory( + IOptions options, + IEnumerable blobProviders) + { + BlobProviders = blobProviders; + Options = options.Value; + } + + public virtual IBlobContainer Create(string name, CancellationToken cancellationToken = default) + { + var configuration = Options.Containers.GetOrDefaultConfiguration(name); + return new BlobContainerToProviderAdapter( + name, + configuration, + GetProvider(configuration) + ); + } + + [NotNull] + protected virtual IBlobProvider GetProvider(BlobContainerConfiguration configuration) + { + if (!BlobProviders.Any()) + { + throw new AbpException("No BLOB Storage provider was registered! At least one provider must be registered to be able to use the Blog Storing System."); + } + + foreach (var provider in BlobProviders) + { + if (ProxyHelper.GetUnProxiedType(provider).IsAssignableTo(configuration.ProviderType)) + { + return provider; + } + } + + throw new AbpException( + $"Could not find the BLOB Storage provider with the type ({configuration.ProviderType.AssemblyQualifiedName}) configured for the container {configuration.Name}" + ); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobContainerToProviderAdapter.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobContainerToProviderAdapter.cs new file mode 100644 index 0000000000..c4aa6e9c6f --- /dev/null +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobContainerToProviderAdapter.cs @@ -0,0 +1,99 @@ +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace Volo.Abp.BlobStoring.Providers +{ + 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/Providers/BlobProviderArgs.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderArgs.cs new file mode 100644 index 0000000000..dc7029f3a2 --- /dev/null +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderArgs.cs @@ -0,0 +1,31 @@ +using System.Threading; +using JetBrains.Annotations; + +namespace Volo.Abp.BlobStoring.Providers +{ + public abstract class BlobProviderArgs + { + [NotNull] + public string ContainerName { get; } + + [NotNull] + public BlobContainerConfiguration Configuration { get; } + + [NotNull] + public string BlobName { get; } + + public CancellationToken CancellationToken { get; } + + protected BlobProviderArgs( + [NotNull] string containerName, + [NotNull] BlobContainerConfiguration configuration, + [NotNull] string blobName, + CancellationToken cancellationToken = default) + { + ContainerName = Check.NotNullOrWhiteSpace(containerName, nameof(containerName)); + Configuration = Check.NotNull(configuration, nameof(configuration)); + BlobName = Check.NotNullOrWhiteSpace(blobName, nameof(blobName)); + CancellationToken = cancellationToken; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderDeleteArgs.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderDeleteArgs.cs new file mode 100644 index 0000000000..e7545a0241 --- /dev/null +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderDeleteArgs.cs @@ -0,0 +1,21 @@ +using System.Threading; +using JetBrains.Annotations; + +namespace Volo.Abp.BlobStoring.Providers +{ + public class BlobProviderDeleteArgs : BlobProviderArgs + { + public BlobProviderDeleteArgs( + [NotNull] string containerName, + [NotNull] BlobContainerConfiguration configuration, + [NotNull] string blobName, + CancellationToken cancellationToken = default) + : base( + containerName, + configuration, + blobName, + cancellationToken) + { + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderExistsArgs.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderExistsArgs.cs new file mode 100644 index 0000000000..686c438d08 --- /dev/null +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderExistsArgs.cs @@ -0,0 +1,21 @@ +using System.Threading; +using JetBrains.Annotations; + +namespace Volo.Abp.BlobStoring.Providers +{ + public class BlobProviderExistsArgs : BlobProviderArgs + { + public BlobProviderExistsArgs( + [NotNull] string containerName, + [NotNull] BlobContainerConfiguration configuration, + [NotNull] string blobName, + CancellationToken cancellationToken = default) + : base( + containerName, + configuration, + blobName, + cancellationToken) + { + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderGetArgs.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderGetArgs.cs new file mode 100644 index 0000000000..949cc1053c --- /dev/null +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderGetArgs.cs @@ -0,0 +1,21 @@ +using System.Threading; +using JetBrains.Annotations; + +namespace Volo.Abp.BlobStoring.Providers +{ + public class BlobProviderGetArgs : BlobProviderArgs + { + public BlobProviderGetArgs( + [NotNull] string containerName, + [NotNull] BlobContainerConfiguration configuration, + [NotNull] string blobName, + CancellationToken cancellationToken = default) + : base( + containerName, + configuration, + blobName, + cancellationToken) + { + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderSaveArgs.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderSaveArgs.cs new file mode 100644 index 0000000000..fb482f8e5a --- /dev/null +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/BlobProviderSaveArgs.cs @@ -0,0 +1,41 @@ +using System.IO; +using System.Threading; +using JetBrains.Annotations; + +namespace Volo.Abp.BlobStoring.Providers +{ + public class BlobProviderSaveArgs + { + [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, + CancellationToken cancellationToken = default) + { + 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/Providers/IBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/IBlobProvider.cs new file mode 100644 index 0000000000..23e67502f0 --- /dev/null +++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/Providers/IBlobProvider.cs @@ -0,0 +1,18 @@ +using System.IO; +using System.Threading.Tasks; + +namespace Volo.Abp.BlobStoring.Providers +{ + public interface IBlobProvider + { + Task SaveAsync(BlobProviderSaveArgs args); + + Task DeleteAsync(BlobProviderDeleteArgs args); + + Task ExistsAsync(BlobProviderExistsArgs args); + + Task GetAsync(BlobProviderGetArgs args); + + Task GetOrNullAsync(BlobProviderGetArgs args); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/ProxyHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/ProxyHelper.cs index 96a1915e26..db7ff4b869 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/ProxyHelper.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DynamicProxy/ProxyHelper.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using System.Reflection; namespace Volo.Abp.DynamicProxy @@ -6,6 +7,7 @@ namespace Volo.Abp.DynamicProxy public static class ProxyHelper { private const string ProxyNamespace = "Castle.Proxies"; + /// /// Returns dynamic proxy target object if this is a proxied object, otherwise returns the given object. /// It supports Castle Dynamic Proxies. @@ -28,5 +30,10 @@ namespace Volo.Abp.DynamicProxy return targetField.GetValue(obj); } + + public static Type GetUnProxiedType(object obj) + { + return UnProxy(obj).GetType(); + } } } diff --git a/framework/test/Volo.Abp.BlobStoring.Tests/Volo.Abp.BlobStoring.Tests.csproj b/framework/test/Volo.Abp.BlobStoring.Tests/Volo.Abp.BlobStoring.Tests.csproj index d1776263a2..5ae7e10c44 100644 --- a/framework/test/Volo.Abp.BlobStoring.Tests/Volo.Abp.BlobStoring.Tests.csproj +++ b/framework/test/Volo.Abp.BlobStoring.Tests/Volo.Abp.BlobStoring.Tests.csproj @@ -8,6 +8,7 @@ + diff --git a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/AbpBlobStoringOptions_Tests.cs b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/AbpBlobStoringOptions_Tests.cs index 250ec0b737..b4cd5e3be1 100644 --- a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/AbpBlobStoringOptions_Tests.cs +++ b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/AbpBlobStoringOptions_Tests.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using Microsoft.Extensions.Options; using Shouldly; +using Volo.Abp.BlobStoring.TestObjects; using Xunit; namespace Volo.Abp.BlobStoring @@ -18,11 +19,11 @@ namespace Volo.Abp.BlobStoring public void Should_Property_Set_And_Get_Options_For_Different_Containers() { var testContainer1Config = _options.Containers - .GetOrDefault(BlobContainerNameAttribute.GetContainerName()); + .GetOrDefaultConfiguration(BlobContainerNameAttribute.GetContainerName()); testContainer1Config.ShouldContainKeyAndValue("TestConfig1", "TestValue1"); var testContainer2Config = _options.Containers - .GetOrDefault(BlobContainerNameAttribute.GetContainerName()); + .GetOrDefaultConfiguration(BlobContainerNameAttribute.GetContainerName()); testContainer2Config.ShouldContainKeyAndValue("TestConfig2", "TestValue2"); } } diff --git a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/AbpBlobStoringTestBase.cs b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/AbpBlobStoringTestBase.cs index 7027cb8147..07e34c599f 100644 --- a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/AbpBlobStoringTestBase.cs +++ b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/AbpBlobStoringTestBase.cs @@ -4,6 +4,9 @@ namespace Volo.Abp.BlobStoring { public abstract class AbpBlobStoringTestBase : AbpIntegratedTest { - + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/AbpBlobStoringTestModule.cs b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/AbpBlobStoringTestModule.cs index 429349d28f..dc29bff71c 100644 --- a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/AbpBlobStoringTestModule.cs +++ b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/AbpBlobStoringTestModule.cs @@ -1,25 +1,42 @@ -using Volo.Abp.Modularity; +using Microsoft.Extensions.DependencyInjection; +using NSubstitute; +using Volo.Abp.Autofac; +using Volo.Abp.BlobStoring.Fakes; +using Volo.Abp.BlobStoring.Providers; +using Volo.Abp.BlobStoring.TestObjects; +using Volo.Abp.Modularity; namespace Volo.Abp.BlobStoring { [DependsOn( typeof(AbpBlobStoringModule), - typeof(AbpTestBaseModule) + typeof(AbpTestBaseModule), + typeof(AbpAutofacModule) )] public class AbpBlobStoringTestModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { + context.Services.AddSingleton(Substitute.For()); + context.Services.AddSingleton(Substitute.For()); + Configure(options => { options.Containers + .ConfigureDefault(container => + { + container["TestConfigDefault"] = "TestValueDefault"; + container.ProviderType = typeof(FakeBlobProvider1); + }) .Configure(container => { container["TestConfig1"] = "TestValue1"; + container.ProviderType = typeof(FakeBlobProvider1); }) .Configure(container => { container["TestConfig2"] = "TestValue2"; + container.ProviderType = typeof(FakeBlobProvider2); }); }); } diff --git a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/BlobContainerFactory_Tests.cs b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/BlobContainerFactory_Tests.cs new file mode 100644 index 0000000000..ce1bd0eec6 --- /dev/null +++ b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/BlobContainerFactory_Tests.cs @@ -0,0 +1,78 @@ +using System.Threading.Tasks; +using NSubstitute; +using Shouldly; +using Volo.Abp.BlobStoring.Fakes; +using Volo.Abp.BlobStoring.Providers; +using Volo.Abp.BlobStoring.TestObjects; +using Xunit; + +namespace Volo.Abp.BlobStoring +{ + public class BlobContainerFactory_Tests : AbpBlobStoringTestBase + { + private readonly IBlobContainerFactory _factory; + private readonly FakeProviders _fakeProviders; + + public BlobContainerFactory_Tests() + { + _factory = GetRequiredService(); + _fakeProviders = GetRequiredService(); + } + + [Fact] + public async Task Should_Create_Containers_With_Configured_Providers() + { + // TestContainer1 with FakeBlobProvider1 + + await _fakeProviders.Provider1 + .DidNotReceiveWithAnyArgs() + .ExistsAsync(default); + + await _factory + .Create() + .ExistsAsync("TestBlob1"); + + await _fakeProviders.Provider1 + .Received(1) + .ExistsAsync(Arg.Is(args => + args.ContainerName == BlobContainerNameAttribute.GetContainerName() && + args.BlobName == "TestBlob1" + ) + ); + + // TestContainer2 with FakeBlobProvider2 + + await _fakeProviders.Provider2 + .DidNotReceiveWithAnyArgs() + .ExistsAsync(default); + + await _factory + .Create() + .ExistsAsync("TestBlob2"); + + await _fakeProviders.Provider2 + .Received(1) + .ExistsAsync(Arg.Is(args => + args.ContainerName == BlobContainerNameAttribute.GetContainerName() && + args.BlobName == "TestBlob2" + ) + ); + + // TestContainer3 with FakeBlobProvider1 (default provider) + + _fakeProviders.Provider1.ClearReceivedCalls(); + + await _factory + .Create() + .ExistsAsync("TestBlob3"); + + await _fakeProviders.Provider1 + .Received(1) + .ExistsAsync(Arg.Is(t => + t.ContainerName == BlobContainerNameAttribute.GetContainerName() && + t.BlobName == "TestBlob3" + ) + ); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/BlobContainerNameAttribute_Tests.cs b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/BlobContainerNameAttribute_Tests.cs index a482e7811b..242b195a0c 100644 --- a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/BlobContainerNameAttribute_Tests.cs +++ b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/BlobContainerNameAttribute_Tests.cs @@ -1,4 +1,5 @@ using Shouldly; +using Volo.Abp.BlobStoring.TestObjects; using Xunit; namespace Volo.Abp.BlobStoring @@ -9,27 +10,16 @@ namespace Volo.Abp.BlobStoring public void Should_Get_Specified_Name() { BlobContainerNameAttribute - .GetContainerName() - .ShouldBe("ContName2"); + .GetContainerName() + .ShouldBe("Test2"); } [Fact] public void Should_Get_Full_Class_Name_If_Not_Specified() { BlobContainerNameAttribute - .GetContainerName() - .ShouldBe(typeof(MyContainerType1).FullName); - } - - private class MyContainerType1 - { - - } - - [BlobContainerName("ContName2")] - private class MyContainerType2 - { - + .GetContainerName() + .ShouldBe(typeof(TestContainer1).FullName); } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/Fakes/FakeBlobProvider1.cs b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/Fakes/FakeBlobProvider1.cs new file mode 100644 index 0000000000..4eb401e0fb --- /dev/null +++ b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/Fakes/FakeBlobProvider1.cs @@ -0,0 +1,34 @@ +using System.IO; +using System.Threading.Tasks; +using Volo.Abp.BlobStoring.Providers; + +namespace Volo.Abp.BlobStoring.Fakes +{ + public class FakeBlobProvider1 : IBlobProvider + { + public virtual Task SaveAsync(BlobProviderSaveArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task DeleteAsync(BlobProviderDeleteArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task ExistsAsync(BlobProviderExistsArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task GetAsync(BlobProviderGetArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task GetOrNullAsync(BlobProviderGetArgs args) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/Fakes/FakeBlobProvider2.cs b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/Fakes/FakeBlobProvider2.cs new file mode 100644 index 0000000000..233bed8d16 --- /dev/null +++ b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/Fakes/FakeBlobProvider2.cs @@ -0,0 +1,34 @@ +using System.IO; +using System.Threading.Tasks; +using Volo.Abp.BlobStoring.Providers; + +namespace Volo.Abp.BlobStoring.Fakes +{ + public class FakeBlobProvider2 : IBlobProvider + { + public virtual Task SaveAsync(BlobProviderSaveArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task DeleteAsync(BlobProviderDeleteArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task ExistsAsync(BlobProviderExistsArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task GetAsync(BlobProviderGetArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task GetOrNullAsync(BlobProviderGetArgs args) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/Fakes/FakeProviders.cs b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/Fakes/FakeProviders.cs new file mode 100644 index 0000000000..045f835e59 --- /dev/null +++ b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/Fakes/FakeProviders.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Linq; +using Volo.Abp.BlobStoring.Providers; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.BlobStoring.Fakes +{ + public class FakeProviders : ISingletonDependency + { + public FakeBlobProvider1 Provider1 { get; } + + public FakeBlobProvider2 Provider2 { get; } + + public FakeProviders(IEnumerable providers) + { + Provider1 = providers.OfType().Single(); + Provider2 = providers.OfType().Single(); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/TestContainer1.cs b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/TestContainer1.cs deleted file mode 100644 index 1c11f61d50..0000000000 --- a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/TestContainer1.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Volo.Abp.BlobStoring -{ - public class TestContainer1 - { - - } - - public class TestContainer2 - { - - } -} \ No newline at end of file diff --git a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/TestObjects/TestContainer1.cs b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/TestObjects/TestContainer1.cs new file mode 100644 index 0000000000..61c84a1148 --- /dev/null +++ b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/TestObjects/TestContainer1.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.BlobStoring.TestObjects +{ + public class TestContainer1 + { + + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/TestObjects/TestContainer2.cs b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/TestObjects/TestContainer2.cs new file mode 100644 index 0000000000..3193da3749 --- /dev/null +++ b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/TestObjects/TestContainer2.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.BlobStoring.TestObjects +{ + [BlobContainerName("Test2")] + public class TestContainer2 + { + + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/TestObjects/TestContainer3.cs b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/TestObjects/TestContainer3.cs new file mode 100644 index 0000000000..b96a71c1b7 --- /dev/null +++ b/framework/test/Volo.Abp.BlobStoring.Tests/Volo/Abp/BlobStoring/TestObjects/TestContainer3.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.BlobStoring.TestObjects +{ + public class TestContainer3 + { + + } +} \ No newline at end of file