-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
369 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// ---------------------------------------------------------------------------------- | ||
// Copyright (c) The Standard Organization: A coalition of the Good-Hearted Engineers | ||
// ---------------------------------------------------------------------------------- | ||
|
||
namespace STX.SPAL.Abstractions | ||
{ | ||
public interface ISPALProvider | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>disable</ImplicitUsings> | ||
<Nullable>disable</Nullable> | ||
</PropertyGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// ---------------------------------------------------------------------------------- | ||
// Copyright (c) The Standard Organization: A coalition of the Good-Hearted Engineers | ||
// ---------------------------------------------------------------------------------- | ||
|
||
namespace STX.SPAL.Core | ||
{ | ||
public interface ISPALOrchestrationService | ||
{ | ||
T GetImplementation<T>(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// ---------------------------------------------------------------------------------- | ||
// Copyright (c) The Standard Organization: A coalition of the Good-Hearted Engineers | ||
// ---------------------------------------------------------------------------------- | ||
|
||
using System; | ||
|
||
namespace STX.SPAL.Core | ||
{ | ||
public partial class SPALOrchestrationService | ||
{ | ||
private static T TryCatch<T>( | ||
Func<T> function) | ||
{ | ||
try | ||
{ | ||
return function(); | ||
} | ||
|
||
catch (Exception exception) | ||
{ | ||
throw; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
// ---------------------------------------------------------------------------------- | ||
// Copyright (c) The Standard Organization: A coalition of the Good-Hearted Engineers | ||
// ---------------------------------------------------------------------------------- | ||
|
||
using Microsoft.Extensions.DependencyInjection; | ||
using STX.SPAL.Abstractions; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Reflection; | ||
using System.Runtime.InteropServices; | ||
|
||
namespace STX.SPAL.Core | ||
{ | ||
public partial class SPALOrchestrationService : ISPALOrchestrationService | ||
{ | ||
private const int DEFAULT_MAXIMUM_DEPTH_ANALISYS = 0; | ||
|
||
private readonly IServiceProvider serviceProvider; | ||
|
||
public SPALOrchestrationService(IServiceProvider serviceProvider) | ||
{ | ||
this.serviceProvider = serviceProvider; | ||
} | ||
|
||
private static Type[] GetInterfaceImplementations<T>(Assembly assembly) | ||
where T : ISPALProvider | ||
{ | ||
Type spalInterfaceType = typeof(T); | ||
|
||
Type[] implementations = | ||
assembly | ||
.GetExportedTypes() | ||
.Where(type => | ||
type.GetInterfaces() | ||
.Any(interfaceType => | ||
//@interface is T | ||
interfaceType.Assembly.FullName == spalInterfaceType.Assembly.FullName | ||
&& interfaceType.Namespace == spalInterfaceType.Namespace | ||
&& interfaceType.Name == spalInterfaceType.Name | ||
)) | ||
.ToArray(); | ||
|
||
return implementations; | ||
} | ||
|
||
private static Assembly[] GetDependantAssemblies( | ||
Assembly assembly, | ||
int currentDepth = 0, | ||
int maximumDepth = DEFAULT_MAXIMUM_DEPTH_ANALISYS) | ||
{ | ||
return assembly | ||
.GetReferencedAssemblies() | ||
.SelectMany(referencedAssemblyName => | ||
{ | ||
Assembly referencedAssembly = Assembly.Load(referencedAssemblyName); | ||
|
||
return currentDepth < maximumDepth | ||
? GetDependantAssemblies(referencedAssembly, currentDepth + 1, maximumDepth) | ||
: new Assembly[] { referencedAssembly }; | ||
}) | ||
.ToArray(); | ||
} | ||
|
||
private static Assembly[] GetAllAssemblies(Assembly rootAssembly) | ||
{ | ||
Assembly[] assemblies = | ||
GetDependantAssemblies(rootAssembly) | ||
.Distinct() | ||
.ToArray(); | ||
|
||
return assemblies; | ||
} | ||
|
||
// Maybe this should go under an Extension Class for IServiceColletion | ||
public static ServiceCollection RegisterAllImplementations<T>(ServiceCollection services) | ||
where T : ISPALProvider | ||
{ | ||
// Not work because, even STX.Serializations.Providers.XXXXX were added as a dependant project, there is no | ||
// type used from the main project. So the compiler "removes" those assemblies from GetReferencedAssemblies. | ||
Assembly[] assemblies = GetAllAssemblies(Assembly.GetEntryAssembly()); | ||
|
||
Type[] typesToRegister = assemblies | ||
.SelectMany(assembly => GetInterfaceImplementations<T>(assembly)) | ||
.ToArray(); | ||
|
||
// This strategy uses MetadataLoadContext. Allows inspecting without explicit dependencies and more memory-efficient. | ||
// https://learn.microsoft.com/en-us/dotnet/standard/assembly/inspect-contents-using-metadataloadcontext | ||
string[] runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll"); | ||
var paths = new List<string>(runtimeAssemblies); | ||
|
||
string applicationPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); | ||
string[] applicationAssembliesPaths = Directory.GetFiles(applicationPath, "*.dll"); | ||
paths.AddRange(applicationAssembliesPaths); | ||
|
||
var pathAssemblyResolver = new PathAssemblyResolver(paths); | ||
string coreAssemblyName = typeof(object).Assembly.GetName().Name; | ||
|
||
using (var metadaLoadContext = new MetadataLoadContext(pathAssemblyResolver, coreAssemblyName)) | ||
{ | ||
foreach (string applicationAssemblyPath in applicationAssembliesPaths) | ||
{ | ||
Assembly assembly = metadaLoadContext.LoadFromAssemblyPath(applicationAssemblyPath); | ||
|
||
GetInterfaceImplementations<T>(assembly) | ||
.Select(implementationType => | ||
{ | ||
Assembly runtimeAssembly = Assembly.LoadFrom(applicationAssemblyPath); | ||
implementationType = runtimeAssembly.GetExportedTypes() | ||
.Single(type => type.Name == implementationType.Name); | ||
|
||
if (services.Any(serviceDescriptor => serviceDescriptor.ServiceType == typeof(T))) | ||
throw new Exception($"More than one implementation registered for {typeof(T).Name}. Please specify one of them or use keys for specifing multiple implementations for the same interface."); | ||
|
||
services.AddTransient(typeof(T), implementationType); | ||
Console.WriteLine($"Registered {implementationType.FullName} ({typeof(T).Name})"); | ||
|
||
return services; | ||
}) | ||
.ToArray(); | ||
} | ||
} | ||
|
||
Console.WriteLine($"Register Done!."); | ||
|
||
return services; | ||
} | ||
|
||
public T GetImplementation<T>() => | ||
TryCatch(() => | ||
serviceProvider.GetRequiredService<T>()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>disable</ImplicitUsings> | ||
<Nullable>disable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" /> | ||
<PackageReference Include="System.Reflection.MetadataLoadContext" Version="8.0.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\STX.SPAL.Abstractions\STX.SPAL.Abstractions.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// ---------------------------------------------------------------------------------- | ||
// Copyright (c) The Standard Organization: A coalition of the Good-Hearted Engineers | ||
// ---------------------------------------------------------------------------------- | ||
|
||
using Microsoft.Extensions.DependencyInjection; | ||
using STX.Serialization.Providers.Abstractions; | ||
using STX.SPAL.Core; | ||
|
||
namespace STX.Serialization.POC | ||
{ | ||
internal class Program | ||
{ | ||
static void Main(string[] args) | ||
{ | ||
var services = new ServiceCollection(); | ||
services = SPALOrchestrationService.RegisterAllImplementations<ISerializationProvider>(services); | ||
services | ||
.AddScoped<ISPALOrchestrationService, SPALOrchestrationService>(); | ||
|
||
IServiceProvider serviceProvider = services.BuildServiceProvider(); | ||
using IServiceScope scope = serviceProvider.CreateScope(); | ||
|
||
ISPALOrchestrationService spalOrchestrationService = | ||
scope.ServiceProvider | ||
.GetRequiredService<ISPALOrchestrationService>(); | ||
|
||
ISerializationProvider serializationProvider = | ||
spalOrchestrationService.GetImplementation<ISerializationProvider>(); | ||
|
||
System.Console.WriteLine(serializationProvider.GetName()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\STX.Serialization.Providers.Abstractions\STX.Serialization.Providers.Abstractions.csproj" /> | ||
<ProjectReference Include="..\STX.Serialization.Providers.NewtonsoftJson\STX.Serialization.Providers.NewtonsoftJson.csproj" /> | ||
<ProjectReference Include="..\STX.Serialization.Providers.SystemTextJson\STX.Serialization.Providers.SystemTextJson.csproj" /> | ||
<ProjectReference Include="..\STX.SPAL.Core\STX.SPAL.Core.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
STX.Serialization.Providers.Abstractions/ISerializationProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// ---------------------------------------------------------------------------------- | ||
// Copyright (c) The Standard Organization: A coalition of the Good-Hearted Engineers | ||
// ---------------------------------------------------------------------------------- | ||
|
||
using STX.SPAL.Abstractions; | ||
|
||
namespace STX.Serialization.Providers.Abstractions | ||
{ | ||
public interface ISerializationProvider : ISPALProvider | ||
{ | ||
string GetName(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
STX.Serialization.Providers.NewtonsoftJson/STX.Serialization.Providers.NewtonsoftJson.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>disable</ImplicitUsings> | ||
<Nullable>disable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\STX.Serialization.Providers.Abstractions\STX.Serialization.Providers.Abstractions.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
14 changes: 14 additions & 0 deletions
14
STX.Serialization.Providers.NewtonsoftJson/SerializationProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// ---------------------------------------------------------------------------------- | ||
// Copyright (c) The Standard Organization: A coalition of the Good-Hearted Engineers | ||
// ---------------------------------------------------------------------------------- | ||
|
||
using STX.Serialization.Providers.Abstractions; | ||
|
||
namespace STX.Serialization.Providers.NewtonsoftJson | ||
{ | ||
public class SerializationProvider : ISerializationProvider | ||
{ | ||
public string GetName() => | ||
this.GetType().FullName; | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
STX.Serialization.Providers.SystemTextJson/STX.Serialization.Providers.SystemTextJson.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>disable</ImplicitUsings> | ||
<Nullable>disable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\STX.Serialization.Providers.Abstractions\STX.Serialization.Providers.Abstractions.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Oops, something went wrong.