using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace OpenDBDiff.Tests.Utils
{
///
/// Summary description for ResourceFileExtractor.
///
public sealed class ResourceFileExtractor
{
#region Static
#region Private fields
private static readonly IDictionary extractors = new ConcurrentDictionary();
#endregion Private fields
#region Public properties
/// Instance of resource extractor for executing assembly
public static ResourceFileExtractor Instance
{
get
{
Assembly _assembly = Assembly.GetCallingAssembly();
string _key = _assembly.GetName().FullName;
if (!extractors.TryGetValue(_key, out ResourceFileExtractor extractor)
&& !extractors.TryGetValue(_key, out extractor))
{
extractor = new ResourceFileExtractor(_assembly, true, null);
extractors.Add(_key, extractor);
}
return extractor;
}
}
#endregion Public properties
#endregion Static
#region Private fields
private readonly ResourceFileExtractor m_baseExtractor;
#endregion Private fields
#region Constructors
///
/// Create instance
///
/// ResourceFilePath in assembly. Example: .Properties.Scripts.
///
public ResourceFileExtractor(string resourceFilePath, ResourceFileExtractor baseExtractor)
: this(Assembly.GetCallingAssembly(), baseExtractor)
{
ResourceFilePath = resourceFilePath;
}
///
/// Create instance
///
///
public ResourceFileExtractor(ResourceFileExtractor baseExtractor)
: this(Assembly.GetCallingAssembly(), baseExtractor)
{
}
///
/// Create instance
///
/// ResourceFilePath in assembly. Example: .Properties.Scripts.
public ResourceFileExtractor(string resourcePath)
: this(Assembly.GetCallingAssembly(), resourcePath)
{
}
///
/// Instance constructor
///
///
///
public ResourceFileExtractor(Assembly assembly, string resourcePath)
: this(assembly ?? Assembly.GetCallingAssembly())
{
ResourceFilePath = resourcePath;
}
///
/// Instance constructor
///
public ResourceFileExtractor()
: this(Assembly.GetCallingAssembly())
{
}
///
/// Instance constructor
///
///
public ResourceFileExtractor(Assembly assembly)
: this(assembly ?? Assembly.GetCallingAssembly(), (ResourceFileExtractor)null)
{
}
///
/// Instance constructor
///
///
///
public ResourceFileExtractor(Assembly assembly, ResourceFileExtractor baseExtractor)
: this(assembly ?? Assembly.GetCallingAssembly(), false, baseExtractor)
{
}
///
/// Instance constructor
///
///
///
///
/// Argument is null.
private ResourceFileExtractor(Assembly assembly, bool isStatic, ResourceFileExtractor baseExtractor)
{
#region Check
if (assembly is null)
{
throw new ArgumentNullException("assembly");
}
#endregion Check
Assembly = assembly;
m_baseExtractor = baseExtractor;
AssemblyName = Assembly.GetName().Name;
IsStatic = isStatic;
ResourceFilePath = ".Resources.";
}
#endregion Constructors
#region Public properties
/// Work assembly
public Assembly Assembly { get; }
/// Work assembly name
public string AssemblyName { get; }
public bool IsStatic { get; set; }
///
/// Path to read resource files. Example: .Resources.Upgrades.
///
public string ResourceFilePath { get; }
public IEnumerable GetFileNames(Func predicate = null)
{
predicate = predicate ?? (s => true);
string _path = AssemblyName + ResourceFilePath;
foreach (string _resourceName in Assembly.GetManifestResourceNames())
{
if (_resourceName.StartsWith(_path) && predicate(_resourceName))
{
yield return _resourceName.Replace(_path, string.Empty);
}
}
}
#endregion Public properties
#region Public methods
public string ReadFileFromResource(string fileName)
{
Stream _stream = ReadFileFromResourceToStream(fileName);
string _result;
StreamReader sr = new StreamReader(_stream);
try
{
_result = sr.ReadToEnd();
}
finally
{
sr.Close();
}
return _result;
}
public string ReadFileFromResourceFormat(string fileName, params object[] formatArgs)
{
return string.Format(ReadFileFromResource(fileName), formatArgs);
}
///
/// Read file in current assembly by specific file name
///
///
///
/// ApplicationException.
public Stream ReadFileFromResourceToStream(string fileName)
{
string _nameResFile = AssemblyName + ResourceFilePath + fileName;
Stream _stream = Assembly.GetManifestResourceStream(_nameResFile);
#region Not found
if (_stream is null)
{
#region Get from base extractor
if (!(m_baseExtractor is null))
{
return m_baseExtractor.ReadFileFromResourceToStream(fileName);
}
#endregion Get from base extractor
throw new ArgumentException("Can't find resource file " + _nameResFile, nameof(fileName));
}
#endregion Not found
return _stream;
}
///
/// Read file in current assembly by specific path
///
/// Specific path
/// Read file name
///
public string ReadSpecificFileFromResource(string specificPath, string fileName)
{
ResourceFileExtractor _ext = new ResourceFileExtractor(Assembly, specificPath);
return _ext.ReadFileFromResource(fileName);
}
#endregion Public methods
}
}