BLOB Storing: Creating a Custom Provider
This document explains how you can create a new storage provider for the BLOB storing system with an example.
Read the BLOB Storing document to understand how to use the BLOB storing system. This document only covers how to create a new storage provider.
Example Implementation
The first step is to create a class implements the IBlobProvider
interface or inherit from the BlobProviderBase
abstract class.
using System.IO;
using System.Threading.Tasks;
using Volo.Abp.BlobStoring;
using Volo.Abp.DependencyInjection;
namespace AbpDemo
{
public class MyCustomBlobProvider : BlobProviderBase, ITransientDependency
{
public override Task SaveAsync(BlobProviderSaveArgs args)
{
//TODO...
}
public override Task<bool> DeleteAsync(BlobProviderDeleteArgs args)
{
//TODO...
}
public override Task<bool> ExistsAsync(BlobProviderExistsArgs args)
{
//TODO...
}
public override Task<Stream> GetOrNullAsync(BlobProviderGetArgs args)
{
//TODO...
}
}
}
MyCustomBlobProvider
inherits from theBlobProviderBase
and overrides theabstract
methods. The actual implementation is up to you.- Implementing
ITransientDependency
registers this class to the Dependency Injection system as a transient service.
Notice: Naming conventions are important. If your class name doesn't end with
BlobProvider
, you must manually register/expose your service for theIBlobProvider
.
That's all. Now, you can configure containers (inside the ConfigureServices
method of your module) to use the MyCustomBlobProvider
class:
Configure<AbpBlobStoringOptions>(options =>
{
options.Containers.ConfigureDefault(container =>
{
container.ProviderType = typeof(MyCustomBlobProvider);
});
});
See the BLOB Storing document if you want to configure a specific container.
BlobContainerConfiguration Extension Method
If you want to provide a simpler configuration, create an extension method for the BlobContainerConfiguration
class:
public static class MyBlobContainerConfigurationExtensions
{
public static BlobContainerConfiguration UseMyCustomBlobProvider(
this BlobContainerConfiguration containerConfiguration)
{
containerConfiguration.ProviderType = typeof(MyCustomBlobProvider);
return containerConfiguration;
}
}
Then you can configure containers easier using the extension method:
Configure<AbpBlobStoringOptions>(options =>
{
options.Containers.ConfigureDefault(container =>
{
container.UseMyCustomBlobProvider();
});
});
Extra Configuration Options
BlobContainerConfiguration
allows to add/remove provider specific configuration objects. If your provider needs to additional configuration, you can create a wrapper class to the BlobContainerConfiguration
for a type-safe configuration option:
public class MyCustomBlobProviderConfiguration
{
public string MyOption1
{
get => _containerConfiguration
.GetConfiguration<string>("MyCustomBlobProvider.MyOption1");
set => _containerConfiguration
.SetConfiguration("MyCustomBlobProvider.MyOption1", value);
}
private readonly BlobContainerConfiguration _containerConfiguration;
public MyCustomBlobProviderConfiguration(
BlobContainerConfiguration containerConfiguration)
{
_containerConfiguration = containerConfiguration;
}
}
Then you can change the MyBlobContainerConfigurationExtensions
class like that:
public static class MyBlobContainerConfigurationExtensions
{
public static BlobContainerConfiguration UseMyCustomBlobProvider(
this BlobContainerConfiguration containerConfiguration,
Action<MyCustomBlobProviderConfiguration> configureAction)
{
containerConfiguration.ProviderType = typeof(MyCustomBlobProvider);
configureAction.Invoke(
new MyCustomBlobProviderConfiguration(containerConfiguration)
);
return containerConfiguration;
}
public static MyCustomBlobProviderConfiguration GetMyCustomBlobProviderConfiguration(
this BlobContainerConfiguration containerConfiguration)
{
return new MyCustomBlobProviderConfiguration(containerConfiguration);
}
}
- Added an action parameter to the
UseMyCustomBlobProvider
method to allow developers to set the additional options. - Added a new
GetMyCustomBlobProviderConfiguration
method to be used insideMyCustomBlobProvider
class to obtain the configured values.
Then anyone can set the MyOption1
as shown below:
Configure<AbpBlobStoringOptions>(options =>
{
options.Containers.ConfigureDefault(container =>
{
container.UseMyCustomBlobProvider(provider =>
{
provider.MyOption1 = "my value";
});
});
});
Finally, you can access to the extra options using the GetMyCustomBlobProviderConfiguration
method:
public class MyCustomBlobProvider : BlobProviderBase, ITransientDependency
{
public override Task SaveAsync(BlobProviderSaveArgs args)
{
var config = args.Configuration.GetMyCustomBlobProviderConfiguration();
var value = config.MyOption1;
//...
}
}
Contribute?
If you create a new provider and you think it can be useful for other developers, please consider to contribute to the ABP on GitHub.