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 } }