Files
FileServices/FileService/FileServiceProvider.cs

140 lines
5.2 KiB
C#
Raw Normal View History

using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;
using Ufangx.FileServices.Abstractions;
using Ufangx.FileServices.Models;
using System.Linq;
using System.Threading.Tasks;
using System.IO;
using Microsoft.Extensions.DependencyInjection;
namespace Ufangx.FileServices
{
public class FileServiceProvider : IFileServiceProvider,IDisposable
{
private readonly FileServiceOptions options;
private readonly IServiceProvider serviceProvider;
private readonly IServiceScope serviceScope;
public FileServiceProvider(IOptions<FileServiceOptions> options, IServiceProvider serviceProvider)
{
this.options = options.Value;
this.serviceScope = serviceProvider.CreateScope();
this.serviceProvider = serviceScope.ServiceProvider;
}
public IEnumerable<string> AuthenticationSchemes => options.AuthenticationSchemes;
public string DefaultSchemeName => options.DefaultTopic;
FileServiceScheme GetScheme(string name) {
if (string.IsNullOrWhiteSpace(name))
{
throw new ArgumentException("message", nameof(name));
}
var topic = options.SchemeMap[name];
if (topic == null)
{
throw new Exception($"无效的文件服务方案名称“{name}”");
}
return topic;
}
public IFileHandler GetHandler(string schemeName)
{
if (string.IsNullOrWhiteSpace(schemeName)) return null;
var scheme = GetScheme(schemeName);
if (scheme.HandlerType == null) return null;
if (!typeof(IFileHandler).IsAssignableFrom(scheme.HandlerType)) {
throw new Exception($"类型“{scheme.HandlerType.FullName}”没有实现“{typeof(IFileHandler).FullName}”接口");
}
return serviceProvider.GetService(scheme.HandlerType) as IFileHandler;
}
public string GetStoreDirectory(string schemeName)
=> string.IsNullOrWhiteSpace(schemeName) ? string.Empty : GetScheme(schemeName).StoreDirectory;
public async Task<string> GenerateFileName(string originName, string schemeName, string directory = null)
{
if (string.IsNullOrWhiteSpace(originName))
{
throw new ArgumentException("message", nameof(originName));
}
FileNameRule nameRule = options?.RuleOptions?.Rule ?? FileNameRule.Ascending;
if (nameRule == FileNameRule.Custom && options?.RuleOptions?.Custom==null) {
nameRule = FileNameRule.Ascending;
}
if (directory == null) { directory = string.Empty; }
directory = Path.Combine(GetStoreDirectory(schemeName), directory);
string fileName;
switch (nameRule)
{
case FileNameRule.Ascending:
fileName = Path.Combine(directory, originName);
int index = 0;
var fileService = GetFileService();
while (await fileService.Exists(fileName))
{
fileName = Path.Combine(directory, $"{Path.GetFileNameWithoutExtension(originName)}({++index}){Path.GetExtension(originName)}");
}
break;
case FileNameRule.Date:
fileName = Path.Combine(directory, string.Format(options?.RuleOptions?.Format ?? "{0:yyyyMMddHHmmss}", DateTime.Now) + Path.GetExtension(originName));
break;
case FileNameRule.Custom:
fileName = Path.Combine(directory, options.RuleOptions.Custom(originName));
break;
default:
fileName = Path.Combine(directory, originName);
break;
}
return fileName.Replace('\\', '/');
}
public FileValidateResult Validate(string schemeName, string fileName,long fileSize)
{
if (string.IsNullOrWhiteSpace(schemeName)) {
return FileValidateResult.Successfully;
}
var scheme = GetScheme(schemeName);
if (scheme.LimitedSize.HasValue && scheme.LimitedSize.Value < fileSize) {
return FileValidateResult.Limited;
}
string ext = Path.GetExtension(fileName);
return
scheme.SupportExtensions==null
|| scheme.SupportExtensions.Count()==0
|| scheme.SupportExtensions.Any(e => string.Equals(ext, e, StringComparison.OrdinalIgnoreCase))
? FileValidateResult.Successfully : FileValidateResult.Invalid;
}
public IFileService GetFileService()
{
return serviceProvider.GetService<IFileService>();
}
public IResumableService GetResumableService()
{
return serviceProvider.GetService<IResumableService>();
}
public void Dispose()
{
serviceScope.Dispose();
}
public IEnumerable<FileServiceScheme> GetSchemes()
{
return options.Schemes;
}
}
}