Skip to content

Add collection return support to ScanForTypes attribute#55

Draft
Copilot wants to merge 2 commits intomainfrom
copilot/return-found-types-as-array
Draft

Add collection return support to ScanForTypes attribute#55
Copilot wants to merge 2 commits intomainfrom
copilot/return-found-types-as-array

Conversation

Copy link
Contributor

Copilot AI commented Mar 20, 2026

ScanForTypes methods can now return Type[] or IEnumerable<Type> (no Handler needed) to get the matched types directly, or return TResponse[]/IEnumerable<TResponse> when a Handler mapping T → TResponse is provided. This feature is exclusive to ScanForTypes; GenerateServiceRegistrations is unaffected.

New capabilities

// Case 1: return matched types directly — no Handler required
[ScanForTypes(AssignableTo = typeof(IService))]
public static partial Type[] GetServiceTypes();
// Generates: return [typeof(MyService1), typeof(MyService2)];

// Case 2: map each found type via a Handler
[ScanForTypes(AssignableTo = typeof(IService), Handler = nameof(Describe))]
public static partial ServiceInfo[] GetServiceInfos();

private static ServiceInfo Describe<T>() => new(typeof(T).Name);
// Generates: return [Describe<MyService1>(), Describe<MyService2>()];

Changes

  • MethodModel — added ReturnTypeIsCollection / CollectionElementTypeName fields and a GetCollectionReturnInfo() helper that detects array and IEnumerable<T> return types using SpecialType.System_Collections_Generic_IEnumerable_T.
  • MethodImplementationModel — added CollectionItems (EquatableArray<string>) holding the pre-built expression strings for each collection element.
  • ParseHandlerMethodModel — relaxes the "Handler required" rule when the return type is Type[]/IEnumerable<Type>; validates Handler return type matches the collection element type for mapped returns.
  • FindServicesToRegister — populates CollectionItems with typeof(T) expressions (no-Handler path) or handler invocation expressions (Handler path).
  • DependencyInjectionGenerator — adds GenerateCollectionSource() emitting a C# collection expression (return [...]); routes generation accordingly.
  • DiagnosticDescriptors — new diagnostic DI0015 (WrongHandlerReturnTypeForCollectionReturn) when the Handler's return type doesn't match the collection element type.
Original prompt

This section details on the original issue you should resolve

<issue_title>Return found types as an array</issue_title>
<issue_description>In some cases I need to process found types, and using CustomHandler is not sufficient.

Acceptance Criteria:

  1. When method with ScanForTypes attribute returns Type[] or IEnumerable, and Handler is not specified - we return collection of found types (use collection expressions in return).
  2. When method with ScanForTypes attribute returns TResponse[] or IEnumerable, and Handler method returns TResponse (i.e. somehow maps found T type to TResponse type) - we return collection of found types mapped by Handler (use collection expressions in return).
  3. If Handler return type does not correspond to collection return type - report error.
  4. It is only supported for ScanForTypes attribute, not GenerateServiceRegistrations attribute.</issue_description>

Comments on the Issue (you are @copilot in this section)


📍 Connect Copilot coding agent with Jira, Azure Boards or Linear to delegate work to Copilot in one click without leaving your project management tool.

…ble<T>)

Co-authored-by: Dreamescaper <17177729+Dreamescaper@users.noreply.github.com>
Copilot AI changed the title [WIP] Return found types as an array implementation Add collection return support to ScanForTypes attribute Mar 20, 2026
Copilot AI requested a review from Dreamescaper March 20, 2026 13:44
Copy link
Owner

@Dreamescaper Dreamescaper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update README

: GenerateCustomHandlingSource(method, customHandling);
: method.ReturnTypeIsCollection
? GenerateCollectionSource(method, collectionItems)
: GenerateCustomHandlingSource(method, customHandling);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace nester ternary with switch expression

typesFound = true;

if (attribute.CustomHandler != null)
var implementationTypeName = implementationType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

split extract collection handling and custom handler to private methods

{
public static partial global::System.Type[] GetServiceTypes()
{
return [typeof(global::GeneratorTests.MyService1), typeof(global::GeneratorTests.MyService2)];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update to use multiline collection expression, e.g.

                public static partial global::System.Type[] GetServiceTypes()
                {
                    return [
                        typeof(global::GeneratorTests.MyService1), 
                        typeof(global::GeneratorTests.MyService2)
                    ];
                }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Return found types as an array

2 participants