From c621c79af219077631340be5915d15ef8a8c4a63 Mon Sep 17 00:00:00 2001 From: Gennady Verdel Date: Wed, 6 Mar 2019 10:07:27 +0200 Subject: [PATCH 1/9] #36 Adding Patterns Calculator for unified assembly path calculation --- Solid.Core.Tests/PatternsCalculatorTests.cs | 110 ++++++++++++++++++++ Solid.Core.Tests/Solid.Core.Tests.csproj | 19 ++++ Solid.sln | 25 ++++- 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 Solid.Core.Tests/PatternsCalculatorTests.cs create mode 100644 Solid.Core.Tests/Solid.Core.Tests.csproj diff --git a/Solid.Core.Tests/PatternsCalculatorTests.cs b/Solid.Core.Tests/PatternsCalculatorTests.cs new file mode 100644 index 00000000..6e7b6f8f --- /dev/null +++ b/Solid.Core.Tests/PatternsCalculatorTests.cs @@ -0,0 +1,110 @@ +using System.Collections.Generic; +using System.Linq; +using FluentAssertions; +using Xunit; + +namespace Solid.Core.Tests +{ + public class PatternsCalculatorTests + { + public class InputData + { + public InputData(string[] prefixes, string[] namespaces, string[] extensions) + { + Prefixes = prefixes; + Namespaces = namespaces; + Extensions = extensions; + } + + public string[] Prefixes { get; } + public string[] Namespaces { get; } + public string[] Extensions { get; } + } + + public static IEnumerable NonEmptyCollectionsData => + new List + { + new object[] + { + new InputData(new[] {"Prefix"}, new[] {"Namespace"}, new[] {".ext"}), + new[] {new PatternDescription("Prefix", "Namespace", ".ext")} + }, + new object[] + { + new InputData(new[] {"Prefix"}, new[] {"Namespace1", "Namespace2"}, new[] {".ext"}), + new[] + { + new PatternDescription("Prefix", "Namespace1", ".ext"), + new PatternDescription("Prefix", "Namespace2", ".ext") + } + }, + new object[] + { + new InputData(new[] {"Prefix"}, new[] {"Namespace1", "Namespace2"}, new[] {".ext1", ".ext2"}), + new[] + { + new PatternDescription("Prefix", "Namespace1", ".ext1"), + new PatternDescription("Prefix", "Namespace1", ".ext2"), + new PatternDescription("Prefix", "Namespace2", ".ext1"), + new PatternDescription("Prefix", "Namespace2", ".ext2") + } + }, + new object[] + { + new InputData(new[] {"Prefix1", "Prefix2"}, new[] {"Namespace1", "Namespace2"}, new[] {".ext1", ".ext2"}), + new[] + { + new PatternDescription("Prefix1", "Namespace1", ".ext1"), + new PatternDescription("Prefix1", "Namespace1", ".ext2"), + new PatternDescription("Prefix1", "Namespace2", ".ext1"), + new PatternDescription("Prefix1", "Namespace2", ".ext2"), + new PatternDescription("Prefix2", "Namespace1", ".ext1"), + new PatternDescription("Prefix2", "Namespace1", ".ext2"), + new PatternDescription("Prefix2", "Namespace2", ".ext1"), + new PatternDescription("Prefix2", "Namespace2", ".ext2") + } + } + }; + + [Theory] + [MemberData(nameof(NonEmptyCollectionsData))] + public void Search_AllCollectionsAreNonEmpty_ExplicitPathsAreReturned(InputData input, PatternDescription[] expectedOutput) + { + var searcher = new PatternsCalculator(); + var paths = searcher.Calculate(input.Prefixes, input.Namespaces, input.Extensions).ToArray(); + + paths.Should().BeEquivalentTo(expectedOutput); + } + } + + public struct PatternDescription + { + public PatternDescription(string prefix, string contents, string postfix) + { + Prefix = prefix; + Contents = contents; + Postfix = postfix; + } + + public string Prefix { get; private set; } + public string Contents { get; private set; } + public string Postfix { get; private set; } + } + + internal class PatternsCalculator + { + public IEnumerable Calculate(string[] prefixes, string[] namespaces, string[] extensions) + { + foreach (var prefix in prefixes) + { + foreach (var ns in namespaces) + { + foreach (var extension in extensions) + { + yield return new PatternDescription(prefix, ns, extension); + } + } + } + } + } +} \ No newline at end of file diff --git a/Solid.Core.Tests/Solid.Core.Tests.csproj b/Solid.Core.Tests/Solid.Core.Tests.csproj new file mode 100644 index 00000000..59c42ca6 --- /dev/null +++ b/Solid.Core.Tests/Solid.Core.Tests.csproj @@ -0,0 +1,19 @@ + + + + netcoreapp2.2 + + false + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + diff --git a/Solid.sln b/Solid.sln index 71ed5c06..afede0b7 100644 --- a/Solid.sln +++ b/Solid.sln @@ -83,7 +83,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{274366D9-5 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Solid.Core", "Solid.Core\Solid.Core.csproj", "{4D64C940-EA28-42D8-841C-7F54A261BF73}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Solid.Extensibility.Tests", "Solid.Extensibility.Tests\Solid.Extensibility.Tests.csproj", "{75AB5255-0E92-4AF2-89C5-EBD34083799F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Solid.Extensibility.Tests", "Solid.Extensibility.Tests\Solid.Extensibility.Tests.csproj", "{75AB5255-0E92-4AF2-89C5-EBD34083799F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Solid.Core.Tests", "Solid.Core.Tests\Solid.Core.Tests.csproj", "{E7FFB63B-3878-4AA0-B57E-CEAF548B0762}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -599,6 +601,26 @@ Global {75AB5255-0E92-4AF2-89C5-EBD34083799F}.Release|x64.Build.0 = Release|Any CPU {75AB5255-0E92-4AF2-89C5-EBD34083799F}.Release|x86.ActiveCfg = Release|Any CPU {75AB5255-0E92-4AF2-89C5-EBD34083799F}.Release|x86.Build.0 = Release|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Debug|ARM.ActiveCfg = Debug|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Debug|ARM.Build.0 = Debug|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Debug|ARM64.Build.0 = Debug|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Debug|x64.ActiveCfg = Debug|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Debug|x64.Build.0 = Debug|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Debug|x86.ActiveCfg = Debug|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Debug|x86.Build.0 = Debug|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Release|Any CPU.Build.0 = Release|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Release|ARM.ActiveCfg = Release|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Release|ARM.Build.0 = Release|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Release|ARM64.ActiveCfg = Release|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Release|ARM64.Build.0 = Release|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Release|x64.ActiveCfg = Release|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Release|x64.Build.0 = Release|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Release|x86.ActiveCfg = Release|Any CPU + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -641,6 +663,7 @@ Global {C023E56E-AAF6-4F31-B7AE-293945368D35} = {1C712DFC-927F-43C0-B8DF-02ED6077B4A8} {4D64C940-EA28-42D8-841C-7F54A261BF73} = {274366D9-581A-4EBD-8C54-87DAEAB1869A} {75AB5255-0E92-4AF2-89C5-EBD34083799F} = {2A800A7F-1255-4617-B636-CBD74E0ED96A} + {E7FFB63B-3878-4AA0-B57E-CEAF548B0762} = {274366D9-581A-4EBD-8C54-87DAEAB1869A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DF34B008-79AB-4162-ADC9-E6F970571414} From 48b88e95ce41359b16aa9dc805bd995f4825098a Mon Sep 17 00:00:00 2001 From: Gennady Verdel Date: Wed, 6 Mar 2019 10:20:51 +0200 Subject: [PATCH 2/9] #36 Added support for wildcard matching --- Solid.Core.Tests/PatternsCalculatorTests.cs | 101 +++++++++++++++----- 1 file changed, 76 insertions(+), 25 deletions(-) diff --git a/Solid.Core.Tests/PatternsCalculatorTests.cs b/Solid.Core.Tests/PatternsCalculatorTests.cs index 6e7b6f8f..aa628ba5 100644 --- a/Solid.Core.Tests/PatternsCalculatorTests.cs +++ b/Solid.Core.Tests/PatternsCalculatorTests.cs @@ -26,50 +26,87 @@ public InputData(string[] prefixes, string[] namespaces, string[] extensions) { new object[] { - new InputData(new[] {"Prefix"}, new[] {"Namespace"}, new[] {".ext"}), - new[] {new PatternDescription("Prefix", "Namespace", ".ext")} + new InputData(new[] {"Prefix"}, new[] {"Namespace"}, new[] {"ext"}), + new[] {new PatternDescription("Prefix", "Namespace", "ext")} }, new object[] { - new InputData(new[] {"Prefix"}, new[] {"Namespace1", "Namespace2"}, new[] {".ext"}), + new InputData(new[] {"Prefix"}, new[] {"Namespace1", "Namespace2"}, new[] {"ext"}), new[] { - new PatternDescription("Prefix", "Namespace1", ".ext"), - new PatternDescription("Prefix", "Namespace2", ".ext") + new PatternDescription("Prefix", "Namespace1", "ext"), + new PatternDescription("Prefix", "Namespace2", "ext") } }, new object[] { - new InputData(new[] {"Prefix"}, new[] {"Namespace1", "Namespace2"}, new[] {".ext1", ".ext2"}), + new InputData(new[] {"Prefix"}, new[] {"Namespace1", "Namespace2"}, new[] {"ext1", "ext2"}), new[] { - new PatternDescription("Prefix", "Namespace1", ".ext1"), - new PatternDescription("Prefix", "Namespace1", ".ext2"), - new PatternDescription("Prefix", "Namespace2", ".ext1"), - new PatternDescription("Prefix", "Namespace2", ".ext2") + new PatternDescription("Prefix", "Namespace1", "ext1"), + new PatternDescription("Prefix", "Namespace1", "ext2"), + new PatternDescription("Prefix", "Namespace2", "ext1"), + new PatternDescription("Prefix", "Namespace2", "ext2") } }, new object[] { - new InputData(new[] {"Prefix1", "Prefix2"}, new[] {"Namespace1", "Namespace2"}, new[] {".ext1", ".ext2"}), + new InputData(new[] {"Prefix1", "Prefix2"}, new[] {"Namespace1", "Namespace2"}, new[] {"ext1", "ext2"}), new[] { - new PatternDescription("Prefix1", "Namespace1", ".ext1"), - new PatternDescription("Prefix1", "Namespace1", ".ext2"), - new PatternDescription("Prefix1", "Namespace2", ".ext1"), - new PatternDescription("Prefix1", "Namespace2", ".ext2"), - new PatternDescription("Prefix2", "Namespace1", ".ext1"), - new PatternDescription("Prefix2", "Namespace1", ".ext2"), - new PatternDescription("Prefix2", "Namespace2", ".ext1"), - new PatternDescription("Prefix2", "Namespace2", ".ext2") + new PatternDescription("Prefix1", "Namespace1", "ext1"), + new PatternDescription("Prefix1", "Namespace1", "ext2"), + new PatternDescription("Prefix1", "Namespace2", "ext1"), + new PatternDescription("Prefix1", "Namespace2", "ext2"), + new PatternDescription("Prefix2", "Namespace1", "ext1"), + new PatternDescription("Prefix2", "Namespace1", "ext2"), + new PatternDescription("Prefix2", "Namespace2", "ext1"), + new PatternDescription("Prefix2", "Namespace2", "ext2") } } }; + public static IEnumerable EmptyCollectionsData => + new List + { + new object[] + { + new InputData(new string[] {}, new[] {"Namespace"}, new[] {"ext"}), + new[] {new PatternDescription("*", "Namespace", "ext")} + }, + new object[] + { + new InputData(null, new[] {"Namespace"}, new[] {"ext"}), + new[] {new PatternDescription("*", "Namespace", "ext")} + }, + new object[] + { + new InputData(new string[] {}, new string[] {}, new[] {"ext"}), + new[] {new PatternDescription("*", "*", "ext")} + }, + new object[] + { + new InputData(null, null, new[] {"ext"}), + new[] {new PatternDescription("*", "*", "ext")} + }, + new object[] + { + new InputData(new string[] {}, new string[] {}, new string[] {}), + new[] {new PatternDescription("*", "*", "*")} + }, + new object[] + { + new InputData(null, null, null), + new[] {new PatternDescription("*", "*", "*")} + } + }; + [Theory] [MemberData(nameof(NonEmptyCollectionsData))] - public void Search_AllCollectionsAreNonEmpty_ExplicitPathsAreReturned(InputData input, PatternDescription[] expectedOutput) - { + [MemberData(nameof(EmptyCollectionsData))] + public void Calculate_VariousInputsAreSupplied_ExpectedOutputsAreReturned(InputData input, + PatternDescription[] expectedOutput) + { var searcher = new PatternsCalculator(); var paths = searcher.Calculate(input.Prefixes, input.Namespaces, input.Extensions).ToArray(); @@ -86,15 +123,19 @@ public PatternDescription(string prefix, string contents, string postfix) Postfix = postfix; } - public string Prefix { get; private set; } - public string Contents { get; private set; } - public string Postfix { get; private set; } + public string Prefix { get; } + public string Contents { get; } + public string Postfix { get; } } internal class PatternsCalculator - { + { public IEnumerable Calculate(string[] prefixes, string[] namespaces, string[] extensions) { + prefixes = prefixes.Patch(); + namespaces = namespaces.Patch(); + extensions = extensions.Patch(); + foreach (var prefix in prefixes) { foreach (var ns in namespaces) @@ -105,6 +146,16 @@ public IEnumerable Calculate(string[] prefixes, string[] nam } } } + } + } + + internal static class CollectionExtensions + { + private static string WildCard = "*"; + + internal static string[] Patch(this string[] input) + { + return input == null || input.Length == 0 ? new[] {WildCard} : input; } } } \ No newline at end of file From 91277179dff0f660edeadb596b47069f57e8eb3f Mon Sep 17 00:00:00 2001 From: Gennady Verdel Date: Wed, 6 Mar 2019 10:23:35 +0200 Subject: [PATCH 3/9] #36 Moved PatternsCalculator to Soldi.Core --- Solid.Core.Tests/PatternsCalculatorTests.cs | 47 +-------------------- Solid.Core.Tests/Solid.Core.Tests.csproj | 4 ++ Solid.Core/CollectionExtensions.cs | 12 ++++++ Solid.Core/PatternDescription.cs | 16 +++++++ Solid.Core/PatternsCalculator.cs | 25 +++++++++++ 5 files changed, 58 insertions(+), 46 deletions(-) create mode 100644 Solid.Core/CollectionExtensions.cs create mode 100644 Solid.Core/PatternDescription.cs create mode 100644 Solid.Core/PatternsCalculator.cs diff --git a/Solid.Core.Tests/PatternsCalculatorTests.cs b/Solid.Core.Tests/PatternsCalculatorTests.cs index aa628ba5..9ecf5e8c 100644 --- a/Solid.Core.Tests/PatternsCalculatorTests.cs +++ b/Solid.Core.Tests/PatternsCalculatorTests.cs @@ -112,50 +112,5 @@ public void Calculate_VariousInputsAreSupplied_ExpectedOutputsAreReturned(InputD paths.Should().BeEquivalentTo(expectedOutput); } - } - - public struct PatternDescription - { - public PatternDescription(string prefix, string contents, string postfix) - { - Prefix = prefix; - Contents = contents; - Postfix = postfix; - } - - public string Prefix { get; } - public string Contents { get; } - public string Postfix { get; } - } - - internal class PatternsCalculator - { - public IEnumerable Calculate(string[] prefixes, string[] namespaces, string[] extensions) - { - prefixes = prefixes.Patch(); - namespaces = namespaces.Patch(); - extensions = extensions.Patch(); - - foreach (var prefix in prefixes) - { - foreach (var ns in namespaces) - { - foreach (var extension in extensions) - { - yield return new PatternDescription(prefix, ns, extension); - } - } - } - } - } - - internal static class CollectionExtensions - { - private static string WildCard = "*"; - - internal static string[] Patch(this string[] input) - { - return input == null || input.Length == 0 ? new[] {WildCard} : input; - } - } + } } \ No newline at end of file diff --git a/Solid.Core.Tests/Solid.Core.Tests.csproj b/Solid.Core.Tests/Solid.Core.Tests.csproj index 59c42ca6..b71efe23 100644 --- a/Solid.Core.Tests/Solid.Core.Tests.csproj +++ b/Solid.Core.Tests/Solid.Core.Tests.csproj @@ -16,4 +16,8 @@ + + + + diff --git a/Solid.Core/CollectionExtensions.cs b/Solid.Core/CollectionExtensions.cs new file mode 100644 index 00000000..91081b35 --- /dev/null +++ b/Solid.Core/CollectionExtensions.cs @@ -0,0 +1,12 @@ +namespace Solid.Core +{ + internal static class CollectionExtensions + { + private const string WildCard = "*"; + + internal static string[] Patch(this string[] input) + { + return input == null || input.Length == 0 ? new[] { WildCard } : input; + } + } +} \ No newline at end of file diff --git a/Solid.Core/PatternDescription.cs b/Solid.Core/PatternDescription.cs new file mode 100644 index 00000000..b5852e67 --- /dev/null +++ b/Solid.Core/PatternDescription.cs @@ -0,0 +1,16 @@ +namespace Solid.Core +{ + public struct PatternDescription + { + public PatternDescription(string prefix, string contents, string postfix) + { + Prefix = prefix; + Contents = contents; + Postfix = postfix; + } + + public string Prefix { get; } + public string Contents { get; } + public string Postfix { get; } + } +} \ No newline at end of file diff --git a/Solid.Core/PatternsCalculator.cs b/Solid.Core/PatternsCalculator.cs new file mode 100644 index 00000000..25d66644 --- /dev/null +++ b/Solid.Core/PatternsCalculator.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +namespace Solid.Core +{ + public class PatternsCalculator + { + public IEnumerable Calculate(string[] prefixes, string[] namespaces, string[] extensions) + { + prefixes = prefixes.Patch(); + namespaces = namespaces.Patch(); + extensions = extensions.Patch(); + + foreach (var prefix in prefixes) + { + foreach (var ns in namespaces) + { + foreach (var extension in extensions) + { + yield return new PatternDescription(prefix, ns, extension); + } + } + } + } + } +} \ No newline at end of file From 8b24e75f48e510f57f930c24990a6d0ed80d8b59 Mon Sep 17 00:00:00 2001 From: Gennady Verdel Date: Wed, 6 Mar 2019 10:51:52 +0200 Subject: [PATCH 4/9] #36 Using assembly loading only inside loading strategy --- .../ClientAssemblySourceProvider.cs | 3 +- .../ServerAssemblySourceProvider.cs | 3 +- .../AssemblyLoadingStrategy.cs | 29 +++++++++----- .../AssemblySourceProviderBase.cs | 39 ++++++------------- .../CustomAssemblySourceProvider.cs | 4 +- 5 files changed, 39 insertions(+), 39 deletions(-) diff --git a/Solid.Practices.Composition.Client/ClientAssemblySourceProvider.cs b/Solid.Practices.Composition.Client/ClientAssemblySourceProvider.cs index 1133fdb6..7056b119 100644 --- a/Solid.Practices.Composition.Client/ClientAssemblySourceProvider.cs +++ b/Solid.Practices.Composition.Client/ClientAssemblySourceProvider.cs @@ -13,7 +13,8 @@ public class ClientAssemblySourceProvider : AssemblySourceProviderBase /// Initializes a new instance of the class. /// /// The root path. - public ClientAssemblySourceProvider(string rootPath) : base(rootPath) + /// The prefixes. + public ClientAssemblySourceProvider(string rootPath, string[] prefixes) : base(rootPath, prefixes) { } diff --git a/Solid.Practices.Composition.Web/ServerAssemblySourceProvider.cs b/Solid.Practices.Composition.Web/ServerAssemblySourceProvider.cs index 9c076118..856e20f3 100644 --- a/Solid.Practices.Composition.Web/ServerAssemblySourceProvider.cs +++ b/Solid.Practices.Composition.Web/ServerAssemblySourceProvider.cs @@ -12,7 +12,8 @@ public class ServerAssemblySourceProvider : AssemblySourceProviderBase /// Initializes a new instance of the class. /// /// The root path. - public ServerAssemblySourceProvider(string rootPath) : base(rootPath) + /// The prefixes. + public ServerAssemblySourceProvider(string rootPath, string[] prefixes) : base(rootPath, prefixes) { } diff --git a/Solid.Practices.Composition/AssemblyLoadingStrategy.cs b/Solid.Practices.Composition/AssemblyLoadingStrategy.cs index 95b41bf0..5c9ad964 100644 --- a/Solid.Practices.Composition/AssemblyLoadingStrategy.cs +++ b/Solid.Practices.Composition/AssemblyLoadingStrategy.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Reflection; using Solid.Common; +using Solid.Core; using Solid.Practices.Composition.Contracts; namespace Solid.Practices.Composition @@ -35,19 +36,26 @@ public class FileSystemBasedAssemblyLoadingStrategy : IAssemblyLoadingStrategy { private readonly string _rootPath; private readonly string[] _prefixes; - private static readonly string[] AllowedModulePatterns = {"*.dll", "*.exe"}; + private readonly string[] _namespaces; + private readonly string[] _extensions; /// /// Initializes a new instance of the class. /// /// Root path for inspection /// Allowed prefixes; leave empty if all are allowed. + /// Allowed namespaces; leave empty if all are allowed. + /// Allowed extensions; leave empty if all are allowed. public FileSystemBasedAssemblyLoadingStrategy( - string rootPath, - string[] prefixes = null) + string rootPath, + string[] prefixes = null, + string[] namespaces = null, + string[] extensions = null) { _rootPath = rootPath; _prefixes = prefixes; + _namespaces = namespaces; + _extensions = extensions; } /// @@ -56,12 +64,15 @@ public FileSystemBasedAssemblyLoadingStrategy( private IEnumerable DiscoverAssemblyNames() => DiscoverFilePaths().Select(Path.GetFileNameWithoutExtension); - private IEnumerable DiscoverFilePaths() => AllowedModulePatterns.Select(searchPattern => - _prefixes == null || _prefixes.Length == 0 - ? PlatformProvider.Current.GetFiles(_rootPath, searchPattern) - : _prefixes.Select(prefix => PlatformProvider.Current.GetFiles(_rootPath, prefix + searchPattern)) - .SelectMany(t => t) - .ToArray()).SelectMany(k => k); + private IEnumerable DiscoverFilePaths() + { + var patternsCalculator = new PatternsCalculator(); + var patterns = patternsCalculator.Calculate(_prefixes, _namespaces, _extensions); + return patterns + .Select(k => + PlatformProvider.Current.GetFiles(_rootPath, Path.Combine(k.Prefix + "*" + k.Contents, k.Postfix))) + .SelectMany(k => k); + } } /// diff --git a/Solid.Practices.Composition/AssemblySourceProviderBase.cs b/Solid.Practices.Composition/AssemblySourceProviderBase.cs index b944bf80..ca0953d0 100644 --- a/Solid.Practices.Composition/AssemblySourceProviderBase.cs +++ b/Solid.Practices.Composition/AssemblySourceProviderBase.cs @@ -1,8 +1,6 @@ using System.Collections.Generic; -using System.IO; using System.Linq; using System.Reflection; -using Solid.Common; using Solid.Practices.Composition.Contracts; namespace Solid.Practices.Composition @@ -15,12 +13,19 @@ namespace Solid.Practices.Composition public abstract class AssemblySourceProviderBase : IAssemblySourceProvider { private readonly string _rootPath; + private readonly string[] _prefixes; + private IAssemblyLoadingStrategy _assemblyLoadingStrategy; /// /// Initializes a new instance of the class. /// /// The root path. - protected AssemblySourceProviderBase(string rootPath) => _rootPath = rootPath; + /// The prefixes. + protected AssemblySourceProviderBase(string rootPath, string[] prefixes = null) + { + _rootPath = rootPath; + _prefixes = prefixes; + } private Assembly[] _inspectedAssemblies; @@ -38,31 +43,11 @@ public abstract class AssemblySourceProviderBase : IAssemblySourceProvider /// protected abstract string[] ResolveNamespaces(); - private Assembly[] CreateAssemblies() => - SafeAssemblyLoader.LoadAssembliesFromNames(DiscoverAssemblyNames()).ToArray(); - - private IEnumerable DiscoverAssemblyNames() => DiscoverFilePathsFromNamespaces(ResolveNamespaces()) - .Select(Path.GetFileNameWithoutExtension); - - private IEnumerable DiscoverFilePathsFromNamespaces(string[] namespaces) - { - return AssemblyLoadingManager - .Extensions().Select(searchPattern => namespaces.Length == 0 - ? PlatformProvider.Current.GetFiles(_rootPath, searchPattern) - : namespaces.Select( - @namespace => - GetFilesByNamespace(@namespace, searchPattern)) - .SelectMany(t => t.ToArray()) - .ToArray()).SelectMany(k => k); - } - - private IEnumerable GetFilesByNamespace(string @namespace, string searchPattern) + private Assembly[] CreateAssemblies() { - var matches = PlatformProvider.Current.GetFiles(_rootPath) - .Select(t => t.ToUpper()) - .Where(t => Path.GetFileName(t).Contains(@namespace.ToUpper()) && - t.EndsWith(searchPattern.ToUpper())).ToArray(); - return matches; + _assemblyLoadingStrategy = new FileSystemBasedAssemblyLoadingStrategy(_rootPath, _prefixes, + ResolveNamespaces(), AssemblyLoadingManager.Extensions().ToArray()); + return _assemblyLoadingStrategy.Load().ToArray(); } } } diff --git a/Solid.Practices.Composition/CustomAssemblySourceProvider.cs b/Solid.Practices.Composition/CustomAssemblySourceProvider.cs index 93ea2464..311c586f 100644 --- a/Solid.Practices.Composition/CustomAssemblySourceProvider.cs +++ b/Solid.Practices.Composition/CustomAssemblySourceProvider.cs @@ -13,8 +13,10 @@ public sealed class CustomAssemblySourceProvider : AssemblySourceProviderBase /// Initializes a new instance of the class. /// /// + /// /// - public CustomAssemblySourceProvider(string rootPath, string[] namespaces) : base(rootPath) + public CustomAssemblySourceProvider(string rootPath, string[] prefixes = null, string[] namespaces = null) + : base(rootPath, prefixes) { _namespaces = namespaces; } From 228890f13c2639ee123d279abfce5aafc03a9a12 Mon Sep 17 00:00:00 2001 From: Gennady Verdel Date: Wed, 6 Mar 2019 10:55:20 +0200 Subject: [PATCH 5/9] #36 Improved path matching --- Solid.Practices.Composition/AssemblyLoadingStrategy.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Solid.Practices.Composition/AssemblyLoadingStrategy.cs b/Solid.Practices.Composition/AssemblyLoadingStrategy.cs index 5c9ad964..979b4c07 100644 --- a/Solid.Practices.Composition/AssemblyLoadingStrategy.cs +++ b/Solid.Practices.Composition/AssemblyLoadingStrategy.cs @@ -70,7 +70,8 @@ private IEnumerable DiscoverFilePaths() var patterns = patternsCalculator.Calculate(_prefixes, _namespaces, _extensions); return patterns .Select(k => - PlatformProvider.Current.GetFiles(_rootPath, Path.Combine(k.Prefix + "*" + k.Contents, k.Postfix))) + PlatformProvider.Current.GetFiles(_rootPath).Where(t => + t.StartsWith(k.Prefix) && t.Contains(k.Contents) && t.EndsWith(k.Postfix))) .SelectMany(k => k); } } From 15f05f4d120a705e30846441d490893f223c3fda Mon Sep 17 00:00:00 2001 From: Gennady Verdel Date: Wed, 6 Mar 2019 11:27:42 +0200 Subject: [PATCH 6/9] #36 Fixed extensions usage for Composition Container --- Solid.Core/CollectionExtensions.cs | 11 +++++++---- .../CompositionContainerTests.cs | 9 ++++++--- .../AssemblyLoadingStrategy.cs | 11 ++++++++--- Solid.Practices.Composition/CompositionManager.cs | 4 +++- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/Solid.Core/CollectionExtensions.cs b/Solid.Core/CollectionExtensions.cs index 91081b35..45b02398 100644 --- a/Solid.Core/CollectionExtensions.cs +++ b/Solid.Core/CollectionExtensions.cs @@ -1,12 +1,15 @@ namespace Solid.Core { internal static class CollectionExtensions - { - private const string WildCard = "*"; - + { internal static string[] Patch(this string[] input) { - return input == null || input.Length == 0 ? new[] { WildCard } : input; + return input == null || input.Length == 0 ? new[] { Consts.WildCard } : input; } } + + public static class Consts + { + public const string WildCard = "*"; + } } \ No newline at end of file diff --git a/Solid.Practices.Composition.Tests/CompositionContainerTests.cs b/Solid.Practices.Composition.Tests/CompositionContainerTests.cs index 0100ff11..f466abab 100644 --- a/Solid.Practices.Composition.Tests/CompositionContainerTests.cs +++ b/Solid.Practices.Composition.Tests/CompositionContainerTests.cs @@ -46,7 +46,8 @@ public void RootPathContainsCustomModulesAndCorrectPrefixIsUsed_CustomModulesAre { var rootPath = GetCurrentDirectory(); - ICompositionContainer compositionContainer = CreateCompositionContainer(rootPath, new[] { "Solid" }); + ICompositionContainer compositionContainer = + CreateCompositionContainer(rootPath, new[] {"Solid"}); compositionContainer.Compose(); var modules = compositionContainer.Modules; @@ -102,14 +103,16 @@ private static CompositionContainer CreateCompositionContainer where TModule : ICompositionModule { return new CompositionContainer(CreateModuleCreationStrategy(), - new FileSystemBasedAssemblyLoadingStrategy(rootPath)); + new FileSystemBasedAssemblyLoadingStrategy(rootPath, prefixes:null, namespaces:null, extensions:AssemblyLoadingManager.Extensions().ToArray())); } private static CompositionContainer CreateCompositionContainer(string rootPath, string[] prefixes) where TModule : ICompositionModule { return new CompositionContainer(CreateModuleCreationStrategy(), - new FileSystemBasedAssemblyLoadingStrategy(rootPath, prefixes)); + new FileSystemBasedAssemblyLoadingStrategy(rootPath, prefixes, + null, + AssemblyLoadingManager.Extensions().ToArray())); } private static ICompositionModuleCreationStrategy CreateModuleCreationStrategy() diff --git a/Solid.Practices.Composition/AssemblyLoadingStrategy.cs b/Solid.Practices.Composition/AssemblyLoadingStrategy.cs index 979b4c07..d189e395 100644 --- a/Solid.Practices.Composition/AssemblyLoadingStrategy.cs +++ b/Solid.Practices.Composition/AssemblyLoadingStrategy.cs @@ -68,11 +68,16 @@ private IEnumerable DiscoverFilePaths() { var patternsCalculator = new PatternsCalculator(); var patterns = patternsCalculator.Calculate(_prefixes, _namespaces, _extensions); - return patterns + var allFiles = PlatformProvider.Current.GetFiles(_rootPath).Select(Path.GetFileName).ToArray(); + var filePaths = patterns .Select(k => - PlatformProvider.Current.GetFiles(_rootPath).Where(t => - t.StartsWith(k.Prefix) && t.Contains(k.Contents) && t.EndsWith(k.Postfix))) + //TODO: Consider RegEx + allFiles.Where(t => + (k.Prefix == Consts.WildCard || t.StartsWith(k.Prefix)) && + (k.Contents == Consts.WildCard || t.Contains(k.Contents)) && + (k.Postfix == Consts.WildCard || t.EndsWith(k.Postfix)))) .SelectMany(k => k); + return filePaths; } } diff --git a/Solid.Practices.Composition/CompositionManager.cs b/Solid.Practices.Composition/CompositionManager.cs index 93fc27c9..2935f067 100644 --- a/Solid.Practices.Composition/CompositionManager.cs +++ b/Solid.Practices.Composition/CompositionManager.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Reflection; using Solid.Practices.Composition.Contracts; using Solid.Practices.Modularity; @@ -76,7 +77,8 @@ private void InitializeComposition(IEnumerable assemblies) private void InitializeComposition(string rootPath, string[] prefixes = null) { CompositionContainer = new CompositionContainer(_compositionModuleCreationStrategy, - new FileSystemBasedAssemblyLoadingStrategy(rootPath, prefixes)); + //TODO: Use DiscoveryAspect of course + new FileSystemBasedAssemblyLoadingStrategy(rootPath, prefixes, namespaces:null, extensions:AssemblyLoadingManager.Extensions().ToArray())); CompositionContainer.Compose(); } } From 3bffa464d37f8ed3896fba841739b9a9469271eb Mon Sep 17 00:00:00 2001 From: Gennady Verdel Date: Wed, 6 Mar 2019 11:39:31 +0200 Subject: [PATCH 7/9] #36 Using Discovery Aspect inside the Modularity Aspect --- .../ICompositionManager.cs | 17 +++++++------- .../CompositionManager.cs | 21 ++--------------- .../ModularityAspect.cs | 23 ++++++++----------- 3 files changed, 20 insertions(+), 41 deletions(-) diff --git a/Solid.Practices.Composition.Contracts/ICompositionManager.cs b/Solid.Practices.Composition.Contracts/ICompositionManager.cs index 77ad9c00..6aa88a59 100644 --- a/Solid.Practices.Composition.Contracts/ICompositionManager.cs +++ b/Solid.Practices.Composition.Contracts/ICompositionManager.cs @@ -1,16 +1,17 @@ -namespace Solid.Practices.Composition.Contracts +using System.Collections.Generic; +using System.Reflection; + +namespace Solid.Practices.Composition.Contracts { /// - /// Allows initializing composition from the given path. + /// Allows initializing composition modules using pre-loaded assemblies. /// public interface ICompositionManager : ICompositionModulesProvider - { + { /// - /// Initializes composition modules from the provided path. + /// Initializes composition modules using pre-loaded assemblies. /// - /// Root path. - /// Optional file name prefixes; - /// used for filtering potential assembly candidates. - void Initialize(string rootPath, string[] prefixes = null); + /// The assemblies. + void Initialize(IEnumerable assemblies); } } diff --git a/Solid.Practices.Composition/CompositionManager.cs b/Solid.Practices.Composition/CompositionManager.cs index 2935f067..3593001c 100644 --- a/Solid.Practices.Composition/CompositionManager.cs +++ b/Solid.Practices.Composition/CompositionManager.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using System.Reflection; using Solid.Practices.Composition.Contracts; using Solid.Practices.Modularity; @@ -51,15 +50,7 @@ protected internal CompositionManager(ICompositionModuleCreationStrategy composi /// /// Collection of composition modules. /// - public IEnumerable Modules => CompositionContainer.Modules; - - /// - /// Initializes composition modules from the provided path. - /// - /// Root path. - /// Optional file name prefixes; - /// used for filtering potential assembly candidates. - public void Initialize(string rootPath, string[] prefixes = null) => InitializeComposition(rootPath, prefixes); + public IEnumerable Modules => CompositionContainer.Modules; /// /// Initializes composition modules from the provided assemblies. @@ -72,14 +63,6 @@ private void InitializeComposition(IEnumerable assemblies) CompositionContainer = new CompositionContainer(_compositionModuleCreationStrategy, new PreloadedAssemblyLoadingStrategy(assemblies)); CompositionContainer.Compose(); - } - - private void InitializeComposition(string rootPath, string[] prefixes = null) - { - CompositionContainer = new CompositionContainer(_compositionModuleCreationStrategy, - //TODO: Use DiscoveryAspect of course - new FileSystemBasedAssemblyLoadingStrategy(rootPath, prefixes, namespaces:null, extensions:AssemblyLoadingManager.Extensions().ToArray())); - CompositionContainer.Compose(); - } + } } } \ No newline at end of file diff --git a/Solid.Practices.Composition/ModularityAspect.cs b/Solid.Practices.Composition/ModularityAspect.cs index 1bd15dff..ae292af7 100644 --- a/Solid.Practices.Composition/ModularityAspect.cs +++ b/Solid.Practices.Composition/ModularityAspect.cs @@ -17,23 +17,19 @@ public sealed class ModularityAspect : ICompositionModulesProvider, IHaveErrors { + private readonly IAssemblySourceProvider _assemblySourceProvider; private readonly CompositionOptions _options; - /// - /// Creates an instance of with empty - /// - public ModularityAspect() : - this(new CompositionOptions()) - { - - } - /// /// Creates an instance of using provided /// + /// The assembly source provider /// The composition options - public ModularityAspect(CompositionOptions options) + public ModularityAspect( + IAssemblySourceProvider assemblySourceProvider, + CompositionOptions options) { + _assemblySourceProvider = assemblySourceProvider; _options = options; } @@ -60,7 +56,7 @@ public void Initialize() ModularityInfo modularityInfo = new ModularityInfo(); try { - compositionManager.Initialize(RelativePath, Prefixes); + compositionManager.Initialize(_assemblySourceProvider.Assemblies); } catch (AggregateAssemblyInspectionException ex) { @@ -79,9 +75,8 @@ public void Initialize() /// public string Id => "Modularity"; - - //TODO: Add explicit dep on Discovery when assemblies loading strategies are merged + /// - public string[] Dependencies => new[] { "Platform"}; + public string[] Dependencies => new[] { "Platform", "Discovery" }; } } \ No newline at end of file From 7b270af549d855b7a41133261f2e422ea7a3a2df Mon Sep 17 00:00:00 2001 From: Gennady Verdel Date: Wed, 6 Mar 2019 16:36:55 +0200 Subject: [PATCH 8/9] #36 Cleanup + comments for public elements --- Solid.Core/CollectionExtensions.cs | 5 - Solid.Core/Consts.cs | 13 ++ Solid.Core/PatternDescription.cs | 20 +++ Solid.Core/PatternsCalculator.cs | 10 ++ .../Exceptions.cs | 113 ++++++++++++++ .../SimpleCompositionContainer.cs | 143 +----------------- .../TypeInfoExtractionService.cs | 40 +++++ .../AssemblyLoadingStrategy.cs | 6 +- .../CustomAssemblySourceProvider.cs | 11 +- .../ModularityAspect.cs | 4 +- Solid.Practices.Composition/ModularityInfo.cs | 2 +- 11 files changed, 209 insertions(+), 158 deletions(-) create mode 100644 Solid.Core/Consts.cs create mode 100644 Solid.Practices.Composition.Container/Exceptions.cs create mode 100644 Solid.Practices.Composition.Container/TypeInfoExtractionService.cs diff --git a/Solid.Core/CollectionExtensions.cs b/Solid.Core/CollectionExtensions.cs index 45b02398..c08cffa7 100644 --- a/Solid.Core/CollectionExtensions.cs +++ b/Solid.Core/CollectionExtensions.cs @@ -7,9 +7,4 @@ internal static string[] Patch(this string[] input) return input == null || input.Length == 0 ? new[] { Consts.WildCard } : input; } } - - public static class Consts - { - public const string WildCard = "*"; - } } \ No newline at end of file diff --git a/Solid.Core/Consts.cs b/Solid.Core/Consts.cs new file mode 100644 index 00000000..7cfcd82c --- /dev/null +++ b/Solid.Core/Consts.cs @@ -0,0 +1,13 @@ +namespace Solid.Core +{ + /// + /// Constant values. + /// + public static class Consts + { + /// + /// Wildcard value. + /// + public const string WildCard = "*"; + } +} \ No newline at end of file diff --git a/Solid.Core/PatternDescription.cs b/Solid.Core/PatternDescription.cs index b5852e67..3054bcf2 100644 --- a/Solid.Core/PatternDescription.cs +++ b/Solid.Core/PatternDescription.cs @@ -1,7 +1,16 @@ namespace Solid.Core { + /// + /// The file path pattern description. + /// public struct PatternDescription { + /// + /// Initializes an instance of + /// + /// The prefix. + /// The contents. + /// The postfix. public PatternDescription(string prefix, string contents, string postfix) { Prefix = prefix; @@ -9,8 +18,19 @@ public PatternDescription(string prefix, string contents, string postfix) Postfix = postfix; } + /// + /// The prefix. + /// public string Prefix { get; } + + /// + /// The contents. + /// public string Contents { get; } + + /// + /// The postfix. + /// public string Postfix { get; } } } \ No newline at end of file diff --git a/Solid.Core/PatternsCalculator.cs b/Solid.Core/PatternsCalculator.cs index 25d66644..1928ebac 100644 --- a/Solid.Core/PatternsCalculator.cs +++ b/Solid.Core/PatternsCalculator.cs @@ -2,8 +2,18 @@ namespace Solid.Core { + /// + /// Calculates patterns for file paths. + /// public class PatternsCalculator { + /// + /// Calculates patterns for file paths based on the required conditions. + /// + /// The list of allowed prefixes. Leave empty if all are allowed. + /// The list of allowed namespaces. Leave empty if all are allowed. + /// The list of allowed extensions. Leave empty if all are allowed. + /// The list of allowed patterns. public IEnumerable Calculate(string[] prefixes, string[] namespaces, string[] extensions) { prefixes = prefixes.Patch(); diff --git a/Solid.Practices.Composition.Container/Exceptions.cs b/Solid.Practices.Composition.Container/Exceptions.cs new file mode 100644 index 00000000..c3d853ee --- /dev/null +++ b/Solid.Practices.Composition.Container/Exceptions.cs @@ -0,0 +1,113 @@ +using System; +using System.Reflection; + +namespace Solid.Practices.Composition.Container +{ + /// + /// Represents an exception that is thrown during modules composition. + /// + public class CompositionException : Exception + { + /// + /// Creates a new instance of + /// + /// The message. + public CompositionException(string message) + :base(message) + { + + } + } + + /// + /// Represents an exception that is thrown during assemblies' inspection. + /// + public class AggregateAssemblyInspectionException : Exception + { + /// + /// The collection modules' inner exceptions. + /// + public Exception[] InnerExceptions { get; } + + /// + /// Creates an instance of + /// + /// The inner exceptions. + public AggregateAssemblyInspectionException(Exception[] innerExceptions) + : base("Unable to load assemblies") + { + InnerExceptions = innerExceptions; + } + } + + /// + /// Represents an exception that is thrown during assembly inspection + /// + public class AssemblyInspectionException : Exception + { + /// + /// The assembly whose inspection resulted in the exception. + /// + public string AssemblyName { get; } + + /// + /// Creates an instance of + /// + /// The assembly. + /// The inner exception. + public AssemblyInspectionException(string assemblyName, Exception innerException) + : base("Unable to load defined types", innerException) + { + AssemblyName = assemblyName; + } + + /// + public override string ToString() + { + return $"{Message} for {AssemblyName}; Inner exception is: {InnerException}"; + } + } + + /// + /// Represents an exception that is thrown during modules' creation. + /// + public class AggregateModuleCreationException : Exception + { + /// + /// The collection modules' inner exceptions. + /// + public ModuleCreationException[] InnerExceptions { get; } + + /// + /// Creates an instance of + /// + /// The inner exceptions. + public AggregateModuleCreationException(ModuleCreationException[] innerExceptions) + : base("Unable to create composition modules") + { + InnerExceptions = innerExceptions; + } + } + + /// + /// Represents an exception that is thrown during module creation. + /// + public class ModuleCreationException : Exception + { + /// + /// The module type. + /// + public TypeInfo Type { get; } + + /// + /// Creates an instance of + /// + /// The module type. + /// The inner exception. + public ModuleCreationException(TypeInfo type, Exception innerException) + : base("Unable to create module for the specified type", innerException) + { + Type = type; + } + } +} \ No newline at end of file diff --git a/Solid.Practices.Composition.Container/SimpleCompositionContainer.cs b/Solid.Practices.Composition.Container/SimpleCompositionContainer.cs index 77ca5bb6..5b513d43 100644 --- a/Solid.Practices.Composition.Container/SimpleCompositionContainer.cs +++ b/Solid.Practices.Composition.Container/SimpleCompositionContainer.cs @@ -1,152 +1,11 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Reflection; using Solid.Practices.Composition.Contracts; using Solid.Practices.Modularity; namespace Solid.Practices.Composition.Container -{ - /// - /// Represents means of extracting type info. - /// - public interface ITypeInfoExtractionService - { - /// - /// Gets the types that are defined in the assembly. - /// - /// The assembly to be queried for types. - /// - IEnumerable GetTypes(Assembly assembly); - /// - /// Tests whether the provided type qualifies as a composition module. - /// - /// The type to be tested. - /// The composition module type. - /// True, if the type qualifies as a composition module; false otherwise. - bool IsCompositionModule(TypeInfo type, Type moduleType); - } - - /// - public class TypeInfoExtractionService : ITypeInfoExtractionService - { - /// - public IEnumerable GetTypes(Assembly assembly) => assembly.DefinedTypes; - - /// - public bool IsCompositionModule(TypeInfo type, Type moduleType) => type.IsClass && type.IsAbstract == false - && type.ImplementedInterfaces.Contains( - moduleType); - } - - /// - /// Represents an exception that is thrown during modules composition. - /// - public class CompositionException : Exception - { - /// - /// Creates a new instance of - /// - /// The message. - public CompositionException(string message) - :base(message) - { - - } - } - - /// - /// Represents an exception that is thrown during assemblies' inspection. - /// - public class AggregateAssemblyInspectionException : Exception - { - /// - /// The collection modules' inner exceptions. - /// - public Exception[] InnerExceptions { get; } - - /// - /// Creates an instance of - /// - /// The inner exceptions. - public AggregateAssemblyInspectionException(Exception[] innerExceptions) - : base("Unable to load assemblies") - { - InnerExceptions = innerExceptions; - } - } - - /// - /// Represents an exception that is thrown during assembly inspection - /// - public class AssemblyInspectionException : Exception - { - /// - /// The assembly whose inspection resulted in the exception. - /// - public string AssemblyName { get; } - - /// - /// Creates an instance of - /// - /// The assembly. - /// The inner exception. - public AssemblyInspectionException(string assemblyName, Exception innerException) - :base("Unable to load defined types", innerException) - { - AssemblyName = assemblyName; - } - - /// - public override string ToString() - { - return $"{Message} for {AssemblyName}; Inner exception is: {InnerException}"; - } - } - - /// - /// Represents an exception that is thrown during modules' creation. - /// - public class AggregateModuleCreationException : Exception - { - /// - /// The collection modules' inner exceptions. - /// - public ModuleCreationException[] InnerExceptions { get; } - - /// - /// Creates an instance of - /// - /// The inner exceptions. - public AggregateModuleCreationException(ModuleCreationException[] innerExceptions) - :base("Unable to create composition modules") - { - InnerExceptions = innerExceptions; - } - } - - /// - /// Represents an exception that is thrown during module creation. - /// - public class ModuleCreationException : Exception - { - /// - /// The module type. - /// - public TypeInfo Type { get; } - - /// - /// Creates an instance of - /// - /// The module type. - /// The inner exception. - public ModuleCreationException(TypeInfo type, Exception innerException) - :base("Unable to create module for the specified type", innerException) - { - Type = type; - } - } - +{ /// /// Represents a basic implementation of composition container with export feature only. /// diff --git a/Solid.Practices.Composition.Container/TypeInfoExtractionService.cs b/Solid.Practices.Composition.Container/TypeInfoExtractionService.cs new file mode 100644 index 00000000..b55fca81 --- /dev/null +++ b/Solid.Practices.Composition.Container/TypeInfoExtractionService.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace Solid.Practices.Composition.Container +{ + /// + /// Represents means of extracting type info. + /// + public interface ITypeInfoExtractionService + { + /// + /// Gets the types that are defined in the assembly. + /// + /// The assembly to be queried for types. + /// + IEnumerable GetTypes(Assembly assembly); + /// + /// Tests whether the provided type qualifies as a composition module. + /// + /// The type to be tested. + /// The composition module type. + /// True, if the type qualifies as a composition module; false otherwise. + bool IsCompositionModule(TypeInfo type, Type moduleType); + } + + /// + public class TypeInfoExtractionService : ITypeInfoExtractionService + { + /// + public IEnumerable GetTypes(Assembly assembly) => assembly.DefinedTypes; + + /// + public bool IsCompositionModule(TypeInfo type, Type moduleType) => type.IsClass && type.IsAbstract == false + && type.ImplementedInterfaces + .Contains( + moduleType); + } +} \ No newline at end of file diff --git a/Solid.Practices.Composition/AssemblyLoadingStrategy.cs b/Solid.Practices.Composition/AssemblyLoadingStrategy.cs index d189e395..9e51c764 100644 --- a/Solid.Practices.Composition/AssemblyLoadingStrategy.cs +++ b/Solid.Practices.Composition/AssemblyLoadingStrategy.cs @@ -19,11 +19,9 @@ public class PreloadedAssemblyLoadingStrategy : IAssemblyLoadingStrategy /// /// Initializes a new instance of the class. /// - /// The preloaded assemblies. - /// Allowed prefixes; leave empty if all are allowed. + /// The preloaded assemblies. public PreloadedAssemblyLoadingStrategy( - IEnumerable assemblies, - string[] prefixes = null) => Assemblies = assemblies.FilterByPrefixes(prefixes).ToArray(); + IEnumerable assemblies) => Assemblies = assemblies.ToArray(); /// public IEnumerable Load() => Assemblies; diff --git a/Solid.Practices.Composition/CustomAssemblySourceProvider.cs b/Solid.Practices.Composition/CustomAssemblySourceProvider.cs index 311c586f..45aec407 100644 --- a/Solid.Practices.Composition/CustomAssemblySourceProvider.cs +++ b/Solid.Practices.Composition/CustomAssemblySourceProvider.cs @@ -12,10 +12,13 @@ public sealed class CustomAssemblySourceProvider : AssemblySourceProviderBase /// /// Initializes a new instance of the class. /// - /// - /// - /// - public CustomAssemblySourceProvider(string rootPath, string[] prefixes = null, string[] namespaces = null) + /// The root path. + /// The prefixes. + /// The namespaces. + public CustomAssemblySourceProvider( + string rootPath, + string[] prefixes = null, + string[] namespaces = null) : base(rootPath, prefixes) { _namespaces = namespaces; diff --git a/Solid.Practices.Composition/ModularityAspect.cs b/Solid.Practices.Composition/ModularityAspect.cs index ae292af7..137d035d 100644 --- a/Solid.Practices.Composition/ModularityAspect.cs +++ b/Solid.Practices.Composition/ModularityAspect.cs @@ -23,8 +23,8 @@ public sealed class ModularityAspect : /// /// Creates an instance of using provided /// - /// The assembly source provider - /// The composition options + /// The assembly source provider. + /// The composition options. public ModularityAspect( IAssemblySourceProvider assemblySourceProvider, CompositionOptions options) diff --git a/Solid.Practices.Composition/ModularityInfo.cs b/Solid.Practices.Composition/ModularityInfo.cs index aee793d0..1a925836 100644 --- a/Solid.Practices.Composition/ModularityInfo.cs +++ b/Solid.Practices.Composition/ModularityInfo.cs @@ -5,7 +5,7 @@ namespace Solid.Practices.Composition { /// - /// The modularity information + /// The modularity information. /// public struct ModularityInfo { From 55158eb1b08f72318fe36d4719c9c0d34e3353c5 Mon Sep 17 00:00:00 2001 From: Gennady Verdel Date: Wed, 6 Mar 2019 16:49:41 +0200 Subject: [PATCH 9/9] #36 Updated assembly versions --- Solid.Bootstrapping/Solid.Bootstrapping.csproj | 11 ++--------- .../net/Properties/AssemblyInfo.cs | 4 ++-- .../uwp/Properties/AssemblyInfo.cs | 4 ++-- Solid.Common/Solid.Common.csproj | 6 +----- Solid.Core/Solid.Core.csproj | 7 ++----- Solid.Extensibility/Solid.Extensibility.csproj | 11 ++--------- .../Solid.IoC.Adapters.BoDi.csproj | 16 +++------------- .../Solid.Patterns.Builder.csproj | 11 ++--------- .../Solid.Patterns.ChainOfResponsibility.csproj | 11 ++--------- .../Solid.Patterns.Memento.csproj | 11 ++--------- .../Solid.Patterns.Visitor.csproj | 11 ++--------- .../Solid.Practices.Composition.Client.csproj | 9 ++------- .../Solid.Practices.Composition.Container.csproj | 11 ++--------- .../Solid.Practices.Composition.Contracts.csproj | 11 ++--------- .../Solid.Practices.Composition.Web.csproj | 10 ++-------- .../Solid.Practices.Composition.csproj | 15 ++++----------- Solid.Practices.IoC/Solid.Practices.IoC.csproj | 11 ++--------- .../Solid.Practices.Middleware.csproj | 11 ++--------- .../Solid.Practices.Modularity.csproj | 11 ++--------- .../Solid.Practices.Scheduling.csproj | 11 ++--------- 20 files changed, 42 insertions(+), 161 deletions(-) diff --git a/Solid.Bootstrapping/Solid.Bootstrapping.csproj b/Solid.Bootstrapping/Solid.Bootstrapping.csproj index 50cdb822..2274e171 100644 --- a/Solid.Bootstrapping/Solid.Bootstrapping.csproj +++ b/Solid.Bootstrapping/Solid.Bootstrapping.csproj @@ -1,16 +1,9 @@ - + netstandard2.0 - Solid.Bootstrapping - Solid.Bootstrapping - 2.0.0.0 - 2.0.0.0 - - - false - 2.0.0 + 2.1.0 diff --git a/Solid.Common.Platform/net/Properties/AssemblyInfo.cs b/Solid.Common.Platform/net/Properties/AssemblyInfo.cs index 1ff7fe9d..5ff296aa 100644 --- a/Solid.Common.Platform/net/Properties/AssemblyInfo.cs +++ b/Solid.Common.Platform/net/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.0.0")] -[assembly: AssemblyFileVersion("2.0.0")] +[assembly: AssemblyVersion("2.1.0")] +[assembly: AssemblyFileVersion("2.1.0")] diff --git a/Solid.Common.Platform/uwp/Properties/AssemblyInfo.cs b/Solid.Common.Platform/uwp/Properties/AssemblyInfo.cs index 286da4b8..25729452 100644 --- a/Solid.Common.Platform/uwp/Properties/AssemblyInfo.cs +++ b/Solid.Common.Platform/uwp/Properties/AssemblyInfo.cs @@ -23,6 +23,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.0.0")] +[assembly: AssemblyVersion("2.1.0.0")] +[assembly: AssemblyFileVersion("2.1.0.0")] [assembly: ComVisible(false)] \ No newline at end of file diff --git a/Solid.Common/Solid.Common.csproj b/Solid.Common/Solid.Common.csproj index 0c050999..081cd391 100644 --- a/Solid.Common/Solid.Common.csproj +++ b/Solid.Common/Solid.Common.csproj @@ -2,12 +2,8 @@ netstandard2.0 - - - false - 2.0.0 - Solid.Common + 2.1.0 diff --git a/Solid.Core/Solid.Core.csproj b/Solid.Core/Solid.Core.csproj index e5ec2122..c464bf7f 100644 --- a/Solid.Core/Solid.Core.csproj +++ b/Solid.Core/Solid.Core.csproj @@ -1,12 +1,9 @@  - netstandard2.0 - - - + netstandard2.0 false - 2.0.0 + 2.1.0 diff --git a/Solid.Extensibility/Solid.Extensibility.csproj b/Solid.Extensibility/Solid.Extensibility.csproj index a9026505..8d4e4644 100644 --- a/Solid.Extensibility/Solid.Extensibility.csproj +++ b/Solid.Extensibility/Solid.Extensibility.csproj @@ -1,16 +1,9 @@  - + netstandard2.0 - Solid.Extensibility - Solid.Extensibility - 2.0.0.0 - 2.0.0.0 - - - false - 2.0.0 + 2.1.0 diff --git a/Solid.IoC.Adapters.BoDi/Solid.IoC.Adapters.BoDi.csproj b/Solid.IoC.Adapters.BoDi/Solid.IoC.Adapters.BoDi.csproj index 4a3cf372..e047ac14 100644 --- a/Solid.IoC.Adapters.BoDi/Solid.IoC.Adapters.BoDi.csproj +++ b/Solid.IoC.Adapters.BoDi/Solid.IoC.Adapters.BoDi.csproj @@ -1,16 +1,9 @@  - + netstandard2.0 - Solid.IoC.Adapters.BoDi - Solid.IoC.Adapters.BoDi - 2.0.0.0 - 2.0.0.0 - - - false - 2.0.0 + 2.1.0 @@ -26,9 +19,6 @@ - - {156f34d5-5b15-40cd-9873-c822d5335b0d} - Solid.Practices.IoC - + \ No newline at end of file diff --git a/Solid.Patterns.Builder/Solid.Patterns.Builder.csproj b/Solid.Patterns.Builder/Solid.Patterns.Builder.csproj index 0dd73214..ca0116e3 100644 --- a/Solid.Patterns.Builder/Solid.Patterns.Builder.csproj +++ b/Solid.Patterns.Builder/Solid.Patterns.Builder.csproj @@ -1,16 +1,9 @@  - + netstandard2.0 - Solid.Patterns.Builder - Solid.Patterns.Builder - 2.0.0.0 - 2.0.0.0 - - - false - 2.0.0 + 2.1.0 diff --git a/Solid.Patterns.ChainOfResponsibility/Solid.Patterns.ChainOfResponsibility.csproj b/Solid.Patterns.ChainOfResponsibility/Solid.Patterns.ChainOfResponsibility.csproj index 1ec4b16d..d5d44f1e 100644 --- a/Solid.Patterns.ChainOfResponsibility/Solid.Patterns.ChainOfResponsibility.csproj +++ b/Solid.Patterns.ChainOfResponsibility/Solid.Patterns.ChainOfResponsibility.csproj @@ -1,16 +1,9 @@  - + netstandard2.0 - Solid.Patterns.ChainOfResponsibility - Solid.Patterns.ChainOfResponsibility - 2.0.0.0 - 2.0.0.0 - - - false - 2.0.0 + 2.1.0 diff --git a/Solid.Patterns.Memento/Solid.Patterns.Memento.csproj b/Solid.Patterns.Memento/Solid.Patterns.Memento.csproj index 5e4f565c..a12e9b6b 100644 --- a/Solid.Patterns.Memento/Solid.Patterns.Memento.csproj +++ b/Solid.Patterns.Memento/Solid.Patterns.Memento.csproj @@ -1,16 +1,9 @@  - + netstandard2.0 - Solid.Patterns.Memento - Solid.Patterns.Memento - 2.0.0.0 - 2.0.0.0 - - - false - 2.0.0 + 2.1.0 diff --git a/Solid.Patterns.Visitor/Solid.Patterns.Visitor.csproj b/Solid.Patterns.Visitor/Solid.Patterns.Visitor.csproj index b8f2d758..204bb761 100644 --- a/Solid.Patterns.Visitor/Solid.Patterns.Visitor.csproj +++ b/Solid.Patterns.Visitor/Solid.Patterns.Visitor.csproj @@ -1,16 +1,9 @@  - + netstandard2.0 - Solid.Patterns.Visitor - Solid.Patterns.Visitor - 2.0.0.0 - 2.0.0.0 - - - false - 2.0.0 + 2.1.0 diff --git a/Solid.Practices.Composition.Client/Solid.Practices.Composition.Client.csproj b/Solid.Practices.Composition.Client/Solid.Practices.Composition.Client.csproj index 4fe47ac5..5729ab0b 100644 --- a/Solid.Practices.Composition.Client/Solid.Practices.Composition.Client.csproj +++ b/Solid.Practices.Composition.Client/Solid.Practices.Composition.Client.csproj @@ -1,14 +1,9 @@  - + netstandard2.0 - Solid.Practices.Composition.Client - Solid.Practices.Composition.Client - 2.0.0 - - - false + 2.1.0 diff --git a/Solid.Practices.Composition.Container/Solid.Practices.Composition.Container.csproj b/Solid.Practices.Composition.Container/Solid.Practices.Composition.Container.csproj index 02afd8e8..bfd09bcf 100644 --- a/Solid.Practices.Composition.Container/Solid.Practices.Composition.Container.csproj +++ b/Solid.Practices.Composition.Container/Solid.Practices.Composition.Container.csproj @@ -1,16 +1,9 @@  - + netstandard2.0 - Solid.Practices.Composition.Container - Solid.Practices.Composition.Container - 2.0.0.0 - 2.0.0.0 - - - false - 2.0.0 + 2.1.0 diff --git a/Solid.Practices.Composition.Contracts/Solid.Practices.Composition.Contracts.csproj b/Solid.Practices.Composition.Contracts/Solid.Practices.Composition.Contracts.csproj index 409eade6..259758c6 100644 --- a/Solid.Practices.Composition.Contracts/Solid.Practices.Composition.Contracts.csproj +++ b/Solid.Practices.Composition.Contracts/Solid.Practices.Composition.Contracts.csproj @@ -1,16 +1,9 @@  - + netstandard2.0 - Solid.Practices.Composition.Contracts - Solid.Practices.Composition.Contracts - 2.0.0.0 - 2.0.0.0 - - - false - 2.0.0 + 2.1.0 diff --git a/Solid.Practices.Composition.Web/Solid.Practices.Composition.Web.csproj b/Solid.Practices.Composition.Web/Solid.Practices.Composition.Web.csproj index 2e2760f0..6bfac963 100644 --- a/Solid.Practices.Composition.Web/Solid.Practices.Composition.Web.csproj +++ b/Solid.Practices.Composition.Web/Solid.Practices.Composition.Web.csproj @@ -1,15 +1,9 @@ - + netstandard2.0 - Solid.Practices.Composition.Web - Solid.Practices.Composition.Web - 2.0.0 - - - false - 2.0.0 + 2.1.0 diff --git a/Solid.Practices.Composition/Solid.Practices.Composition.csproj b/Solid.Practices.Composition/Solid.Practices.Composition.csproj index cbaf75f3..f07b9f97 100644 --- a/Solid.Practices.Composition/Solid.Practices.Composition.csproj +++ b/Solid.Practices.Composition/Solid.Practices.Composition.csproj @@ -1,18 +1,11 @@  - + - netstandard2.0 - Solid.Practices.Composition - Solid.Practices.Composition - 2.0.0.0 - 2.0.0.0 + netstandard2.0 + false + 2.1.0 - - false - 2.0.0 - - ..\Bin\netstandard2.0\Release ..\Bin\netstandard2.0\Release\Solid.Practices.Composition.xml diff --git a/Solid.Practices.IoC/Solid.Practices.IoC.csproj b/Solid.Practices.IoC/Solid.Practices.IoC.csproj index 33a7221d..76c983a1 100644 --- a/Solid.Practices.IoC/Solid.Practices.IoC.csproj +++ b/Solid.Practices.IoC/Solid.Practices.IoC.csproj @@ -1,16 +1,9 @@  - + netstandard2.0 - Solid.Practices.IoC - Solid.Practices.IoC - 2.0.0.0 - 2.0.0.0 - - - false - 2.0.0 + 2.1.0 diff --git a/Solid.Practices.Middleware/Solid.Practices.Middleware.csproj b/Solid.Practices.Middleware/Solid.Practices.Middleware.csproj index fbe28ad5..3dc59a59 100644 --- a/Solid.Practices.Middleware/Solid.Practices.Middleware.csproj +++ b/Solid.Practices.Middleware/Solid.Practices.Middleware.csproj @@ -1,16 +1,9 @@  - + netstandard2.0 - Solid.Practices.Middleware - Solid.Practices.Middleware - 2.0.0.0 - 2.0.0.0 - - - false - 2.0.0 + 2.1.0 diff --git a/Solid.Practices.Modularity/Solid.Practices.Modularity.csproj b/Solid.Practices.Modularity/Solid.Practices.Modularity.csproj index 915d7cc5..5a4b1f3f 100644 --- a/Solid.Practices.Modularity/Solid.Practices.Modularity.csproj +++ b/Solid.Practices.Modularity/Solid.Practices.Modularity.csproj @@ -1,16 +1,9 @@ - + netstandard2.0 - Solid.Practices.Modularity - Solid.Practices.Modularity - 2.0.0.0 - 2.0.0.0 - - - false - 2.0.0 + 2.1.0 diff --git a/Solid.Practices.Scheduling/Solid.Practices.Scheduling.csproj b/Solid.Practices.Scheduling/Solid.Practices.Scheduling.csproj index bc99a8dc..6999bc09 100644 --- a/Solid.Practices.Scheduling/Solid.Practices.Scheduling.csproj +++ b/Solid.Practices.Scheduling/Solid.Practices.Scheduling.csproj @@ -1,16 +1,9 @@  - + netstandard2.0 - Solid.Practices.Scheduling - Solid.Practices.Scheduling - 2.0.0.0 - 2.0.0.0 - - - false - 2.0.0 + 2.1.0