Skip to content

Commit c7d462f

Browse files
committed
Added implementation.
1 parent a52622f commit c7d462f

12 files changed

+283
-9
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace TNVS.SimpleInjector.Modularization.Abstractions
2+
{
3+
public interface IModule
4+
{
5+
void RegisterServices(IServiceRegistry registry);
6+
}
7+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
3+
namespace TNVS.SimpleInjector.Modularization.Abstractions
4+
{
5+
public interface IServiceRegistry
6+
{
7+
void RegisterSingleton<T>() where T : class;
8+
9+
void RegisterSingleton<T>(T instance) where T : class;
10+
11+
void RegisterSingleton<TService, TImplementation>() where TService : class where TImplementation : class, TService;
12+
13+
void RegisterSingleton<T>(Func<T> instanceProducer) where T : class;
14+
15+
void RegisterSingletonAsMultipleServices<TService1, TService2, TImplementation>() where TService1 : class where TImplementation : class, TService1, TService2;
16+
17+
void RegisterSingletonAsMultipleServices<TService1, TService2, TService3, TImplementation>() where TService1 : class where TService2 : class where TService3 : class where TImplementation : class, TService1, TService2, TService3;
18+
19+
void RegisterTransient<T>() where T : class;
20+
21+
void RegisterTransient<TService, TImplementation>() where TService : class where TImplementation : class, TService;
22+
}
23+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
</Project>

TNVS.SimpleInjector.Modularization.sln

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 15
44
VisualStudioVersion = 15.0.27130.2020
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TNVS.SimpleInjector.Modularization", "TNVS.SimpleInjector.Modularization\TNVS.SimpleInjector.Modularization.csproj", "{D3CB4D05-21E3-4883-A0FF-9749A64EFAD0}"
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TNVS.SimpleInjector.Modularization", "TNVS.SimpleInjector.Modularization\TNVS.SimpleInjector.Modularization.csproj", "{D3CB4D05-21E3-4883-A0FF-9749A64EFAD0}"
7+
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TNVS.SimpleInjector.Modularization.Abstractions", "TNVS.SimpleInjector.Modularization.Abstractions\TNVS.SimpleInjector.Modularization.Abstractions.csproj", "{7CC6567A-59A9-4E98-9050-C55A6A5631F2}"
79
EndProject
810
Global
911
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -15,6 +17,10 @@ Global
1517
{D3CB4D05-21E3-4883-A0FF-9749A64EFAD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
1618
{D3CB4D05-21E3-4883-A0FF-9749A64EFAD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
1719
{D3CB4D05-21E3-4883-A0FF-9749A64EFAD0}.Release|Any CPU.Build.0 = Release|Any CPU
20+
{7CC6567A-59A9-4E98-9050-C55A6A5631F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{7CC6567A-59A9-4E98-9050-C55A6A5631F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{7CC6567A-59A9-4E98-9050-C55A6A5631F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{7CC6567A-59A9-4E98-9050-C55A6A5631F2}.Release|Any CPU.Build.0 = Release|Any CPU
1824
EndGlobalSection
1925
GlobalSection(SolutionProperties) = preSolution
2026
HideSolutionNode = FALSE
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
3+
namespace TNVS.SimpleInjector.Modularization
4+
{
5+
public sealed class AssemblyLoadException : Exception
6+
{
7+
public AssemblyLoadException(string assemblyPath, Exception innerException) : base($"Could not load assembly from path '{assemblyPath}'.", innerException)
8+
{
9+
AssemblyPath = assemblyPath;
10+
}
11+
12+
public string AssemblyPath { get; }
13+
}
14+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.IO;
3+
using System.Reflection;
4+
5+
namespace TNVS.SimpleInjector.Modularization
6+
{
7+
public static class AssemblyLoadUtilities
8+
{
9+
public static void LoadAssembliesFromFolder(string path, bool recurse = false)
10+
{
11+
var directory = new DirectoryInfo(path);
12+
if (!directory.Exists)
13+
throw new ArgumentException($"The path '{path}' does not exist.");
14+
15+
foreach (var assemblyFile in directory.GetFiles("*.dll", recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
16+
{
17+
try
18+
{
19+
Assembly.LoadFile(assemblyFile.FullName);
20+
}
21+
catch (Exception ex)
22+
{
23+
throw new AssemblyLoadException(assemblyFile.FullName, ex);
24+
}
25+
}
26+
}
27+
}
28+
}

TNVS.SimpleInjector.Modularization/Class1.cs

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
3+
namespace TNVS.SimpleInjector.Modularization
4+
{
5+
public class IncompatibleLifestyleException : Exception
6+
{
7+
public IncompatibleLifestyleException(string message) : base(message)
8+
{
9+
}
10+
11+
public IncompatibleLifestyleException(string message, Exception innerException) : base(message, innerException)
12+
{
13+
}
14+
}
15+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Reflection;
4+
5+
namespace TNVS.SimpleInjector.Modularization
6+
{
7+
/// <summary>
8+
/// Provides options for module registration.
9+
/// </summary>
10+
public sealed class ModuleRegistrationOptions
11+
{
12+
/// <summary>
13+
/// Service types added here will have their registrations registered as a collection, even if only one registration is available.
14+
/// </summary>
15+
public IList<Type> ServiceTypesWithForcedCollectionRegistration { get; } = new List<Type>();
16+
17+
/// <summary>
18+
/// This filter predicate can be used to select the modules to register. If the predicate returns false, the module will not be registered.
19+
/// </summary>
20+
public Func<Type, bool> ModuleTypeFilter { get; set; }
21+
22+
/// <summary>
23+
/// This filter predicate can be used to select the assemblies to load modules from. If the predicate returns false, the assembly will not be searched for modules.
24+
/// </summary>
25+
public Func<Assembly, bool> AssemblyFilter { get; set; }
26+
}
27+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using SimpleInjector;
2+
using System;
3+
using System.Linq;
4+
using TNVS.SimpleInjector.Modularization.Abstractions;
5+
6+
namespace TNVS.SimpleInjector.Modularization
7+
{
8+
public static class SimpleInjectorContainerExtensions
9+
{
10+
/// <summary>
11+
/// Registers all modules from all currently loaded assemblies to this container.
12+
/// </summary>
13+
/// <param name="container">The container to register the modules with.</param>
14+
public static void AddModulesFromLoadedAssemblies(this Container container)
15+
{
16+
AddModulesFromLoadedAssemblies(container, new ModuleRegistrationOptions());
17+
}
18+
19+
/// <summary>
20+
/// Registers all modules from all currently loaded assemblies to this container.
21+
/// </summary>
22+
/// <param name="container">The container to register the modules with.</param>
23+
/// <param name="options"></param>
24+
public static void AddModulesFromLoadedAssemblies(this Container container, ModuleRegistrationOptions options)
25+
{
26+
var assembliesToSearch = AppDomain.CurrentDomain.GetAssemblies().Where(a => options.AssemblyFilter == null || options.AssemblyFilter(a));
27+
var registry = new SimpleInjectorServiceRegistry(container, options.ServiceTypesWithForcedCollectionRegistration.ToList());
28+
var moduleTypes = container.GetTypesToRegister(typeof(IModule), assembliesToSearch).Where(mt => options.ModuleTypeFilter == null || options.ModuleTypeFilter(mt));
29+
foreach (var moduleType in moduleTypes)
30+
{
31+
var moduleInstance = (IModule)Activator.CreateInstance(moduleType);
32+
moduleInstance.RegisterServices(registry);
33+
}
34+
registry.AddCollectedRegistrationsToContainer();
35+
}
36+
}
37+
}

0 commit comments

Comments
 (0)