diff --git a/src/Yarhl.IntegrationTests/AssemblyLoadContextExtensionsTests.cs b/src/Yarhl.IntegrationTests/AssemblyLoadContextExtensionsTests.cs
index 51b825b..c78851a 100644
--- a/src/Yarhl.IntegrationTests/AssemblyLoadContextExtensionsTests.cs
+++ b/src/Yarhl.IntegrationTests/AssemblyLoadContextExtensionsTests.cs
@@ -128,7 +128,7 @@ public void FindFormatFromPluginsDir()
string pluginDir = Path.Combine(programDir, "Plugins");
TypeLocator.Instance.LoadContext.TryLoadFromDirectory(pluginDir, false);
- var formats = ConvertersLocator.Instance.Formats;
+ var formats = ConverterLocator.Instance.Formats;
Assert.That(formats, Is.Not.Empty);
Assert.That(
formats.Select(t => t.Name),
@@ -142,11 +142,11 @@ public void FindConverterFromPluginsDir()
string pluginDir = Path.Combine(programDir, "Plugins");
TypeLocator.Instance.LoadContext.TryLoadFromDirectory(pluginDir, false);
- Type poType = ConvertersLocator.Instance.Formats
+ Type poType = ConverterLocator.Instance.Formats
.Single(f => f.Name == "Yarhl.Media.Text.Po")
.Type;
- var converters = ConvertersLocator.Instance.Converters
+ var converters = ConverterLocator.Instance.Converters
.Where(f => f.CanConvert(poType));
Assert.That(converters, Is.Not.Empty);
Assert.That(
diff --git a/src/Yarhl.Plugins/FileFormat/ConvertersLocator.cs b/src/Yarhl.Plugins/FileFormat/ConverterLocator.cs
similarity index 86%
rename from src/Yarhl.Plugins/FileFormat/ConvertersLocator.cs
rename to src/Yarhl.Plugins/FileFormat/ConverterLocator.cs
index 0de2d04..8cc4b42 100644
--- a/src/Yarhl.Plugins/FileFormat/ConvertersLocator.cs
+++ b/src/Yarhl.Plugins/FileFormat/ConverterLocator.cs
@@ -25,18 +25,18 @@ namespace Yarhl.Plugins.FileFormat;
///
/// Locates converter types across assemblies and provide their information.
///
-public sealed class ConvertersLocator
+public sealed class ConverterLocator
{
private static readonly object LockObj = new();
- private static ConvertersLocator? singleInstance;
+ private static ConverterLocator? singleInstance;
private readonly List formatsMetadata;
private readonly List convertersMetadata;
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
- private ConvertersLocator()
+ private ConverterLocator()
{
formatsMetadata = new List();
Formats = formatsMetadata;
@@ -51,11 +51,11 @@ private ConvertersLocator()
/// Gets the plugin manager instance.
///
/// It initializes the manager if needed.
- public static ConvertersLocator Instance {
+ public static ConverterLocator Instance {
get {
if (singleInstance == null) {
lock (LockObj) {
- singleInstance ??= new ConvertersLocator();
+ singleInstance ??= new ConverterLocator();
}
}
@@ -76,6 +76,10 @@ private ConvertersLocator()
///
/// Scan the assemblies from the load context to look for formats and converters.
///
+ ///
+ /// This method is already called when the instance is created. Only needed
+ /// after loading additional assemblies.
+ ///
public void ScanAssemblies()
{
formatsMetadata.Clear();
diff --git a/src/Yarhl.UnitTests/FileFormat/BaseGeneralTests.cs b/src/Yarhl.UnitTests/FileFormat/BaseGeneralTests.cs
index b9acb8b..2cc40a6 100644
--- a/src/Yarhl.UnitTests/FileFormat/BaseGeneralTests.cs
+++ b/src/Yarhl.UnitTests/FileFormat/BaseGeneralTests.cs
@@ -32,7 +32,7 @@ public abstract class BaseGeneralTests
[Test]
public void FormatIsFoundAndIsUnique()
{
- var formats = ConvertersLocator.Instance.Formats
+ var formats = ConverterLocator.Instance.Formats
.Select(f => f.Type);
Assert.That(formats, Does.Contain(typeof(T)));
Assert.That(formats, Is.Unique);
@@ -41,7 +41,7 @@ public void FormatIsFoundAndIsUnique()
[Test]
public void FormatNameMatchAndIsUnique()
{
- var names = ConvertersLocator.Instance.Formats
+ var names = ConverterLocator.Instance.Formats
.Select(f => f.Name);
Assert.That(names, Does.Contain(Name));
Assert.That(names, Is.Unique);
diff --git a/src/Yarhl.UnitTests/Plugins/FileFormat/ConvertersLocatorTests.cs b/src/Yarhl.UnitTests/Plugins/FileFormat/ConvertersLocatorTests.cs
index 1ff08d0..ce2fff0 100644
--- a/src/Yarhl.UnitTests/Plugins/FileFormat/ConvertersLocatorTests.cs
+++ b/src/Yarhl.UnitTests/Plugins/FileFormat/ConvertersLocatorTests.cs
@@ -23,122 +23,173 @@ namespace Yarhl.UnitTests.Plugins.FileFormat;
using System.Linq;
using NUnit.Framework;
using Yarhl.FileFormat;
+using Yarhl.FileSystem;
+using Yarhl.IO;
using Yarhl.Plugins;
+using Yarhl.Plugins.FileFormat;
[TestFixture]
public class ConvertersLocatorTests
{
- /*
[Test]
- public void FormatMetadataContainsNameAndType()
+ public void InstanceIsSingleton()
{
- var format = TypeLocator.Instance.GetFormats()
- .Single(p => p.Metadata.Type == typeof(StringFormat));
- Assert.That(
- format.Metadata.Name,
- Is.EqualTo(typeof(StringFormat).FullName));
+ ConverterLocator instance1 = ConverterLocator.Instance;
+ ConverterLocator instance2 = ConverterLocator.Instance;
+
+ Assert.That(instance1, Is.SameAs(instance2));
}
[Test]
- public void FormatsAreNotDuplicated()
+ public void InstanceIsInitialized()
{
- Assert.That(
- TypeLocator.Instance.GetFormats().Select(f => f.Metadata.Type),
- Is.Unique);
+ ConverterLocator instance = ConverterLocator.Instance;
+
+ Assert.That(instance.Formats, Is.Not.Null);
+ Assert.That(instance.Converters, Is.Not.Null);
}
[Test]
- public void GetFormatsReturnsKnownFormats()
+ public void LocateFormatsWithTypeInfo()
{
- Assert.That(
- TypeLocator.Instance.GetFormats().Select(f => f.Metadata.Name),
- Does.Contain(typeof(BinaryFormat).FullName));
+ InterfaceImplementationInfo myFormat = ConverterLocator.Instance.Formats
+ .FirstOrDefault(i => i.Type == typeof(DerivedSourceFormat));
+
+ Assert.That(myFormat, Is.Not.Null);
+ Assert.That(myFormat.InterfaceImplemented, Is.EqualTo(typeof(IFormat)));
+ Assert.That(myFormat.Name, Is.EqualTo(typeof(DerivedSourceFormat).FullName));
+ }
+
+ [Test]
+ public void FormatsAreNotDuplicated()
+ {
+ InterfaceImplementationInfo[] formats = ConverterLocator.Instance.Formats
+ .Where(f => f.Type == typeof(MySourceFormat))
+ .ToArray();
+
+ Assert.That(formats, Has.Length.EqualTo(1));
}
[Test]
- public void FindSingleInnerConverter()
+ public void LocateFormatsFindYarhlBaseFormats()
{
- IConverter converter = null;
Assert.That(
- () => converter = TypeLocator.Instance
- .FindExtensions>()
- .Single(),
- Throws.Nothing);
+ ConverterLocator.Instance.Formats.Select(f => f.Type),
+ Does.Contain(typeof(BinaryFormat)));
+
Assert.That(
- converter,
- Is.InstanceOf());
- Assert.That(converter.Convert("4"), Is.EqualTo(4));
+ ConverterLocator.Instance.Formats.Select(f => f.Type),
+ Does.Contain(typeof(NodeContainerFormat)));
}
[Test]
- public void FindSingleOuterConverter()
+ public void LocateConvertersWithTypeInfo()
{
- IConverter converter = null;
- Assert.That(
- () => converter = TypeLocator.Instance
- .FindExtensions>()
- .Single(),
- Throws.Nothing);
- Assert.That(converter, Is.InstanceOf());
- Assert.That(converter.Convert("5"), Is.EqualTo(5));
+ ConverterTypeInfo result = ConverterLocator.Instance.Converters
+ .FirstOrDefault(i => i.Type == typeof(MyConverter));
+
+ Assert.That(result, Is.Not.Null);
+ Assert.That(result.InterfaceImplemented, Is.EqualTo(typeof(IConverter)));
+ Assert.That(result.Name, Is.EqualTo(typeof(MyConverter).FullName));
+ Assert.That(result.SourceType, Is.EqualTo(typeof(MySourceFormat)));
+ Assert.That(result.DestinationType, Is.EqualTo(typeof(MyDestFormat)));
}
[Test]
- public void FindTwoConvertersInSameClass()
+ public void ConvertersAreNotDuplicated()
{
- var converter1 = TypeLocator.Instance
- .FindExtensions>();
- Assert.IsInstanceOf(converter1.Single());
-
- Assert.DoesNotThrow(() =>
- converter1.Single(t =>
- Array.Exists(t.GetType().GetInterfaces(), i =>
- i.IsGenericType &&
- i.GenericTypeArguments.Length == 2 &&
- i.GenericTypeArguments[0] == typeof(string) &&
- i.GenericTypeArguments[1] == typeof(int))));
-
- var converter2 = TypeLocator.Instance
- .FindExtensions>();
- Assert.IsInstanceOf(converter2.Single());
-
- Assert.DoesNotThrow(() =>
- converter2.Single(t =>
- Array.Exists(t.GetType().GetInterfaces(), i =>
- i.IsGenericType &&
- i.GenericTypeArguments.Length == 2 &&
- i.GenericTypeArguments[0] == typeof(int) &&
- i.GenericTypeArguments[1] == typeof(string))));
+ ConverterTypeInfo[] results = ConverterLocator.Instance.Converters
+ .Where(f => f.Type == typeof(MyConverter))
+ .ToArray();
+
+ Assert.That(results, Has.Length.EqualTo(1));
}
[Test]
- public void FindDerivedConverter()
+ public void ScanAssembliesDoesNotDuplicateFindings()
{
- var converters = TypeLocator.Instance
- .FindExtensions>();
- IConverter converter = null;
- Assert.That(
- () => converter = converters.Single(),
- Throws.Nothing);
- Assert.IsInstanceOf(converter);
- Assert.IsInstanceOf(converter);
- Assert.That(converter.Convert("3"), Is.EqualTo(3));
+ ConverterLocator.Instance.ScanAssemblies();
+
+ FormatsAreNotDuplicated();
+ ConvertersAreNotDuplicated();
+ }
+
+ [Test]
+ public void LocateConverterWithParameters()
+ {
+ ConverterTypeInfo[] results = ConverterLocator.Instance.Converters
+ .Where(f => f.Type == typeof(MyConverterParametrized))
+ .ToArray();
+
+ Assert.That(results.Length, Is.EqualTo(1));
}
[Test]
- public void FindConvertsWithOtherInterfaces()
+ public void LocateSingleInnerConverter()
{
- IConverter converter = null;
+ ConverterTypeInfo converter = ConverterLocator.Instance.Converters
+ .FirstOrDefault(c => c.Type == typeof(SingleOuterConverter.SingleInnerConverter));
+
+ Assert.That(converter, Is.Not.Null);
+ }
+
+ [Test]
+ public void LocateSingleOuterConverter()
+ {
+ ConverterTypeInfo converter = ConverterLocator.Instance.Converters
+ .FirstOrDefault(c => c.Type == typeof(SingleOuterConverter));
+
+ Assert.That(converter, Is.Not.Null);
+ }
+
+ [Test]
+ public void LocateTwoConvertersInSameClass()
+ {
+ ConverterTypeInfo[] converters = ConverterLocator.Instance.Converters
+ .Where(c => c.Type == typeof(TwoConverters))
+ .ToArray();
+
+ Assert.That(converters.Length, Is.EqualTo(2));
+ Assert.That(
+ Array.Exists(
+ converters,
+ c => c.InterfaceImplemented == typeof(IConverter)),
+ Is.True);
Assert.That(
- () => converter = TypeLocator.Instance
- .FindExtensions>()
- .Single(),
- Throws.Nothing);
- Assert.That(converter, Is.InstanceOf());
- Assert.That(converter.Convert("3"), Is.EqualTo(3));
+ Array.Exists(
+ converters,
+ c => c.SourceType == typeof(MySourceFormat) && c.DestinationType == typeof(MyDestFormat)),
+ Is.True);
+
+ Assert.That(
+ Array.Exists(
+ converters,
+ c => c.InterfaceImplemented == typeof(IConverter)),
+ Is.True);
Assert.That(
- ((ConverterAndOtherInterface)converter).Dispose,
- Throws.Nothing);
+ Array.Exists(
+ converters,
+ c => c.SourceType == typeof(MyDestFormat) && c.DestinationType == typeof(MySourceFormat)),
+ Is.True);
+ }
+
+ [Test]
+ public void LocateDerivedConverter()
+ {
+ ConverterTypeInfo[] converters = ConverterLocator.Instance.Converters
+ .Where(c => c.Type == typeof(DerivedConverter))
+ .ToArray();
+
+ Assert.That(converters.Length, Is.EqualTo(1));
+ }
+
+ [Test]
+ public void LocateConvertsWithOtherInterfaces()
+ {
+ ConverterTypeInfo[] converters = ConverterLocator.Instance.Converters
+ .Where(c => c.Type == typeof(ConverterAndOtherInterface))
+ .ToArray();
+
+ Assert.That(converters.Length, Is.EqualTo(1));
}
- */
}
diff --git a/src/Yarhl.UnitTests/Plugins/FileFormat/TestConvertersDefinition.cs b/src/Yarhl.UnitTests/Plugins/FileFormat/TestConvertersDefinition.cs
index c37af95..1effa18 100644
--- a/src/Yarhl.UnitTests/Plugins/FileFormat/TestConvertersDefinition.cs
+++ b/src/Yarhl.UnitTests/Plugins/FileFormat/TestConvertersDefinition.cs
@@ -41,74 +41,57 @@ public MyDestFormat Convert(MySourceFormat source)
}
}
-public class SingleOuterConverterExample : IConverter
+public class SingleOuterConverter : IConverter
{
- public uint Convert(string source)
+ public MyDestFormat Convert(MySourceFormat source)
{
- return System.Convert.ToUInt32(source);
+ return new MyDestFormat();
}
- public class SingleInnerConverterExample : IConverter
+ public class SingleInnerConverter : IConverter
{
- public ulong Convert(string source)
+ public MyDestFormat Convert(MySourceFormat source)
{
- return System.Convert.ToUInt64(source);
+ return new MyDestFormat();
}
}
}
public sealed class ConverterAndOtherInterface :
- IConverter,
+ IConverter,
IDisposable
{
- public short Convert(string source)
+ public MyDestFormat Convert(MySourceFormat source)
{
- return System.Convert.ToInt16(source);
+ return new MyDestFormat();
}
public void Dispose()
{
- // Test dispose
- }
-}
-
-public class TwoConvertersExample :
- IConverter, IConverter
-{
- public int Convert(string source)
- {
- return System.Convert.ToInt32(source);
- }
-
- public string Convert(int source)
- {
- return source.ToString();
+ GC.SuppressFinalize(this);
}
}
-public class DuplicatedConverter1 :
- IConverter
+public class TwoConverters :
+ IConverter,
+ IConverter
{
- public sbyte Convert(string source)
+ public MyDestFormat Convert(MySourceFormat source)
{
- return System.Convert.ToSByte(source);
+ return new MyDestFormat();
}
-}
-public class DuplicatedConverter2 :
- IConverter
-{
- public sbyte Convert(string source)
+ public MySourceFormat Convert(MyDestFormat source)
{
- return System.Convert.ToSByte(source);
+ return new MySourceFormat();
}
}
-public abstract class BaseAbstractConverter : IConverter
+public abstract class BaseAbstractConverter : IConverter
{
- public long Convert(string source)
+ public MyDestFormat Convert(MySourceFormat source)
{
- return System.Convert.ToInt64(source);
+ return new MyDestFormat();
}
}