您可以从 web.config/app.config 中选择要使用的图像提供程序。首先添加一些适当的配置条目:
<configuration>
<imageProviderConfiguration>
<imageProvider name="fsImageProvider" />
<fsImageProvider directory="C:\Images" />
<azureImageProvider azureKey="foo" storageAccountName="bar" />
</imageProviderConfiguration>
</configuration>
您需要包含类才能从配置文件中访问此信息:
public class ImageProviderSection : ConfigurationSection
{
public const string ImageProviderConfigurationSection = "imageProviderConfiguration";
public const string ImageProviderProperty = "imageProvider";
public const string FSImageProviderProperty = "fsImageProvider";
public const string AzureImageProviderProperty = "azureImageProvider";
[ConfigurationProperty(ImageProviderProperty)]
public ImageProviderElement ImageProvider
{
get { return (ImageProviderElement)this[ImageProviderProperty]; }
set { this[ImageProviderProperty] = value; }
}
[ConfigurationProperty(FSImageProviderProperty)]
public FSImageProviderElement FSImageProvider
{
get { return (FSImageProviderElement)this[FSImageProviderProperty]; }
set { this[FSImageProviderProperty] = value; }
}
[ConfigurationProperty(AzureImageProviderProperty)]
public AzureImageProviderElement AzureImageProvider
{
get { return (AzureImageProviderElement)this[AzureImageProviderProperty]; }
set { this[AzureImageProviderProperty] = value; }
}
}
public class ImageProviderElement : ConfigurationElement
{
private const string nameProperty = "name";
[ConfigurationProperty(nameProperty, IsRequired = true)]
public string Name
{
get { return (string)this[nameProperty]; }
set { this[nameProperty] = value; }
}
}
public class FSImageProviderElement : ConfigurationElement
{
private const string directoryProperty = "directory";
[ConfigurationProperty(directoryProperty, IsRequired = true)]
public string Directory
{
get { return (string)this[directoryProperty]; }
set { this[directoryProperty] = value; }
}
}
public class AzureImageProviderElement : ConfigurationElement
{
private const string azureKeyProperty = "azureKey";
private const string storageAccountNameProperty = "storageAccountName";
[ConfigurationProperty(azureKeyProperty, IsRequired = true)]
public string AzureKey
{
get { return (string)this[azureKeyProperty]; }
set { this[azureKeyProperty] = value; }
}
[ConfigurationProperty(storageAccountNameProperty, IsRequired = true)]
public string StorageAccountName
{
get { return (string)this[storageAccountNameProperty]; }
set { this[storageAccountNameProperty] = value; }
}
}
现在您可以确定在读取配置文件的简单工厂类中使用哪个提供程序:
public static class ImageProviderFactory
{
public static IImageProvider GetImageProvider()
{
ImageProviderSection imageProviderSection = ConfigurationManager.GetSection(ImageProviderSection.ImageProviderConfigurationSection) as ImageProviderSection;
switch (imageProviderSection.ImageProvider.Name)
{
case ImageProviderSection.FSImageProviderProperty:
return new FSImageProvider();
case ImageProviderSection.AzureImageProviderProperty:
return new AzureImageProvider;
default:
throw new Exception("Invalid image provider in configuration");
}
}
}
并在静态类中保留一个实例(或者您可以使用类似的逻辑设置依赖注入):
public static class Providers
{
public static IImageProvider ImageProvider { get; } = ImageProviderFactory.GetImageProvider();
}
每个图像提供者类都可以从配置文件中访问它的相关配置信息:
public interface IImageProvider
{
void Save(string filename, byte[] imageData);
byte[] Get(string filename);
void Delete(string filename);
}
public class FSImageProvider : IImageProvider
{
private string _directory = string.Empty;
public FSImageProvider()
{
ImageProviderSection imageProviderSection = ConfigurationManager.GetSection(ImageProviderSection.ImageProviderConfigurationSection) as ImageProviderSection;
_directory = imageProviderSection.FSImageProvider.Directory.Trim();
if (!_directory.EndsWith("\\"))
_directory += "\\";
}
public void Delete(string filename)
{
File.Delete(_directory + filename);
}
public byte[] Get(string filename)
{
return File.ReadAllBytes(_directory + filename);
}
public void Save(string filename, byte[] imageData)
{
File.WriteAllBytes(_directory + filename, imageData);
}
}
public class AzureImageProvider : IImageProvider
{
private string _azureKey = string.Empty;
private string _storageAccountName = string.Empty;
public AzureImageProvider()
{
ImageProviderSection imageProviderSection = ConfigurationManager.GetSection(ImageProviderSection.ImageProviderConfigurationSection) as ImageProviderSection;
_azureKey = imageProviderSection.AzureImageProvider.AzureKey;
_storageAccountName = imageProviderSection.AzureImageProvider.StorageAccountName;
}
public void Delete(string filename)
{
throw new NotImplementedException();
}
public byte[] Get(string filename)
{
throw new NotImplementedException();
}
public void Save(string filename, byte[] imageData)
{
throw new NotImplementedException();
}
}
但是,如果您想根据图像服务中的某些参数使用不同的图像提供程序,只需从配置中删除 imageProvider 元素并更改工厂以提供基于(例如)枚举的 IImageProvider:
public enum ImageProviders
{
FileSystem,
Azure
}
public static class ImageProviderFactory
{
public static IImageProvider GetImageProvider(ImageProviders provider)
{
switch (provider)
{
case ImageProviders.FileSystem:
return new FSImageProvider();
case ImageProviders.Azure:
return new AzureImageProvider;
default:
throw new Exception("Invalid image provider");
}
}
}