Compare commits

..

11 Commits

  1. 8
      Debug.LightweightIocContainer.FactoryGenerator/SampleClass.cs
  2. 51
      LightweightIocContainer.FactoryGenerator/FactoryGenerator.cs
  3. 14
      LightweightIocContainer.FactoryGenerator/README.md

@ -10,4 +10,12 @@ public interface ISampleClass;
public interface ISampleClassFactory
{
ISampleClass Create();
T Create<T>() where T : ISampleClass;
Task<ISampleClass> CreateAsync();
ISampleClass Create(string name);
T Create<T, U, V>(U param1, V param2) where T : ISampleClass where U : class, new() where V : struct;
Task<T> CreateAsync<T, U>(U parameter) where T : ISampleClass where U : class;
void ClearMultitonInstance<T>() where T : ISampleClass;
}

@ -49,7 +49,7 @@ public class FactoryGenerator : IIncrementalGenerator
stringBuilder.AppendLine();
}
stringBuilder.AppendLine($"public static class {className}");;
stringBuilder.AppendLine($"public static class {className}");
stringBuilder.AppendLine("{");
stringBuilder.AppendLine($"{INDENT}public static IRegistrationBase WithGeneratedFactory<TFactory>(this IRegistrationBase registration)");
@ -162,6 +162,9 @@ public class FactoryGenerator : IIncrementalGenerator
stringBuilder.AppendLine(GENERATED_FILE_HEADER);
stringBuilder.AppendLine();
stringBuilder.AppendLine("#nullable enable");
stringBuilder.AppendLine();
stringBuilder.AppendLine("using LightweightIocContainer;");
stringBuilder.AppendLine();
@ -174,16 +177,23 @@ public class FactoryGenerator : IIncrementalGenerator
stringBuilder.AppendLine($"public class Generated{typeName}(IocContainer container) : {typeName}");
stringBuilder.AppendLine("{");
foreach (ISymbol? member in typeSymbol.GetMembers())
ImmutableArray<ISymbol> members = typeSymbol.GetMembers();
foreach (ISymbol? member in members)
{
if (member is not IMethodSymbol method)
continue;
stringBuilder.AppendLine();
if (!method.ReturnsVoid) //create method
{
stringBuilder.Append($"{INDENT}public {method.ReturnType.Name} {method.Name}");
stringBuilder.Append($"{INDENT}public {method.ReturnType.Name}");
if (method.ReturnType.Name == "Task")
{
if (method.ReturnType is INamedTypeSymbol { IsGenericType: true } namedTypeSymbol)
stringBuilder.Append($"<{string.Join(", ", namedTypeSymbol.TypeArguments.Select(a => a.Name))}>");
}
stringBuilder.Append($" {method.Name}");
if (method.IsGenericMethod)
stringBuilder.Append($"<{string.Join(", ", method.TypeParameters.Select(p => p.Name))}>");
@ -207,14 +217,21 @@ public class FactoryGenerator : IIncrementalGenerator
foreach (IParameterSymbol parameter in method.Parameters)
{
stringBuilder.AppendLine($"{INDENT}{INDENT}object? {parameter.Name}Value = {parameter.Name}");
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({parameter.Type.Name}));");
stringBuilder.AppendLine();
}
if (method.IsAsync)
stringBuilder.Append($"{INDENT}{INDENT}return await container.ResolveAsync<>("); //TODO: Get return type from Task<>
if (method.ReturnType.Name == "Task")
{
stringBuilder.Append($"{INDENT}{INDENT}return container.ResolveAsync");
if (method.ReturnType is INamedTypeSymbol { IsGenericType: true } namedTypeSymbol)
stringBuilder.Append($"<{string.Join(", ", namedTypeSymbol.TypeArguments.Select(a => a.Name))}>");
stringBuilder.Append("(");
}
else
stringBuilder.Append($"{INDENT}{INDENT}return container.Resolve<{method.ReturnType.Name}>(");
@ -223,13 +240,25 @@ public class FactoryGenerator : IIncrementalGenerator
stringBuilder.AppendLine($"{INDENT}}}");
}
else if (method.Name == CLEAR_MULTITON_INSTANCE_METHOD_NAME)
else if (method is { Name: CLEAR_MULTITON_INSTANCE_METHOD_NAME, IsGenericMethod: true })
{
//TODO
stringBuilder.Append($"{INDENT}public void {method.Name}<{string.Join(", ", method.TypeParameters.Select(p => p.Name))}>()");
foreach (ITypeParameterSymbol typeParameter in method.TypeParameters)
{
List<string> parameterConstraints = GetParameterConstraints(typeParameter);
if (parameterConstraints.Count == 0)
continue;
stringBuilder.Append($" where {typeParameter.Name} : {string.Join(", ", parameterConstraints)}");
}
stringBuilder.AppendLine($" => container.ClearMultitonInstances<{string.Join(", ", method.TypeArguments.Select(a => a.Name))}>();");
}
typeSymbol.GetMembers();
if (members.IndexOf(member) < members.Length - 1) //only append empty line if not the last member
stringBuilder.AppendLine();
}
stringBuilder.AppendLine("}");

@ -7,3 +7,17 @@ The easiest way to [install](https://github.com/SimonG96/LghtweightIocContainer/
```.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<ISampleClass, SampleClass>().WithGeneratedFactory<ISampleClassFactory>();
}
}
```

Loading…
Cancel
Save