简体   繁体   English

Imagesharp 自定义图像提供程序,缓存不起作用

[英]Imagesharp custom image provider, cache not working

I am trying to make a POC with .net 6 and imagesharp.我正在尝试使用 .net 6 和 imagesharp 制作 POC。 I am trying to implement a custom imageprovider with cache in azure.我正在尝试在 azure 中实现一个带有缓存的自定义图像提供程序。

The images are stored ind a SQL database.图像存储在 SQL 数据库中。 For now I just load an image from a static file.现在我只是从 static 文件加载图像。

The images should be loaded from a database, based on a GUID in the url and the images should be cached in azure.应根据 url 中的 GUID 从数据库加载图像,并且应将图像缓存在 azure 中。

I have not been able to find any tutorial for this scenario.我还没有找到这个场景的任何教程。

I have added the following in the program.cs我在 program.cs 中添加了以下内容

builder.Services.AddImageSharp()
        .Configure<AzureBlobStorageImageProviderOptions>(options =>
        {
            // The "BlobContainers" collection allows registration of multiple containers.
            options.BlobContainers.Add(new AzureBlobContainerClientOptions
            {
                ConnectionString = appSettings["string"],
                ContainerName = "cache"
            });
        })
        .ClearProviders()
        .AddProvider<AzureBlobStorageImageProvider>()
        .Configure<AzureBlobStorageCacheOptions>(options =>
        {
            options.ConnectionString = appSettings["string"];
            options.ContainerName = "cache";

            // Optionally create the cache container on startup if not already created.
            AzureBlobStorageCache.CreateIfNotExists(options, PublicAccessType.None);
        }).AddProvider<LoadImageFromDatabaseProvider>().SetCache<AzureBlobStorageCache>()
        .AddProvider<PhysicalFileSystemProvider>()
        .SetCache<AzureBlobStorageCache>();

My implementation is as follows - keep in mind that it is POC:P我的实现如下 - 请记住它是 POC:P

namespace ImageService
{
    public class LoadImageFromDatabaseProvider : IImageProvider
    {
        private readonly ImageRepository _imageRepository;

        /// <summary>
        /// A match function used by the resolver to identify itself as the correct resolver to use.
        /// </summary>
        private Func<HttpContext, bool> _match;

        public LoadImageFromDatabaseProvider(ImageRepository repository)
        {
            _imageRepository = repository;
        }

        public ProcessingBehavior ProcessingBehavior { get; } = ProcessingBehavior.All;

        public Func<HttpContext, bool> Match
        {
            get => _match ?? IsMatch;
            set => _match = value;
        }

        public async Task<IImageResolver> GetAsync(HttpContext context)
        {
            //Extract image name from the querystring e.g. /image?id=<imagei>

            string filename = Path.GetFileName(context.Request.Path);

            var id = filename.Split(".").FirstOrDefault();

            if (!string.IsNullOrEmpty(id))
            {
                var (image, metadata) = await _imageRepository.Get(id);

                return new ImageResolver(image, metadata);
            }
            return null;
        }

        public bool IsValidRequest(HttpContext context) => true;

        private bool IsMatch(HttpContext context)
        {
            return context.Request.Path.Value.Contains("productimages");
        }
    }

    public class ImageResolver : IImageResolver
    {
        private byte[] _data;
        private Metadata _metadata;

        public ImageResolver(byte[] data, Metadata metadata)
        {
            _data = data;
            _metadata = metadata;
        }

        public Task<Stream> OpenReadAsync()
        {
            return Task.FromResult<Stream>(new MemoryStream(_data));
        }

        Task<SixLabors.ImageSharp.Web.ImageMetadata> IImageResolver.GetMetaDataAsync()
        {
            return Task.FromResult(new SixLabors.ImageSharp.Web.ImageMetadata(_metadata.CreatedOn, _data.Length));
        }
    }

    public class Metadata
    {
        public DateTime CreatedOn { get; internal set; }
    }

    public class ImageRepository

    {
        public ImageRepository()
        {
        }

        public async Task<(byte[] image, Metadata metadata)> Get(string id)
        {
            string path = Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\imgs\estonian-unicorn-in-space.jpg");

            byte[] bytes = System.IO.File.ReadAllBytes(path);

            return (bytes, new Metadata() { CreatedOn = DateTime.Now });
        }
    }
}

I can load an image and the image is cached in azure on the first load.我可以加载图像,并且图像在第一次加载时缓存在 azure 中。 However on the second load the image is still fetch from my provider and not the cache in azure.然而,在第二次加载时,图像仍然是从我的提供程序获取的,而不是 azure 中的缓存。 Also I can see on the timestamp in azure that the cached image is updated.我还可以在 azure 的时间戳上看到缓存的图像已更新。

What am I missing for the cache to work?我缺少什么让缓存工作?

You're returning a brand new created date on ever request in ImageRepository .您将根据ImageRepository的请求返回一个全新的创建日期。

The cache will see that new date and assume the image has been updated and thus requires reprocessing.缓存将看到该新日期并假定图像已更新,因此需要重新处理。 You should be using the real create date.您应该使用真正的创建日期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM