Skip to main content

Azure Blob Storage

Azure Blob Storage is used to store binary assets — camera images (single, panoramic, pre-stitch), videos, location boundary files, device configuration data, and map images. The Infrastructure package provides a generic base class and 7 specialized blob repositories, each scoped to a specific container.

Registration

Blob storage repositories are registered as part of the AddAlertCAStorageServices extension method:

services.AddAlertCAStorageServices(configuration);

This registers BlobServiceClient via Azure.Extensions and all blob repositories as scoped services.

Configuration

{
"BlobStorageOptions": {
"AccountName": "",
"ContainerName": "",
"VideoContainerName": "",
"LocationsContainerName": "",
"DeviceDataContainerName": "",
"MapImagesContainerName": ""
}
}

The BlobServiceClient URL is constructed from the AccountName: https://{AccountName}.blob.core.windows.net. Authentication uses DefaultAzureCredential.

Architecture

Note that SingleImageStorageRepository, PanoImageStorageRepository, and PreStitchImageStorageRepository all share the same ImageStorageRepository implementation pointing to the same container — they are differentiated by their marker interfaces for DI registration.

Base Class: AzureStorageRepository<T>

All blob repositories inherit from AzureStorageRepository<T>, which provides:

MethodDescription
DoesBlobExists(string fileName)Check if a blob exists
GetFileBlobAsync(string fileName)Download blob with metadata as BlobEntity
UploadFileBlobAsync(byte[] content, string fileName, Dictionary<string, string> metadata)Upload with metadata
UploadFileBlobAsync(byte[] content, string fileName, bool overwrite)Upload without metadata
UploadZipBlobAsync(List<BlobZipEntity> entities, string fileName, CompressionLevel level)Create and upload ZIP archive
DeleteFromBlob(string fileName)Delete a blob

Repositories

ImageStorageRepository

Implements ISingleImageStorageRepository, IPanoImageStorageRepository, and IPreStitchImageStorageRepository — a single implementation for all image types.

MethodDescription
UploadImageAsync(byte[] imageArray, string blobName, Dictionary<string, string> metadata)Upload image with metadata (PTZ position, timestamps, etc.)
UploadImageAsync(byte[] imageArray, string blobName)Upload image without metadata
UploadImageAsZipAsync(List<BlobZipEntity> entities, string blobName, CompressionLevel level)ZIP multiple images (used for pre-stitch archives)
DownloadImagesAsync(List<string> blobNames)Parallel bulk download

VideoStorageRepository

Interface: IVideoStorageRepository

MethodDescription
UploadVideoAsync(byte[] videoArray, string blobName)Upload video
DownloadVideoAsync(List<string> blobNames)Parallel bulk download

LocationFileStorageRepository

Interface: ILocationFileStorageRepository

MethodDescription
UploadLocationFileAsync(byte[] bytes, string blobName)Upload with overwrite
DeleteLocationFileAsync(string blobName)Delete file
DownloadLocationFilesAsync(List<string> blobNames)Parallel bulk download

DeviceDataRepository

Interface: IDeviceDataRepository

MethodDescription
UploadDeviceDataFileAsync(byte[] fileData, string blobName)Upload device data
DeleteDeviceDataFileAsync(string blobName)Delete file
DownloadDeviceDataFilesAsync(List<string> blobNames)Parallel bulk download

MapImagesRepository

Interface: IMapImagesRepository

MethodDescription
UploadMapImagesFileAsync(byte[] fileData, string blobName)Upload map/basemap image

Usage Example

using Alert.CA.Infrastructure.Repositories.AzureStorageRepositories.Interfaces;

public class ImageService(
ISingleImageStorageRepository imageRepo,
IPanoImageStorageRepository panoRepo)
{
public async Task StoreImage(byte[] image, string blobName, Dictionary<string, string> metadata)
{
await imageRepo.UploadImageAsync(image, blobName, metadata);
}

public async Task<List<BlobEntity>> DownloadBatch(List<string> blobNames)
{
return await panoRepo.DownloadImagesAsync(blobNames);
}
}