diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5475bba..0983bf9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,10 +9,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v1 - - uses: actions/setup-dotnet@v1 + uses: actions/checkout@v5 + - uses: actions/setup-dotnet@v5 with: - dotnet-version: '9.0.x' + dotnet-version: '10.x' - name: Build run: dotnet build @@ -23,10 +23,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v1 - - uses: actions/setup-dotnet@v1 + uses: actions/checkout@v5 + - uses: actions/setup-dotnet@v5 with: - dotnet-version: '9.0.x' + dotnet-version: '10.x' - name: Run tests run: dotnet test diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 70f73a3..18b2e09 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -11,10 +11,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v1 - - uses: actions/setup-dotnet@v1 + uses: actions/checkout@v5 + - uses: actions/setup-dotnet@v5 with: - dotnet-version: '9.0.x' + dotnet-version: '10.x' - name: Build run: dotnet build -c Release -o output - name: Deploy to nuGet gallery diff --git a/.gitignore b/.gitignore index 96e904e..516a722 100644 --- a/.gitignore +++ b/.gitignore @@ -52,7 +52,6 @@ BenchmarkDotNet.Artifacts/ project.lock.json project.fragment.lock.json artifacts/ -**/Properties/launchSettings.json # StyleCop StyleCopReport.xml diff --git a/Debug.LightweightIocContainer.FactoryGenerator/Debug.LightweightIocContainer.FactoryGenerator.csproj b/Debug.LightweightIocContainer.FactoryGenerator/Debug.LightweightIocContainer.FactoryGenerator.csproj new file mode 100644 index 0000000..90b574d --- /dev/null +++ b/Debug.LightweightIocContainer.FactoryGenerator/Debug.LightweightIocContainer.FactoryGenerator.csproj @@ -0,0 +1,16 @@ + + + + net10.0 + preview + enable + enable + + + + + + + \ No newline at end of file diff --git a/Debug.LightweightIocContainer.FactoryGenerator/SampleInstaller.cs b/Debug.LightweightIocContainer.FactoryGenerator/SampleInstaller.cs new file mode 100644 index 0000000..dd14b13 --- /dev/null +++ b/Debug.LightweightIocContainer.FactoryGenerator/SampleInstaller.cs @@ -0,0 +1,20 @@ +// Author: Simon.Gockner +// Created: 2025-12-01 +// Copyright(c) 2025 SimonG. All Rights Reserved. + +using Debug.LightweightIocContainer.FactoryGenerator.Samples; +using Debug.LightweightIocContainer.FactoryGenerator.Samples.Factories; +using Debug.LightweightIocContainer.FactoryGenerator.Samples.Interfaces; +using LightweightIocContainer.FactoryGenerator; +using LightweightIocContainer.Interfaces.Installers; +using LightweightIocContainer.Interfaces.Registrations; + +namespace Debug.LightweightIocContainer.FactoryGenerator; + +public class SampleInstaller : IIocInstaller +{ + public void Install(IRegistrationCollector registration) + { + registration.Add().WithGeneratedFactory(); + } +} \ No newline at end of file diff --git a/Debug.LightweightIocContainer.FactoryGenerator/Samples/Factories/ISampleClassFactory.cs b/Debug.LightweightIocContainer.FactoryGenerator/Samples/Factories/ISampleClassFactory.cs new file mode 100644 index 0000000..9ed43aa --- /dev/null +++ b/Debug.LightweightIocContainer.FactoryGenerator/Samples/Factories/ISampleClassFactory.cs @@ -0,0 +1,21 @@ +using Debug.LightweightIocContainer.FactoryGenerator.Samples.Interfaces; + +namespace Debug.LightweightIocContainer.FactoryGenerator.Samples.Factories; + +public interface ISampleClassFactory +{ + ISampleClass Create(); + T Create() where T : ISampleClass; + Task CreateAsync(); + + ISampleClass Create(string name); + T Create(U param1, V param2) where T : ISampleClass where U : class, new() where V : struct; + Task CreateAsync(U parameter) where T : ISampleClass where U : class; + + ISampleClass Create(Task task) where T : Task; + + Task Create(ISampleClass? sampleClass) where T : class, ISampleClass; + ISampleClass? Create(int id); + + void ClearMultitonInstance() where T : ISampleClass; +} \ No newline at end of file diff --git a/Debug.LightweightIocContainer.FactoryGenerator/Samples/Interfaces/ISampleClass.cs b/Debug.LightweightIocContainer.FactoryGenerator/Samples/Interfaces/ISampleClass.cs new file mode 100644 index 0000000..c9c7c62 --- /dev/null +++ b/Debug.LightweightIocContainer.FactoryGenerator/Samples/Interfaces/ISampleClass.cs @@ -0,0 +1,3 @@ +namespace Debug.LightweightIocContainer.FactoryGenerator.Samples.Interfaces; + +public interface ISampleClass; \ No newline at end of file diff --git a/Debug.LightweightIocContainer.FactoryGenerator/Samples/SampleClass.cs b/Debug.LightweightIocContainer.FactoryGenerator/Samples/SampleClass.cs new file mode 100644 index 0000000..c2b1429 --- /dev/null +++ b/Debug.LightweightIocContainer.FactoryGenerator/Samples/SampleClass.cs @@ -0,0 +1,9 @@ +// Author: Simon.Gockner +// Created: 2025-12-01 +// Copyright(c) 2025 SimonG. All Rights Reserved. + +using Debug.LightweightIocContainer.FactoryGenerator.Samples.Interfaces; + +namespace Debug.LightweightIocContainer.FactoryGenerator.Samples; + +public class SampleClass : ISampleClass; \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md index 43a5e86..fe4cd6f 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Simon G. +Copyright (c) 2025 Simon G. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/LightweightIocContainer.FactoryGenerator/FactoryGenerator.cs b/LightweightIocContainer.FactoryGenerator/FactoryGenerator.cs new file mode 100644 index 0000000..4598053 --- /dev/null +++ b/LightweightIocContainer.FactoryGenerator/FactoryGenerator.cs @@ -0,0 +1,346 @@ +// Author: Simon.Gockner +// Created: 2025-12-01 +// Copyright(c) 2025 SimonG. All Rights Reserved. + +using System.Collections.Immutable; +using System.Text; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace LightweightIocContainer.FactoryGenerator; + +[Generator] +public class FactoryGenerator : IIncrementalGenerator +{ + private const string EXTENSION_CLASS_NAME = "FactoryExtensions"; + private const string BUILDER_CLASS_NAME = "FactoryBuilder"; + + private const string GENERATED_FILE_HEADER = "//---GENERATED by FactoryGenerator! DO NOT EDIT!---"; + private const string INDENT = " "; + + private const string CLEAR_MULTITON_INSTANCE_METHOD_NAME = "ClearMultitonInstance"; + + public void Initialize(IncrementalGeneratorInitializationContext context) + { + string? classNamespace = typeof(FactoryGenerator).Namespace; + context.RegisterPostInitializationOutput(c => c.AddSource($"{EXTENSION_CLASS_NAME}.g.cs", GenerateFactoryExtensionsClass(classNamespace, EXTENSION_CLASS_NAME))); + + IncrementalValuesProvider syntaxProvider = context.SyntaxProvider.CreateSyntaxProvider(IsCallToGenerateFactory, GetTypeArgument); + + context.RegisterSourceOutput(syntaxProvider.Collect(), GenerateTypeDependentClasses); + context.RegisterSourceOutput(syntaxProvider.Collect(), GenerateFactory); + } + + private string GenerateFactoryExtensionsClass(string? classNamespace, string className) + { + StringBuilder stringBuilder = new(); + + stringBuilder.AppendLine(GENERATED_FILE_HEADER); + stringBuilder.AppendLine(); + + stringBuilder.AppendLine("using LightweightIocContainer.Interfaces.Factories;"); + stringBuilder.AppendLine("using LightweightIocContainer.Interfaces.Registrations;"); + stringBuilder.AppendLine(); + + if (!string.IsNullOrEmpty(classNamespace)) + { + stringBuilder.AppendLine($"namespace {classNamespace};"); + stringBuilder.AppendLine(); + } + + stringBuilder.AppendLine($"public static class {className}"); + stringBuilder.AppendLine("{"); + + stringBuilder.AppendLine($"{INDENT}public static IRegistrationBase WithGeneratedFactory(this IRegistrationBase registration)"); + stringBuilder.AppendLine($"{INDENT}{{"); + stringBuilder.AppendLine($"{INDENT}{INDENT}FactoryBuilder factoryBuilder = new();"); + stringBuilder.AppendLine($"{INDENT}{INDENT}registration.AddGeneratedFactory(factoryBuilder);"); + stringBuilder.AppendLine(); + stringBuilder.AppendLine($"{INDENT}{INDENT}return registration;"); + stringBuilder.AppendLine($"{INDENT}}}"); + + stringBuilder.AppendLine("}"); + + return stringBuilder.ToString(); + } + + private bool IsCallToGenerateFactory(SyntaxNode node, CancellationToken cancellationToken) + { + if (!node.IsKind(SyntaxKind.GenericName) || node is not GenericNameSyntax genericNameSyntax) + return false; + + if (!genericNameSyntax.ToString().StartsWith("WithGeneratedFactory")) + return false; + + if (genericNameSyntax.TypeArgumentList.Arguments[0] is not IdentifierNameSyntax) + return false; + + return true; + } + + private ITypeSymbol? GetTypeArgument(GeneratorSyntaxContext syntaxContext, CancellationToken cancellationToken) + { + if (syntaxContext.Node is not GenericNameSyntax genericNameSyntax) + return null; + + if (genericNameSyntax.TypeArgumentList.Arguments[0] is not IdentifierNameSyntax identifierNameSyntax) + return null; + + if (syntaxContext.SemanticModel.GetSymbolInfo(identifierNameSyntax).Symbol is not ITypeSymbol typeSymbol) + return null; + + return typeSymbol; + } + + private void GenerateTypeDependentClasses(SourceProductionContext context, ImmutableArray types) + { + string? classNamespace = typeof(FactoryGenerator).Namespace; + context.AddSource($"{BUILDER_CLASS_NAME}.g.cs", GenerateBuilderClassSourceCode(classNamespace, types)); + } + + private void GenerateFactory(SourceProductionContext context, ImmutableArray types) + { + foreach (ISymbol? symbol in types.Distinct(SymbolEqualityComparer.IncludeNullability)) + { + if (symbol is not ITypeSymbol typeSymbol) + continue; + + context.AddSource($"Generated{typeSymbol.Name}.g.cs", GenerateFactorySourceCode(typeSymbol)); + } + } + + private string GenerateBuilderClassSourceCode(string? classNamespace, ImmutableArray types) + { + StringBuilder stringBuilder = new(); + + stringBuilder.AppendLine(GENERATED_FILE_HEADER); + stringBuilder.AppendLine(); + + stringBuilder.AppendLine("using LightweightIocContainer.Interfaces.Factories;"); + + foreach (string typeNamespace in GetNamespacesOfTypes(types)) + stringBuilder.AppendLine($"using {typeNamespace};"); + + stringBuilder.AppendLine(); + + if (classNamespace is not null) + { + stringBuilder.AppendLine($"namespace {classNamespace};"); + stringBuilder.AppendLine(); + } + + stringBuilder.AppendLine("public class FactoryBuilder : IFactoryBuilder"); + stringBuilder.AppendLine("{"); + stringBuilder.AppendLine($"{INDENT}public TFactory Create(IocContainer container)"); + stringBuilder.AppendLine($"{INDENT}{{"); + + foreach (ISymbol? symbol in types.Distinct(SymbolEqualityComparer.IncludeNullability)) + { + if (symbol is not ITypeSymbol type) + continue; + + stringBuilder.AppendLine($"{INDENT}{INDENT}if (typeof(TFactory) == typeof({type.Name}))"); + stringBuilder.AppendLine($"{INDENT}{INDENT}{{"); + stringBuilder.AppendLine($"{INDENT}{INDENT}{INDENT}return (TFactory) (object) new Generated{type.Name}(container);"); + stringBuilder.AppendLine($"{INDENT}{INDENT}}}"); + stringBuilder.AppendLine(); + } + + stringBuilder.AppendLine($"{INDENT}{INDENT}throw new Exception(\"Invalid type.\");"); + + stringBuilder.AppendLine($"{INDENT}}}"); + stringBuilder.AppendLine("}"); + + return stringBuilder.ToString(); + } + + private string GenerateFactorySourceCode(ITypeSymbol typeSymbol) + { + string typeName = typeSymbol.Name; + string? typeNamespace = typeSymbol.ContainingNamespace.IsGlobalNamespace ? null : typeSymbol.ContainingNamespace.ToString(); + + StringBuilder stringBuilder = new(); + + stringBuilder.AppendLine(GENERATED_FILE_HEADER); + stringBuilder.AppendLine(); + + stringBuilder.AppendLine("#nullable enable"); + stringBuilder.AppendLine(); + + stringBuilder.AppendLine("using LightweightIocContainer;"); + + ImmutableArray members = typeSymbol.GetMembers(); + + List namespaces = []; + foreach (ISymbol? member in members) + { + if (member is not IMethodSymbol method) + continue; + + if (!method.ReturnsVoid) + { + if (method.ReturnType is INamedTypeSymbol { IsGenericType: true } namedTypeSymbol) + { + namespaces.AddRange(namedTypeSymbol.TypeArguments.Select(GetNamespaceOfType)); + + if (method.ReturnType.Name != "Task") + namespaces.Add(GetNamespaceOfType(method.ReturnType)); + } + else + namespaces.Add(GetNamespaceOfType(method.ReturnType)); + } + + namespaces.AddRange(method.Parameters.Select(p => GetNamespaceOfType(p.Type))); + } + + foreach (string @namespace in namespaces.Distinct().OfType().OrderBy(n => n)) + stringBuilder.AppendLine($"using {@namespace};"); + + stringBuilder.AppendLine(); + + if (typeNamespace is not null) + { + stringBuilder.AppendLine($"namespace {typeNamespace};"); + stringBuilder.AppendLine(); + } + + stringBuilder.AppendLine($"public class Generated{typeName}(IocContainer container) : {typeName}"); + stringBuilder.AppendLine("{"); + + foreach (ISymbol? member in members) + { + if (member is not IMethodSymbol method) + continue; + + if (!method.ReturnsVoid) //create method + { + stringBuilder.Append($"{INDENT}public {GetTypeText(method.ReturnType)} {method.Name}"); + + if (method.IsGenericMethod) + stringBuilder.Append(GetGenericParameters(method)); + + stringBuilder.Append($"({string.Join(", ", method.Parameters.Select(GetParameterText))})"); + + if (method.IsGenericMethod) + stringBuilder.Append(GetParameterConstraintsText(method)); + + stringBuilder.AppendLine(); + stringBuilder.AppendLine($"{INDENT}{{"); + + foreach (IParameterSymbol parameter in method.Parameters) + { + stringBuilder.AppendLine($"{INDENT}{INDENT}object? {parameter.Name}Value = {parameter.Name};"); + stringBuilder.AppendLine($"{INDENT}{INDENT}if ({parameter.Name}Value is null)"); + stringBuilder.AppendLine($"{INDENT}{INDENT}{INDENT}{parameter.Name}Value = new NullParameter(typeof({GetTypeText(parameter.Type, false)}));"); + stringBuilder.AppendLine(); + } + + //don't use getTypeText here, because we need the raw type name for Task<> + if (method.ReturnType is INamedTypeSymbol { IsGenericType: true } namedTypeSymbol) + { + if (method.ReturnType.Name == "Task") + stringBuilder.Append($"{INDENT}{INDENT}return container.FactoryResolveAsync{GetGenericArguments(namedTypeSymbol)}("); + else + stringBuilder.Append($"{INDENT}{INDENT}return container.FactoryResolve<{method.ReturnType.Name}{GetGenericArguments(namedTypeSymbol)}>("); + } + else + stringBuilder.Append($"{INDENT}{INDENT}return container.FactoryResolve<{method.ReturnType.Name}>("); + + stringBuilder.Append(string.Join(", ", method.Parameters.Select(p => $"{p.Name}Value"))); + stringBuilder.AppendLine(");"); + + stringBuilder.AppendLine($"{INDENT}}}"); + } + else if (method is { Name: CLEAR_MULTITON_INSTANCE_METHOD_NAME, IsGenericMethod: true }) + { + stringBuilder.Append($"{INDENT}public void {method.Name}{GetGenericParameters(method)}()"); + stringBuilder.Append(GetParameterConstraintsText(method)); + + stringBuilder.AppendLine($" => container.ClearMultitonInstances{GetGenericArguments(method)}();"); + } + + if (members.IndexOf(member) < members.Length - 1) //only append empty line if not the last member + stringBuilder.AppendLine(); + } + + stringBuilder.AppendLine("}"); + + return stringBuilder.ToString(); + } + + private string? GetNamespaceOfType(ITypeSymbol s) => s.ContainingNamespace.IsGlobalNamespace ? null : s.ContainingNamespace.ToString(); + private IEnumerable GetNamespacesOfTypes(ImmutableArray types) => + types.OfType() + .Select(GetNamespaceOfType) + .OfType() + .Distinct(); + + private string GetTypeText(ITypeSymbol typeSymbol) => GetTypeText(typeSymbol, true); + private string GetTypeText(ITypeSymbol typeSymbol, bool allowNullable) + { + StringBuilder stringBuilder = new(); + stringBuilder.Append(typeSymbol.Name); + + if (typeSymbol is INamedTypeSymbol { IsGenericType: true } namedTypeSymbol) + stringBuilder.Append(GetGenericArguments(namedTypeSymbol)); + + if (allowNullable && typeSymbol.NullableAnnotation == NullableAnnotation.Annotated) + stringBuilder.Append("?"); + + return stringBuilder.ToString(); + } + + private string GetParameterText(IParameterSymbol parameter) => $"{GetTypeText(parameter.Type)} {parameter.Name}"; + private string GetGenericArguments(INamedTypeSymbol namedTypeSymbol) => GetGenericArguments(namedTypeSymbol.TypeArguments); + private string GetGenericArguments(IMethodSymbol methodSymbol) => GetGenericArguments(methodSymbol.TypeArguments); + private string GetGenericArguments(ImmutableArray typeArguments) => $"<{string.Join(", ", typeArguments.Select(GetTypeText))}>"; + + private string GetGenericParameters(IMethodSymbol methodSymbol) => GetGenericParameters(methodSymbol.TypeParameters); + private string GetGenericParameters(ImmutableArray typeParameters) => $"<{string.Join(", ", typeParameters.Select(GetTypeText))}>"; + + private string GetParameterConstraintsText(IMethodSymbol method) + { + StringBuilder stringBuilder = new(); + + foreach (ITypeParameterSymbol typeParameter in method.TypeParameters) + { + List parameterConstraints = GetParameterConstraints(typeParameter); + if (parameterConstraints.Count == 0) + continue; + + stringBuilder.Append($" where {typeParameter.Name} : {string.Join(", ", parameterConstraints)}"); + } + + return stringBuilder.ToString(); + } + + private List GetParameterConstraints(ITypeParameterSymbol typeParameterSymbol) + { + List constraints = []; + if (typeParameterSymbol.HasReferenceTypeConstraint) + constraints.Add("class"); + + if (typeParameterSymbol.HasValueTypeConstraint) + constraints.Add("struct"); + + if (typeParameterSymbol.HasUnmanagedTypeConstraint) + constraints.Add("unmanaged"); + + if (typeParameterSymbol.HasNotNullConstraint) + constraints.Add("notnull"); + + foreach (ITypeSymbol constraintType in typeParameterSymbol.ConstraintTypes) + { + if (constraintType is INamedTypeSymbol { IsGenericType: true } namedTypeSymbol) + constraints.Add($"{constraintType.Name}{GetGenericArguments(namedTypeSymbol)}"); + else + constraints.Add(constraintType.Name); + } + + if (typeParameterSymbol.HasConstructorConstraint) + constraints.Add("new()"); + + return constraints; + } +} \ No newline at end of file diff --git a/LightweightIocContainer.FactoryGenerator/LightweightIocContainer.FactoryGenerator.csproj b/LightweightIocContainer.FactoryGenerator/LightweightIocContainer.FactoryGenerator.csproj new file mode 100644 index 0000000..671da42 --- /dev/null +++ b/LightweightIocContainer.FactoryGenerator/LightweightIocContainer.FactoryGenerator.csproj @@ -0,0 +1,39 @@ + + + + netstandard2.0 + SimonG + Copyright(c) 2025 SimonG. All Rights Reserved. + Incremental generator to generate factories + https://github.com/SimonG96/LightweightIocContainer + preview + enable + enable + true + true + 5.0.0 + beta + + + + true + false + true + https://github.com/SimonG96/LightweightIocContainer + MIT + README.md + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LightweightIocContainer.FactoryGenerator/Properties/launchSettings.json b/LightweightIocContainer.FactoryGenerator/Properties/launchSettings.json new file mode 100644 index 0000000..534c373 --- /dev/null +++ b/LightweightIocContainer.FactoryGenerator/Properties/launchSettings.json @@ -0,0 +1,9 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "DebugRoslynSourceGenerator": { + "commandName": "DebugRoslynComponent", + "targetProject": "../Debug.LightweightIocContainer.FactoryGenerator/Debug.LightweightIocContainer.FactoryGenerator.csproj" + } + } +} \ No newline at end of file diff --git a/LightweightIocContainer.FactoryGenerator/README.md b/LightweightIocContainer.FactoryGenerator/README.md new file mode 100644 index 0000000..c02edb9 --- /dev/null +++ b/LightweightIocContainer.FactoryGenerator/README.md @@ -0,0 +1,23 @@ +## Get started with the Lightweight IOC Container Factory Generator + +### How to install + +The easiest way to [install](https://github.com/SimonG96/LghtweightIocContainer/wiki/Install-Lightweight-IOC-Container) the Lightweight IOC Container is by using [NuGet](https://www.nuget.org/packages/LightweightIocContainer.FactoryGenerator/) through the [`.NET CLI`](https://github.com/SimonG96/LightweightIocContainer/wiki/Install-Lightweight-IOC-Container#net-cli): + +```.net +> dotnet add package LightweightIocContainer.FactoryGenerator --version 5.0.0 +``` + +### Example usage + +When registering an interface you can use the `WithGeneratedFactory<>()` method to generate a factory for the registered type: + +```c# +public class SampleInstaller : IIocInstaller +{ + public void Install(IRegistrationCollector registration) + { + registration.Add().WithGeneratedFactory(); + } +} +``` diff --git a/LightweightIocContainer.Validation/LightweightIocContainer.Validation.csproj b/LightweightIocContainer.Validation/LightweightIocContainer.Validation.csproj index f7f5a19..596598d 100644 --- a/LightweightIocContainer.Validation/LightweightIocContainer.Validation.csproj +++ b/LightweightIocContainer.Validation/LightweightIocContainer.Validation.csproj @@ -1,45 +1,45 @@ - - net6.0 - SimonG - Copyright(c) 2024 SimonG. All Rights Reserved. - A lightweight IOC Container Validator. - https://github.com/SimonG96/LightweightIocContainer - latest - enable - enable - LightweightIocContainer.Validation.xml - 4.4.0 - + + net10.0 + SimonG + Copyright(c) 2025 SimonG. All Rights Reserved. + A lightweight IOC Container Validator. + https://github.com/SimonG96/LightweightIocContainer + latest + enable + enable + LightweightIocContainer.Validation.xml + 5.0.0 + beta + - - true - https://github.com/SimonG96/LightweightIocContainer - MIT - README.md - true - snupkg - + + true + https://github.com/SimonG96/LightweightIocContainer + MIT + README.md + true + snupkg + - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + - - - + + + - - - - - - + + + + + + - + \ No newline at end of file diff --git a/LightweightIocContainer.Validation/README.md b/LightweightIocContainer.Validation/README.md index 3127460..9dc2c3f 100644 --- a/LightweightIocContainer.Validation/README.md +++ b/LightweightIocContainer.Validation/README.md @@ -5,7 +5,7 @@ The easiest way to [install](https://github.com/SimonG96/LghtweightIocContainer/wiki/Install-Lightweight-IOC-Container) the Lightweight IOC Container is by using [NuGet](https://www.nuget.org/packages/LightweightIocContainer.Validation/) through the [`.NET CLI`](https://github.com/SimonG96/LightweightIocContainer/wiki/Install-Lightweight-IOC-Container#net-cli): ```.net -> dotnet add package LightweightIocContainer.Validaton --version 4.4.0-beta2 +> dotnet add package LightweightIocContainer.Validation --version 5.0.0 ``` ### Validation diff --git a/LightweightIocContainer.sln b/LightweightIocContainer.sln index e4fa8ab..df30de0 100644 --- a/LightweightIocContainer.sln +++ b/LightweightIocContainer.sln @@ -11,6 +11,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LightweightIocContainer.Val EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.LightweightIocContainer.Validation", "Test.LightweightIocContainer.Validation\Test.LightweightIocContainer.Validation.csproj", "{82818CE7-6219-4A2E-A506-3AE09A00578C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LightweightIocContainer.FactoryGenerator", "LightweightIocContainer.FactoryGenerator\LightweightIocContainer.FactoryGenerator.csproj", "{3AAB43AC-1CBA-4A81-81CB-1EAC2AB792E3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debug.LightweightIocContainer.FactoryGenerator", "Debug.LightweightIocContainer.FactoryGenerator\Debug.LightweightIocContainer.FactoryGenerator.csproj", "{578ED8B2-A2BE-4E10-9422-4D5AF2E605E0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.LightweightIocContainer.FactoryGenerator", "Test.LightweightIocContainer.FactoryGenerator\Test.LightweightIocContainer.FactoryGenerator.csproj", "{0CB46F2E-5429-40BB-9F9F-31606B212E81}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -33,6 +39,18 @@ Global {82818CE7-6219-4A2E-A506-3AE09A00578C}.Debug|Any CPU.Build.0 = Debug|Any CPU {82818CE7-6219-4A2E-A506-3AE09A00578C}.Release|Any CPU.ActiveCfg = Release|Any CPU {82818CE7-6219-4A2E-A506-3AE09A00578C}.Release|Any CPU.Build.0 = Release|Any CPU + {3AAB43AC-1CBA-4A81-81CB-1EAC2AB792E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3AAB43AC-1CBA-4A81-81CB-1EAC2AB792E3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3AAB43AC-1CBA-4A81-81CB-1EAC2AB792E3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3AAB43AC-1CBA-4A81-81CB-1EAC2AB792E3}.Release|Any CPU.Build.0 = Release|Any CPU + {578ED8B2-A2BE-4E10-9422-4D5AF2E605E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {578ED8B2-A2BE-4E10-9422-4D5AF2E605E0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {578ED8B2-A2BE-4E10-9422-4D5AF2E605E0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {578ED8B2-A2BE-4E10-9422-4D5AF2E605E0}.Release|Any CPU.Build.0 = Release|Any CPU + {0CB46F2E-5429-40BB-9F9F-31606B212E81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0CB46F2E-5429-40BB-9F9F-31606B212E81}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0CB46F2E-5429-40BB-9F9F-31606B212E81}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0CB46F2E-5429-40BB-9F9F-31606B212E81}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/LightweightIocContainer/Factories/TypedFactory.cs b/LightweightIocContainer/Factories/TypedFactory.cs index 9f88148..7dc717d 100644 --- a/LightweightIocContainer/Factories/TypedFactory.cs +++ b/LightweightIocContainer/Factories/TypedFactory.cs @@ -19,10 +19,16 @@ public class TypedFactory : TypedFactoryBase, ITypedFactory< private const string CLEAR_MULTITON_INSTANCE_METHOD_NAME = "ClearMultitonInstance"; /// - /// The + /// Constructor for creating factories dynamically /// /// The current instance of the public TypedFactory(IocContainer container) => Factory = CreateFactory(container); + + /// + /// Constructor for generated factories + /// + /// The generated factory instance + public TypedFactory(TFactory factory) => Factory = factory; /// /// The implemented abstract typed factory/> diff --git a/LightweightIocContainer/Interfaces/Factories/IFactoryBuilder.cs b/LightweightIocContainer/Interfaces/Factories/IFactoryBuilder.cs new file mode 100644 index 0000000..f64ae43 --- /dev/null +++ b/LightweightIocContainer/Interfaces/Factories/IFactoryBuilder.cs @@ -0,0 +1,19 @@ +// Author: Simon.Gockner +// Created: 2025-12-02 +// Copyright(c) 2025 SimonG. All Rights Reserved. + +namespace LightweightIocContainer.Interfaces.Factories; + +/// +/// Internal class used by the factory source generator to create factory instances +/// +public interface IFactoryBuilder +{ + /// + /// Internal method used by the factory source generator to create factory instances + /// + /// The current instance of the + /// The type of the factory + /// The created factory instance + TFactory Create(IocContainer container); +} \ No newline at end of file diff --git a/LightweightIocContainer/Interfaces/Registrations/Fluent/IWithFactory.cs b/LightweightIocContainer/Interfaces/Registrations/Fluent/IWithFactory.cs index b06d491..978b045 100644 --- a/LightweightIocContainer/Interfaces/Registrations/Fluent/IWithFactory.cs +++ b/LightweightIocContainer/Interfaces/Registrations/Fluent/IWithFactory.cs @@ -25,6 +25,13 @@ public interface IWithFactory /// The type of the implementation for the custom factory /// The current instance of this IRegistrationBase WithFactory() where TFactoryImplementation : TFactoryInterface; + + /// + /// Internal method used by the factory source generator to add the generated factory to the registration + /// + /// The factory creator + /// The type of the generated factory + void AddGeneratedFactory(IFactoryBuilder factoryBuilder); } internal interface IWithFactoryInternal : IWithFactory diff --git a/LightweightIocContainer/LightweightIocContainer.csproj b/LightweightIocContainer/LightweightIocContainer.csproj index de2ccac..e7b9283 100644 --- a/LightweightIocContainer/LightweightIocContainer.csproj +++ b/LightweightIocContainer/LightweightIocContainer.csproj @@ -1,38 +1,38 @@ - - net6.0 - SimonG - Copyright(c) 2024 SimonG. All Rights Reserved. - A lightweight IOC Container that is powerful enough to do all the things you need it to do. - https://github.com/SimonG96/LightweightIocContainer - latest - enable - enable - LightweightIocContainer.xml - 4.4.0 - + + net10.0 + SimonG + Copyright(c) 2025 SimonG. All Rights Reserved. + A lightweight IOC Container that is powerful enough to do all the things you need it to do. + https://github.com/SimonG96/LightweightIocContainer + latest + enable + enable + LightweightIocContainer.xml + 5.0.0 + beta + - - true - https://github.com/SimonG96/LightweightIocContainer - LICENSE.md - README.md - true - snupkg - + + true + https://github.com/SimonG96/LightweightIocContainer + LICENSE.md + README.md + true + snupkg + - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + - - - - + + + + - + \ No newline at end of file diff --git a/LightweightIocContainer/LightweightIocContainer.xml b/LightweightIocContainer/LightweightIocContainer.xml index ab26ed9..63c2fb5 100644 --- a/LightweightIocContainer/LightweightIocContainer.xml +++ b/LightweightIocContainer/LightweightIocContainer.xml @@ -384,10 +384,16 @@ - The + Constructor for creating factories dynamically The current instance of the + + + Constructor for generated factories + + The generated factory instance + The implemented abstract typed factory/> @@ -480,6 +486,19 @@ The given A new with the given + + + Internal class used by the factory source generator to create factory instances + + + + + Internal method used by the factory source generator to create factory instances + + The current instance of the + The type of the factory + The created factory instance + Non-generic @@ -664,6 +683,13 @@ The type of the implementation for the custom factory The current instance of this + + + Internal method used by the factory source generator to add the generated factory to the registration + + The factory creator + The type of the generated factory + The Factory added with the method @@ -1595,6 +1621,13 @@ The type of the abstract typed factory The current instance of this + + + Internal method used by the factory source generator to add the generated factory to the registration + + The factory creator + The type of the generated factory + Register a custom implemented factory for the diff --git a/LightweightIocContainer/Properties/AssemblyInfo.cs b/LightweightIocContainer/Properties/AssemblyInfo.cs index 79de6d3..b94a037 100644 --- a/LightweightIocContainer/Properties/AssemblyInfo.cs +++ b/LightweightIocContainer/Properties/AssemblyInfo.cs @@ -7,4 +7,5 @@ using System.Runtime.CompilerServices; [assembly:InternalsVisibleTo("LightweightIocContainer.Validation")] [assembly:InternalsVisibleTo("Test.LightweightIocContainer")] +[assembly:InternalsVisibleTo("Test.LightweightIocContainer.FactoryGenerator")] [assembly:InternalsVisibleTo("Test.LightweightIocContainer.Validation")] diff --git a/LightweightIocContainer/Registrations/RegistrationBase.cs b/LightweightIocContainer/Registrations/RegistrationBase.cs index f9c08a3..048f8ec 100644 --- a/LightweightIocContainer/Registrations/RegistrationBase.cs +++ b/LightweightIocContainer/Registrations/RegistrationBase.cs @@ -121,6 +121,19 @@ internal abstract class RegistrationBase : IRegistrationBase, IWithFactoryIntern return this; } + /// + /// Internal method used by the factory source generator to add the generated factory to the registration + /// + /// The factory creator + /// The type of the generated factory + public void AddGeneratedFactory(IFactoryBuilder factoryBuilder) + { + TypedFactory factory = new(factoryBuilder.Create(_container)); + Factory = factory; + + _container.RegisterFactory(factory); + } + /// /// Register a custom implemented factory for the /// diff --git a/README.md b/README.md index 2039dbe..bea9159 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ A lightweight IOC Container that is powerful enough to do all the things you nee [![Nuget](https://img.shields.io/nuget/v/LightweightIocContainer.Validation.svg?label=Validation%20NuGet%20Version&logo=NuGet)](https://www.nuget.org/packages/LightweightIocContainer.Validation/) [![Nuget (with prereleases)](https://img.shields.io/nuget/vpre/LightweightIocContainer.Validation.svg?label=Validation%20NuGet%20Pre-Release&logo=NuGet)](https://www.nuget.org/packages/LightweightIocContainer.Validation/) +[![Nuget](https://img.shields.io/nuget/dt/LightweightIocContainer.FactoryGenerator.svg?label=FactoryGenerator%20NuGet%20Downloads&logo=NuGet)](https://www.nuget.org/packages/LightweightIocContainer.FactoryGenerator/) +[![Nuget](https://img.shields.io/nuget/v/LightweightIocContainer.FactoryGenerator.svg?label=FactoryGenerator%20NuGet%20Version&logo=NuGet)](https://www.nuget.org/packages/LightweightIocContainer.FactoryGenerator/) +[![Nuget (with prereleases)](https://img.shields.io/nuget/vpre/LightweightIocContainer.FactoryGenerator.svg?label=FactoryGenerator%20NuGet%20Pre-Release&logo=NuGet)](https://www.nuget.org/packages/LightweightIocContainer.FactoryGenerator/) + ## Get started with the Lightweight IOC Container ### How to install @@ -19,7 +23,7 @@ A lightweight IOC Container that is powerful enough to do all the things you nee The easiest way to [install](https://github.com/SimonG96/LightweightIocContainer/wiki/Install-Lightweight-IOC-Container) the Lightweight IOC Container is by using [NuGet](https://www.nuget.org/packages/LightweightIocContainer/) through the [`.NET CLI`](https://github.com/SimonG96/LightweightIocContainer/wiki/Install-Lightweight-IOC-Container#net-cli): ```.net -> dotnet add package LightweightIocContainer --version 4.4.0 +> dotnet add package LightweightIocContainer --version 5.0.0 ``` ### Example usage @@ -59,7 +63,7 @@ The easiest way to [install](https://github.com/SimonG96/LightweightIocContainer There is the option to install the [LightweightIocContainer.Validation](https://www.nuget.org/packages/LightweightIocContainer.Validation/) package: ```.net -> dotnet add package LightweightIocContainer.Validaton --version 4.4.0 +> dotnet add package LightweightIocContainer.Validation --version 5.0.0 ``` With this you can validate your `IocContainer` setup by using the `IocValidator` in a unit test: diff --git a/Test.LightweightIocContainer.FactoryGenerator/AsyncFactoryTest.cs b/Test.LightweightIocContainer.FactoryGenerator/AsyncFactoryTest.cs new file mode 100644 index 0000000..41347dd --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/AsyncFactoryTest.cs @@ -0,0 +1,60 @@ +// Author: Simon.Gockner +// Created: 2025-12-03 +// Copyright(c) 2025 SimonG. All Rights Reserved. + +using LightweightIocContainer; +using LightweightIocContainer.FactoryGenerator; +using Test.LightweightIocContainer.FactoryGenerator.TestClasses; +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator; + +[TestFixture] +public class AsyncFactoryTest +{ + [Test] + public async Task TestAsyncFactoryResolve() + { + IocContainer container = new(); + container.Register(r => r.Add().WithGeneratedFactory()); + + IAsyncTestFactory testFactory = container.Resolve(); + IAsyncTest test = await testFactory.Create(); + + Assert.That(test, Is.InstanceOf()); + } + + [Test] + public async Task TestAsyncFactoryResolveOnCreateCalled() + { + IocContainer container = new(); + container.Register(r => r.Add().OnCreateAsync(t => t.Initialize()).WithGeneratedFactory()); + + IAsyncTestFactory testFactory = container.Resolve(); + IAsyncTest test = await testFactory.Create(); + + Assert.That(test, Is.InstanceOf()); + Assert.That(test.IsInitialized, Is.True); + } + + [Test] + public async Task TestAsyncMultitonFactoryResolveOnCreateCalledCorrectly() + { + IocContainer container = new(); + container.Register(r => r.AddMultiton().OnCreateAsync(t => t.Initialize()).WithGeneratedFactory()); + + IAsyncMultitonTestFactory testFactory = container.Resolve(); + IAsyncTest test1 = await testFactory.Create(1); + IAsyncTest test2 = await testFactory.Create(2); + IAsyncTest anotherTest1 = await testFactory.Create(1); + + Assert.That(test1, Is.InstanceOf()); + Assert.That(test1.IsInitialized, Is.True); + + Assert.That(test2, Is.InstanceOf()); + Assert.That(test2.IsInitialized, Is.True); + + Assert.That(test1, Is.SameAs(anotherTest1)); + } +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/FluentFactoryRegistrationTest.cs b/Test.LightweightIocContainer.FactoryGenerator/FluentFactoryRegistrationTest.cs new file mode 100644 index 0000000..dc702a1 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/FluentFactoryRegistrationTest.cs @@ -0,0 +1,212 @@ +// Author: Simon.Gockner +// Created: 2025-12-03 +// Copyright(c) 2025 SimonG. All Rights Reserved. + +using LightweightIocContainer; +using LightweightIocContainer.Exceptions; +using LightweightIocContainer.FactoryGenerator; +using Test.LightweightIocContainer.FactoryGenerator.TestClasses; +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator; + +[TestFixture] +public class FluentFactoryRegistrationTest +{ + private IocContainer _iocContainer; + + [SetUp] + public void SetUp() => _iocContainer = new IocContainer(); + + [TearDown] + public void TearDown() => _iocContainer.Dispose(); + + [Test] + public void TestFluentFactoryRegistration() + { + _iocContainer.Register(r => r.Add().WithGeneratedFactory()); + + IDefaultTestFactory factory = _iocContainer.Resolve(); + IDefaultTest test = factory.Create(); + + Assert.That(factory, Is.InstanceOf()); + Assert.That(test, Is.InstanceOf()); + } + + [Test] + public void TestFluentFactoryRegistrationResolveWithoutFactoryFails() + { + _iocContainer.Register(r => r.Add().WithGeneratedFactory()); + Assert.Throws(()=>_iocContainer.Resolve()); + } + + [Test] + public void TestRegisterFactoryWithoutCreate() => Assert.Throws(() => _iocContainer.Register(r => r.Add().WithGeneratedFactory())); + + [Test] + public void TestResolveFromFactory() + { + _iocContainer.Register(r => r.Add().WithGeneratedFactory()); + + IDefaultTestFactory testFactory = _iocContainer.Resolve(); + IDefaultTest createdTest = testFactory.Create(); + + Assert.That(createdTest, Is.InstanceOf()); + } + + [Test] + public void TestResolveFromFactoryWithParams() + { + _iocContainer.Register(r => r.Add().WithGeneratedFactory()); + _iocContainer.Register(r => r.Add()); //this registration is abnormal and should only be used in unit tests + + IDefaultTestFactory testFactory = _iocContainer.Resolve(); + IDefaultTest createdTest = testFactory.Create("Test"); + + Assert.That(createdTest, Is.InstanceOf()); + } + + [Test] + public void TestResolveFromFactoryWithDefaultParamCreate() + { + _iocContainer.Register(r => r.Add().WithGeneratedFactory()); + _iocContainer.Register(r => r.Add()); //this registration is abnormal and should only be used in unit tests + + IDefaultTestFactory testFactory = _iocContainer.Resolve(); + IDefaultTest createdTest = testFactory.CreateTest(); + + Assert.That(createdTest, Is.InstanceOf()); + } + + [Test] + public void TestResolveFromFactoryWithDefaultParamCtor() + { + _iocContainer.Register(r => r.Add().WithGeneratedFactory()); + _iocContainer.Register(r => r.Add()); //this registration is abnormal and should only be used in unit tests + + IDefaultTestFactory testFactory = _iocContainer.Resolve(); + IDefaultTest createdTest = testFactory.Create(); + + Assert.That(createdTest, Is.InstanceOf()); + } + + [Test] + public void TestResolveFromFactoryWithByte() + { + _iocContainer.Register(r => r.Add().WithGeneratedFactory()); + + IDefaultTestFactory testFactory = _iocContainer.Resolve(); + IDefaultTest createdTest = testFactory.Create(1); + + Assert.That(createdTest, Is.InstanceOf()); + } + + [Test] + public void TestPassingNullAsMiddleParameter() + { + _iocContainer.Register(r => r.Add().WithGeneratedFactory()); + + ITestNullFactory testNullFactory = _iocContainer.Resolve(); + + object obj = new(); + string content = "TestContent"; + string optional2 = "optionalParameter2"; + + IDefaultTest createdTest = testNullFactory.Create(obj, content, null!, optional2); + if (createdTest is not TestNull testNull) + { + Assert.Fail(); + return; + } + + Assert.That(testNull.Obj, Is.SameAs(obj)); + Assert.That(testNull.Content, Is.EqualTo(content)); + Assert.That(testNull.Optional1, Is.Null); + Assert.That(testNull.Optional2, Is.EqualTo(optional2)); + } + + [Test] + public void TestPassingNullAsDefaultParameter() + { + _iocContainer.Register(r => r.Add().WithGeneratedFactory()); + + ITestDefaultFactory testDefaultFactory = _iocContainer.Resolve(); + + object obj = new(); + string content = "TestContent"; + string optional2 = "optionalParameter2"; + + IDefaultTest createdTest = testDefaultFactory.Create(obj, content, null!, optional2); + if (createdTest is not TestNull testNull) + { + Assert.Fail(); + return; + } + + Assert.That(testNull.Obj, Is.SameAs(obj)); + Assert.That(testNull.Content, Is.EqualTo(content)); + Assert.That(testNull.Optional1, Is.Null); + Assert.That(testNull.Optional2, Is.EqualTo(optional2)); + Assert.That(testNull.TestNullFactory, Is.Null); + } + + [Test] + public void TestResolveMultitonFromFactory() + { + _iocContainer.Register(r => r.AddMultiton().WithGeneratedFactory()); + + MultitonScope scope1 = new(); + MultitonScope scope2 = new(); + + IMultitonTestFactory testFactory = _iocContainer.Resolve(); + + IDefaultTest resolvedTest1 = testFactory.Create(scope1); + IDefaultTest resolvedTest2 = testFactory.Create(scope1); + IDefaultTest resolvedTest3 = testFactory.Create(scope2); + + Assert.That(resolvedTest1, Is.SameAs(resolvedTest2)); + Assert.That(resolvedTest1, Is.Not.SameAs(resolvedTest3)); + Assert.That(resolvedTest2, Is.Not.SameAs(resolvedTest3)); + } + + [Test] + public void TestResolveMultitonFromFactoryClearInstances() + { + _iocContainer.Register(r => r.AddMultiton().WithGeneratedFactory()); + + MultitonScope scope1 = new(); + MultitonScope scope2 = new(); + + IMultitonTestFactory testFactory = _iocContainer.Resolve(); + + IDefaultTest resolvedTest1 = testFactory.Create(scope1); + IDefaultTest resolvedTest2 = testFactory.Create(scope1); + IDefaultTest resolvedTest3 = testFactory.Create(scope2); + + Assert.That(resolvedTest1, Is.SameAs(resolvedTest2)); + Assert.That(resolvedTest1, Is.Not.SameAs(resolvedTest3)); + Assert.That(resolvedTest2, Is.Not.SameAs(resolvedTest3)); + + testFactory.ClearMultitonInstance(); + + IDefaultTest resolvedTest4 = testFactory.Create(scope1); + IDefaultTest resolvedTest5 = testFactory.Create(scope2); + + Assert.That(resolvedTest1, Is.Not.SameAs(resolvedTest4)); + Assert.That(resolvedTest2, Is.Not.SameAs(resolvedTest4)); + Assert.That(resolvedTest3, Is.Not.SameAs(resolvedTest5)); + } + + [Test] + public void InvalidMultitonFactoryRegistrationFactoryWithoutParameter() => + Assert.Throws(() => _iocContainer.Register(r => r.AddMultiton().WithGeneratedFactory())); + + [Test] + public void InvalidMultitonFactoryRegistrationFactoryWithoutScopeAsFirstParameter() => + Assert.Throws(() => _iocContainer.Register(r => r.AddMultiton().WithGeneratedFactory())); + + [Test] + public void TestInvalidCreateMethodReturnType() => + Assert.Throws(() => _iocContainer.Register(r => r.Add().WithGeneratedFactory())); +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/MultiLayerResolveTest.cs b/Test.LightweightIocContainer.FactoryGenerator/MultiLayerResolveTest.cs new file mode 100644 index 0000000..ad22459 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/MultiLayerResolveTest.cs @@ -0,0 +1,40 @@ +// Author: Simon.Gockner +// Created: 2025-12-03 +// Copyright(c) 2025 SimonG. All Rights Reserved. + +using LightweightIocContainer; +using LightweightIocContainer.FactoryGenerator; +using Test.LightweightIocContainer.FactoryGenerator.TestClasses; +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator; + +[TestFixture] +public class MultiLayerResolveTest +{ + [Test] + public void TestResolveFactoryAsCtorParameter() + { + IocContainer container = new(); + container.Register(r => r.Add().WithGeneratedFactory()); + container.Register(r => r.Add().WithGeneratedFactory()); + + IAFactory aFactory = container.Resolve(); + IA a = aFactory.Create(); + Assert.That(a, Is.InstanceOf()); + } + + [Test] + public void TestResolveSingleTypeRegistrationAsCtorParameter() + { + IocContainer container = new(); + container.Register(r => r.Add()); + container.Register(r => r.Add().WithGeneratedFactory()); + container.Register(r => r.Add().WithFactoryMethod(_ => new C("test"))); + + IBFactory bFactory = container.Resolve(); + IB b = bFactory.Create(); + Assert.That(b, Is.InstanceOf()); + } +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/OpenGenericRegistrationTest.cs b/Test.LightweightIocContainer.FactoryGenerator/OpenGenericRegistrationTest.cs new file mode 100644 index 0000000..0bbc68c --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/OpenGenericRegistrationTest.cs @@ -0,0 +1,41 @@ +// Author: Simon.Gockner +// Created: 2025-12-03 +// Copyright(c) 2025 SimonG. All Rights Reserved. + +using LightweightIocContainer; +using LightweightIocContainer.FactoryGenerator; +using Test.LightweightIocContainer.FactoryGenerator.TestClasses; +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator; + +[TestFixture] +public class OpenGenericRegistrationTest +{ + private IocContainer _iocContainer; + + [SetUp] + public void SetUp() => _iocContainer = new IocContainer(); + + [TearDown] + public void TearDown() => _iocContainer.Dispose(); + + [Test] + public void TestRegisterFactoryOfOpenGenericType() + { + _iocContainer.Register(r => r.AddOpenGenerics(typeof(IGenericTest<>), typeof(GenericTest<>)).WithGeneratedFactory()); + IGenericTestFactory testFactory = _iocContainer.Resolve(); + IGenericTest test = testFactory.Create(); + Assert.That(test, Is.InstanceOf>()); + } + + [Test] + public void TestRegisterFactoryOfOpenGenericTypeWithCtorParameter() + { + _iocContainer.Register(r => r.AddOpenGenerics(typeof(IGenericTest<>), typeof(CtorGenericTest<>)).WithGeneratedFactory()); + ICtorGenericTestFactory testFactory = _iocContainer.Resolve(); + IGenericTest test = testFactory.Create(new Constraint()); + Assert.That(test, Is.InstanceOf>()); + } +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/Test.LightweightIocContainer.FactoryGenerator.csproj b/Test.LightweightIocContainer.FactoryGenerator/Test.LightweightIocContainer.FactoryGenerator.csproj new file mode 100644 index 0000000..a5be96c --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/Test.LightweightIocContainer.FactoryGenerator.csproj @@ -0,0 +1,33 @@ + + + + net10.0 + latest + enable + enable + false + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/A.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/A.cs new file mode 100644 index 0000000..257c818 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/A.cs @@ -0,0 +1,10 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses; + +public class A : IA +{ + public A(IBFactory bFactory) => BProperty = bFactory.Create(new C("from A")); + public IB BProperty { get; } +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/AsyncMultitonTest.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/AsyncMultitonTest.cs new file mode 100644 index 0000000..f348057 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/AsyncMultitonTest.cs @@ -0,0 +1,13 @@ +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses; + +public class AsyncMultitonTest(int id) : AsyncTest +{ + public int Id { get; } = id; + public override async Task Initialize() + { + if (IsInitialized) + throw new Exception(); + + await base.Initialize(); + } +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/AsyncTest.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/AsyncTest.cs new file mode 100644 index 0000000..db49384 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/AsyncTest.cs @@ -0,0 +1,14 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses; + +public class AsyncTest : IAsyncTest +{ + public bool IsInitialized { get; private set; } + + public virtual async Task Initialize() + { + await Task.Delay(200); + IsInitialized = true; + } +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/B.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/B.cs new file mode 100644 index 0000000..ea3d980 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/B.cs @@ -0,0 +1,10 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses; + +public class B : IB +{ + public B(C c) => C = c; + + public C C { get; } +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/C.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/C.cs new file mode 100644 index 0000000..0c30db7 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/C.cs @@ -0,0 +1,9 @@ +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses; + +public class C +{ + public C(string test) + { + + } +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Constraint.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Constraint.cs new file mode 100644 index 0000000..de12f29 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Constraint.cs @@ -0,0 +1,9 @@ +// Author: Simon.Gockner +// Created: 2025-12-03 +// Copyright(c) 2025 SimonG. All Rights Reserved. + +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses; + +public class Constraint : IConstraint; \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/CtorGenericTest.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/CtorGenericTest.cs new file mode 100644 index 0000000..53447b0 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/CtorGenericTest.cs @@ -0,0 +1,11 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses; + +public class CtorGenericTest : IGenericTest where T : IConstraint, new() +{ + public CtorGenericTest(T item) + { + + } +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/DefaultTest.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/DefaultTest.cs new file mode 100644 index 0000000..8ff1e67 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/DefaultTest.cs @@ -0,0 +1,5 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses; + +public class DefaultTest : IDefaultTest; \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IAFactory.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IAFactory.cs new file mode 100644 index 0000000..f09d0f8 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IAFactory.cs @@ -0,0 +1,8 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; + +public interface IAFactory +{ + IA Create(); +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IAsyncMultitonTestFactory.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IAsyncMultitonTestFactory.cs new file mode 100644 index 0000000..e868964 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IAsyncMultitonTestFactory.cs @@ -0,0 +1,8 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; + +public interface IAsyncMultitonTestFactory +{ + Task Create(int id); +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IAsyncTestFactory.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IAsyncTestFactory.cs new file mode 100644 index 0000000..4da09ba --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IAsyncTestFactory.cs @@ -0,0 +1,8 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; + +public interface IAsyncTestFactory +{ + Task Create(); +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IBFactory.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IBFactory.cs new file mode 100644 index 0000000..893af32 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IBFactory.cs @@ -0,0 +1,9 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; + +public interface IBFactory +{ + IB Create(); + IB Create(C c); +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/ICtorGenericTestFactory.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/ICtorGenericTestFactory.cs new file mode 100644 index 0000000..bda8c3b --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/ICtorGenericTestFactory.cs @@ -0,0 +1,8 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; + +public interface ICtorGenericTestFactory +{ + IGenericTest Create(T item) where T : IConstraint, new(); +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IDefaultTestFactory.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IDefaultTestFactory.cs new file mode 100644 index 0000000..9c4ccda --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IDefaultTestFactory.cs @@ -0,0 +1,11 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; + +public interface IDefaultTestFactory +{ + IDefaultTest Create(); + IDefaultTest Create(string name); + IDefaultTest CreateTest(string name = null!); + IDefaultTest Create(byte id); +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IGenericTestFactory.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IGenericTestFactory.cs new file mode 100644 index 0000000..83a9bdf --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IGenericTestFactory.cs @@ -0,0 +1,8 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; + +public interface IGenericTestFactory +{ + IGenericTest Create() where T : IConstraint, new(); +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IInvalidMultitonTestFactory.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IInvalidMultitonTestFactory.cs new file mode 100644 index 0000000..8250ca9 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IInvalidMultitonTestFactory.cs @@ -0,0 +1,9 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; + +public interface IInvalidMultitonTestFactory +{ + IDefaultTest Create(MultitonScope scope); + IDefaultTest Create(int number); +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IMultitonTestFactory.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IMultitonTestFactory.cs new file mode 100644 index 0000000..9e5effa --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/IMultitonTestFactory.cs @@ -0,0 +1,9 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; + +public interface IMultitonTestFactory +{ + IDefaultTest Create(MultitonScope scope); + void ClearMultitonInstance(); +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/ITestDefaultFactory.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/ITestDefaultFactory.cs new file mode 100644 index 0000000..e88a284 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/ITestDefaultFactory.cs @@ -0,0 +1,8 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; + +public interface ITestDefaultFactory +{ + IDefaultTest Create(object obj, string content, string optional1, string optional2, ITestNullFactory testNullFactory = null!); +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/ITestFactoryNoCreate.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/ITestFactoryNoCreate.cs new file mode 100644 index 0000000..3409b08 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/ITestFactoryNoCreate.cs @@ -0,0 +1,3 @@ +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; + +public interface ITestFactoryNoCreate; \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/ITestFactoryWrongReturn.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/ITestFactoryWrongReturn.cs new file mode 100644 index 0000000..83b5315 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/ITestFactoryWrongReturn.cs @@ -0,0 +1,6 @@ +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; + +public interface ITestFactoryWrongReturn +{ + public MultitonScope Create(); +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/ITestNullFactory.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/ITestNullFactory.cs new file mode 100644 index 0000000..b3a4f80 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Factories/ITestNullFactory.cs @@ -0,0 +1,8 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; + +public interface ITestNullFactory +{ + IDefaultTest Create(object obj, string content, string optional1, string optional2); +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/GenericTest.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/GenericTest.cs new file mode 100644 index 0000000..9265eab --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/GenericTest.cs @@ -0,0 +1,5 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses; + +public class GenericTest : IGenericTest where T : IConstraint, new(); \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IA.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IA.cs new file mode 100644 index 0000000..276ecef --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IA.cs @@ -0,0 +1,6 @@ +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +public interface IA +{ + IB BProperty { get; } +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IAsyncTest.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IAsyncTest.cs new file mode 100644 index 0000000..42af1dd --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IAsyncTest.cs @@ -0,0 +1,7 @@ +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +public interface IAsyncTest +{ + bool IsInitialized { get; } + Task Initialize(); +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IB.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IB.cs new file mode 100644 index 0000000..831f456 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IB.cs @@ -0,0 +1,6 @@ +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +public interface IB +{ + C C { get; } +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IConstraint.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IConstraint.cs new file mode 100644 index 0000000..3956cae --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IConstraint.cs @@ -0,0 +1,3 @@ +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +public interface IConstraint; \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IDefaultTest.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IDefaultTest.cs new file mode 100644 index 0000000..b65741e --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IDefaultTest.cs @@ -0,0 +1,3 @@ +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +public interface IDefaultTest; \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IGenericTest.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IGenericTest.cs new file mode 100644 index 0000000..14a4006 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/Interfaces/IGenericTest.cs @@ -0,0 +1,3 @@ +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +public interface IGenericTest where T : IConstraint, new(); \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/MultitonScope.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/MultitonScope.cs new file mode 100644 index 0000000..7c3fdfe --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/MultitonScope.cs @@ -0,0 +1,3 @@ +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses; + +public class MultitonScope; \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/TestByte.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/TestByte.cs new file mode 100644 index 0000000..81fbacb --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/TestByte.cs @@ -0,0 +1,10 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses; + +public class TestByte : IDefaultTest +{ + private readonly byte _id; + + public TestByte(byte id) => _id = id; +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/TestConstructor.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/TestConstructor.cs new file mode 100644 index 0000000..db2c0e2 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/TestConstructor.cs @@ -0,0 +1,16 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses; + +public class TestConstructor : IDefaultTest +{ + public TestConstructor(string name, DefaultTest test) + { + + } + + public TestConstructor(DefaultTest test, string name = null!) + { + + } +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/TestMultiton.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/TestMultiton.cs new file mode 100644 index 0000000..88ea27d --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/TestMultiton.cs @@ -0,0 +1,11 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses; + +public class TestMultiton : IDefaultTest +{ + public TestMultiton(MultitonScope scope) + { + + } +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.FactoryGenerator/TestClasses/TestNull.cs b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/TestNull.cs new file mode 100644 index 0000000..cf99071 --- /dev/null +++ b/Test.LightweightIocContainer.FactoryGenerator/TestClasses/TestNull.cs @@ -0,0 +1,23 @@ +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Factories; +using Test.LightweightIocContainer.FactoryGenerator.TestClasses.Interfaces; + +namespace Test.LightweightIocContainer.FactoryGenerator.TestClasses; + +public class TestNull : IDefaultTest +{ + + public TestNull(object obj, string content, string optional1, string optional2, ITestNullFactory testNullFactory) + { + Obj = obj; + Content = content; + Optional1 = optional1; + Optional2 = optional2; + TestNullFactory = testNullFactory; + } + + public object Obj { get; } + public string Content { get; } + public string Optional1 { get; } + public string Optional2 { get; } + public ITestNullFactory TestNullFactory { get; } +} \ No newline at end of file diff --git a/Test.LightweightIocContainer.Validation/Test.LightweightIocContainer.Validation.csproj b/Test.LightweightIocContainer.Validation/Test.LightweightIocContainer.Validation.csproj index e716491..684e40c 100644 --- a/Test.LightweightIocContainer.Validation/Test.LightweightIocContainer.Validation.csproj +++ b/Test.LightweightIocContainer.Validation/Test.LightweightIocContainer.Validation.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 false SimonG default @@ -9,11 +9,11 @@ - - + + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Test.LightweightIocContainer/Test.LightweightIocContainer.csproj b/Test.LightweightIocContainer/Test.LightweightIocContainer.csproj index ce75ffa..da69d46 100644 --- a/Test.LightweightIocContainer/Test.LightweightIocContainer.csproj +++ b/Test.LightweightIocContainer/Test.LightweightIocContainer.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 false SimonG default @@ -9,11 +9,11 @@ - - + + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive