Skip to content

Commit eff8416

Browse files
Support for generic builders and roots
1 parent 62a0b3a commit eff8416

File tree

3 files changed

+115
-0
lines changed

3 files changed

+115
-0
lines changed

src/Pure.DI.Core/Core/ApiInvocationProcessor.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,10 +292,17 @@ MemberAccessExpressionSyntax memberAccess when memberAccess.Kind() == SyntaxKind
292292
var rootsArgs = arguments.GetArgs(invocation.ArgumentList, "name", "kind");
293293
var rootsName = rootsArgs[0] is { } nameArg ? semantic.GetConstantValue<string>(semanticModel, nameArg.Expression) ?? "" : "";
294294
var kind = rootsArgs[1] is { } kindArg ? semantic.GetConstantValue<RootKinds>(semanticModel, kindArg.Expression) : RootKinds.Default;
295+
var hasRootsType = false;
295296
foreach (var rootType in GetRelatedTypes(semanticModel, invocation, rootsType))
296297
{
297298
var rootName = GetName((SyntaxNode?)rootsArgs[1] ?? invocation, rootsName, rootType) ?? "";
298299
metadataVisitor.VisitRoot(new MdRoot(invocation, semanticModel, rootType, rootName, new MdTag(0, null), kind, invocationComments, false));
300+
hasRootsType = true;
301+
}
302+
303+
if (!hasRootsType)
304+
{
305+
throw new CompileErrorException($"No type that inherits from {symbolNames.GetName(rootsType)} was found.", invocation.GetLocation(), LogId.ErrorInvalidMetadata);
299306
}
300307

301308
break;
@@ -319,6 +326,7 @@ MemberAccessExpressionSyntax memberAccess when memberAccess.Kind() == SyntaxKind
319326
throw new CompileErrorException("Invalid builders type.", invocation.GetLocation(), LogId.ErrorInvalidMetadata);
320327
}
321328

329+
var hasBuildersType = false;
322330
foreach (var builderType in GetRelatedTypes(semanticModel, invocation, buildersRootType))
323331
{
324332
VisitBuilder(
@@ -328,6 +336,13 @@ MemberAccessExpressionSyntax memberAccess when memberAccess.Kind() == SyntaxKind
328336
buildersRootTypeSyntax,
329337
builderType,
330338
invocationComments);
339+
340+
hasBuildersType = true;
341+
}
342+
343+
if (!hasBuildersType)
344+
{
345+
throw new CompileErrorException($"No type that inherits from {symbolNames.GetName(buildersRootType)} was found.", invocation.GetLocation(), LogId.ErrorInvalidMetadata);
331346
}
332347

333348
break;

tests/Pure.DI.IntegrationTests/BuildersTests.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
namespace Pure.DI.IntegrationTests;
22

3+
using Core;
4+
35
public class BuildersTests
46
{
57
[Fact]
@@ -563,4 +565,52 @@ public static void Main()
563565
result.Success.ShouldBeTrue(result);
564566
result.StdOut.ShouldBe(["Initialize 1 Abc", "Initialize 2 Abc"], result);
565567
}
568+
569+
[Fact]
570+
public async Task ShouldShowErrorWhenInheritedTypeNotFound()
571+
{
572+
// Given
573+
574+
// When
575+
var result = await """
576+
using System;
577+
using Pure.DI;
578+
579+
namespace Sample
580+
{
581+
interface IDependency {}
582+
583+
class Dependency: IDependency
584+
{
585+
}
586+
587+
interface IService
588+
{
589+
IDependency? Dep { get; }
590+
}
591+
592+
static class Setup
593+
{
594+
private static void SetupComposition()
595+
{
596+
DI.Setup("Composition")
597+
.Bind().To<Dependency>()
598+
.Builders<IService>();
599+
}
600+
}
601+
602+
public class Program
603+
{
604+
public static void Main()
605+
{
606+
var composition = new Composition();
607+
}
608+
}
609+
}
610+
""".RunAsync();
611+
612+
// Then
613+
result.Success.ShouldBeFalse(result);
614+
result.Errors.Count(i => i.Id == LogId.ErrorInvalidMetadata).ShouldBe(1, result);
615+
}
566616
}

tests/Pure.DI.IntegrationTests/RootsTests.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
namespace Pure.DI.IntegrationTests;
22

3+
using Core;
4+
35
public class RootsTests
46
{
57
[Fact]
@@ -404,4 +406,52 @@ public static void Main()
404406
result.Success.ShouldBeTrue(result);
405407
result.StdOut.ShouldBe(["Initialize 1 Abc", "Initialize 2 Abc", "Initialize 1 Abc", "Initialize 2 Abc"], result);
406408
}
409+
410+
[Fact]
411+
public async Task ShouldShowErrorWhenInheritedTypeNotFound()
412+
{
413+
// Given
414+
415+
// When
416+
var result = await """
417+
using System;
418+
using Pure.DI;
419+
420+
namespace Sample
421+
{
422+
interface IDependency {}
423+
424+
class Dependency: IDependency
425+
{
426+
}
427+
428+
interface IService
429+
{
430+
IDependency? Dep { get; }
431+
}
432+
433+
static class Setup
434+
{
435+
private static void SetupComposition()
436+
{
437+
DI.Setup("Composition")
438+
.Bind().To<Dependency>()
439+
.Roots<IService>();
440+
}
441+
}
442+
443+
public class Program
444+
{
445+
public static void Main()
446+
{
447+
var composition = new Composition();
448+
}
449+
}
450+
}
451+
""".RunAsync();
452+
453+
// Then
454+
result.Success.ShouldBeFalse(result);
455+
result.Errors.Count(i => i.Id == LogId.ErrorInvalidMetadata).ShouldBe(1, result);
456+
}
407457
}

0 commit comments

Comments
 (0)