Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V9.0.0/delegate additions relocation #96

Merged
merged 4 commits into from
Oct 16, 2024

Conversation

gimlichael
Copy link
Owner

@gimlichael gimlichael commented Oct 16, 2024

PR Classification

Design and code refactoring to replace Template with MutableTuple.

PR Summary

The changes involve replacing the Template class with the MutableTuple class across multiple files to enhance flexibility and maintainability.

Following Framework Design Guidelines, non-essential types was also removed from core assembly and refactored/spitted accordingly.

Summary by CodeRabbit

  • New Features

    • Introduced MutableTupleFactory for creating flexible tuple instances.
    • Enhanced ParallelFactory methods to support additional parameters for improved processing capabilities.
  • Bug Fixes

    • Updated XML deserialization in DefaultXmlConverter for better handling of key-value pairs.
  • Tests

    • Added new unit tests for MutableTuple and ActivatorFactory.
    • Refactored existing tests to align with the new structure.

@gimlichael gimlichael self-assigned this Oct 16, 2024
Copy link

coderabbitai bot commented Oct 16, 2024

Walkthrough

The pull request involves significant refactoring of several classes, transitioning them from static to generic sealed classes, enhancing their flexibility. Key updates include the introduction of a new MutableTupleFactory class, modifications to the ParallelFactory methods for improved parallel processing, and the replacement of template-based structures with tuple-based ones in various components. Additionally, several SuppressMessage attributes were added to suppress specific code analysis warnings. New unit tests were also created to validate the changes.

Changes

File(s) Change Summary
ActionFactory.cs, FuncFactory.cs, TesterFuncFactory.cs Refactored to generic sealed classes, changed constructors to public, updated Clone return type, removed overloaded Create methods, revised XML documentation.
GlobalSuppressions.cs Added multiple SuppressMessage attributes for specific methods in Cuemon.Extensions.
MutableTupleFactory.cs Introduced MutableTupleFactory class providing factory methods for MutableTuple objects.
Cuemon.Threading ParallelFactory Classes Updated methods to accept additional parameters, modified internal handling to use MutableTuple, and updated method signatures.
SynchronousLoop.cs, WhileSynchronousLoop.cs Replaced TemplateFactory<TWorker> with MutableTupleFactory<TWorker> in method signatures.
Cuemon.Xml.Serialization.Converters.DefaultXmlConverter.cs Modified key-value pair storage during XML deserialization to use tuple-based approach.
Unit Tests Introduced new tests for MutableTuple and ActivatorFactory, refactored existing tests for compatibility.

Possibly related PRs

  • V9.0.0/task based sceanario relocation #95: The changes in the ActionFactory and FuncFactory classes, specifically the constructor modifications and the transition to using Decorator.RawEnclose, are directly related to the refactoring of the ActionFactory and FuncFactory classes in the main PR.

🐇 In the land of code where rabbits play,
New factories hop in a brighter way.
With tuples in tow, they leap and bound,
In tests and functions, new joys are found!
So here’s to the changes, both swift and spry,
A hop, skip, and jump, oh me, oh my! 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented Oct 16, 2024

Codecov Report

Attention: Patch coverage is 51.37195% with 319 lines in your changes missing coverage. Please review.

Project coverage is 79.74%. Comparing base (d6153ad) to head (dfebf50).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/Cuemon.Core/MutableTuple.cs 73.85% 63 Missing ⚠️
src/Cuemon.Extensions.Core/ActionFactory.cs 0.00% 52 Missing ⚠️
src/Cuemon.Extensions.Core/FuncFactory.cs 0.00% 52 Missing ⚠️
src/Cuemon.Extensions.Core/TesterFuncFactory.cs 0.00% 52 Missing ⚠️
src/Cuemon.IO/StreamFactory.cs 0.00% 0 Missing and 12 partials ⚠️
...rc/Cuemon.Threading/AdvancedParallelFactory.For.cs 16.66% 9 Missing and 1 partial ⚠️
...mon.Threading/AdvancedParallelFactory.ForResult.cs 16.66% 10 Missing ⚠️
.../Cuemon.Threading/AdvancedParallelFactory.While.cs 16.66% 10 Missing ⚠️
...n.Threading/AdvancedParallelFactory.WhileResult.cs 16.66% 10 Missing ⚠️
src/Cuemon.Threading/ParallelFactory.ForEach.cs 16.66% 10 Missing ⚠️
... and 8 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #96      +/-   ##
==========================================
- Coverage   80.14%   79.74%   -0.41%     
==========================================
  Files         614      621       +7     
  Lines       18939    18912      -27     
  Branches     1914     1922       +8     
==========================================
- Hits        15179    15081      -98     
- Misses       3710     3762      +52     
- Partials       50       69      +19     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 38

🧹 Outside diff range and nitpick comments (33)
src/Cuemon.Extensions.Text.Json/Formatters/JsonFormatter.cs (1)

69-72: Approve changes with a minor suggestion for consistency.

The separation of JsonWriterOptions creation improves code readability and maintainability. This change is good and doesn't alter the functionality.

For consistency with the .NET 8.0 version, consider using object initializer syntax:

-                {
-                    Indented = Options.Settings.WriteIndented,
-                    Encoder = Options.Settings.Encoder
-                }))
+                {
+                    Indented = Options.Settings.WriteIndented,
+                    Encoder = Options.Settings.Encoder
+                }))

This minor change would make the code more consistent across different .NET versions.

test/Cuemon.Core.Tests/Reflection/ActivatorFactoryTest.cs (2)

15-68: LGTM: Comprehensive tests for instance creation with various parameters.

The test methods for creating instances with 1 to 5 parameters are well-structured and thorough. They effectively verify the correct creation and initialization of instances with different numbers of parameters.

Consider using a theory test with InlineData to reduce code duplication and improve maintainability. For example:

[Theory]
[InlineData(42)]
[InlineData(42, "Hello")]
[InlineData(42, "Hello", 3.14)]
[InlineData(42, "Hello", 3.14, true)]
[InlineData(42, "Hello", 3.14, true, 'A')]
public void CreateInstance_WithParameters_ShouldCreateInstance(params object[] parameters)
{
    var instance = ActivatorFactory.CreateInstance(parameters);
    Assert.NotNull(instance);
    Assert.IsType<TestClassWithParameters>(instance);
    // Assert properties based on the number of parameters
}

This approach would require modifying the TestClassWithParameters to handle different numbers of parameters, but it would make the tests more concise and easier to maintain.


70-142: LGTM: Well-structured private test classes.

The private test classes are well-implemented, each with the appropriate number of parameters and corresponding properties. They serve their purpose for testing the ActivatorFactory with different parameter counts.

To improve maintainability and reduce code duplication, consider using a single generic test class that can handle different numbers of parameters. For example:

private class TestClassWithParameters<T1, T2, T3, T4, T5>
{
    public TestClassWithParameters(T1 value1 = default, T2 value2 = default, T3 value3 = default, T4 value4 = default, T5 value5 = default)
    {
        Value1 = value1;
        Value2 = value2;
        Value3 = value3;
        Value4 = value4;
        Value5 = value5;
    }

    public T1 Value1 { get; }
    public T2 Value2 { get; }
    public T3 Value3 { get; }
    public T4 Value4 { get; }
    public T5 Value5 { get; }
}

This approach would allow you to use a single class for all test cases, specifying only the required number of type parameters for each test. It would make the code more concise and easier to maintain.

test/Cuemon.Extensions.Core.Tests/MutableTupleFactoryTest.cs (3)

Line range hint 13-20: Update method name for consistency

The method body has been correctly updated to use MutableTupleFactory.CreateZero(). However, the method name CreateZero_ShouldCreateEmpty is now inconsistent with the new class being tested.

Consider renaming the method to MutableTupleFactory_CreateZero_ShouldCreateEmpty for clarity and consistency with the new class name.


Line range hint 22-414: Update all test method names for consistency and clarity

All test methods have been correctly updated to use MutableTupleFactory instead of Template. The assertions and logic remain correct. However, the method names are now inconsistent with their actual behavior and the new class being tested.

Consider renaming all test methods to follow this pattern: MutableTupleFactory_Create<Number>_ShouldCreate<TupleName>. For example:

  • CreateZero_ShouldCreateSingleMutableTupleFactory_CreateOne_ShouldCreateSingle
  • CreateZero_ShouldCreateDoubleMutableTupleFactory_CreateTwo_ShouldCreateDouble
  • ...
  • CreateZero_ShouldCreateVigupleMutableTupleFactory_CreateTwenty_ShouldCreateViguple

This naming convention will improve clarity and consistency across all test methods.


Line range hint 1-414: Consider refactoring tests for improved maintainability

The test class provides comprehensive coverage for all MutableTupleFactory.Create methods. However, there's significant repetition in the test structure. Consider the following improvements:

  1. Implement a parameterized test that covers all cases from 0 to 20 elements. This could significantly reduce code duplication and make it easier to maintain and extend these tests in the future.

  2. Create a helper method to generate the expected values for each tuple size. This would make the tests more readable and easier to maintain.

  3. Use a custom assertion method to check the tuple contents, which could make the individual tests more concise.

Here's a rough example of how this could look:

[Theory]
[InlineData(0)]
[InlineData(1)]
// ... add data for 2 to 20
public void MutableTupleFactory_Create_ShouldCreateCorrectTuple(int size)
{
    var values = Enumerable.Range(1, size).ToArray();
    var sut = CreateTuple(size, values);
    
    Assert.Equal(size > 0, !sut.IsEmpty);
    AssertTupleContents(sut, values);
    TestOutput.WriteLine(sut.ToString());
}

private static IMutableTuple CreateTuple(int size, int[] values)
{
    return size switch
    {
        0 => MutableTupleFactory.CreateZero(),
        1 => MutableTupleFactory.CreateOne(values[0]),
        // ... add cases for 2 to 20
        _ => throw new ArgumentOutOfRangeException(nameof(size))
    };
}

private static void AssertTupleContents(IMutableTuple tuple, int[] expectedValues)
{
    Assert.Equal(expectedValues.Length, tuple.ToArray().Length);
    for (int i = 0; i < expectedValues.Length; i++)
    {
        Assert.Equal(expectedValues[i], tuple.ToArray()[i]);
    }
}

This approach would make the tests more maintainable and easier to extend in the future.

src/Cuemon.Xml/Serialization/Converters/DefaultXmlConverter.cs (1)

115-115: LGTM! Consider adding a comment for clarity.

The replacement of Template.CreateTwo with MutableTuple<object, object> aligns well with the PR objectives of refactoring and enhancing flexibility. This change maintains the existing functionality while potentially improving maintainability.

To enhance code clarity, consider adding a brief comment explaining the purpose of this transformation:

-            var castedValues = values.Select(pair => new MutableTuple<object, object>(Decorator.Enclose(pair.Key).ChangeType(dictionaryType[0]), Decorator.Enclose(pair.Value).ChangeType(dictionaryType[1]))).ToList();
+            // Convert dictionary entries to MutableTuple, applying type conversion for both key and value
+            var castedValues = values.Select(pair => new MutableTuple<object, object>(
+                Decorator.Enclose(pair.Key).ChangeType(dictionaryType[0]),
+                Decorator.Enclose(pair.Value).ChangeType(dictionaryType[1])
+            )).ToList();

This comment and formatting will help future maintainers quickly understand the purpose of this transformation.

test/Cuemon.Core.Tests/MutableTupleTest.cs (2)

1-11: Note the custom testing setup

The test class uses a custom Test base class and Codebelt.Extensions.Xunit. While this is fine for project-specific testing patterns, it's worth documenting the purpose and benefits of this setup to aid in long-term maintainability.

Consider adding a comment explaining the purpose of the custom Test base class and any special features provided by Codebelt.Extensions.Xunit.


13-409: Improve test method naming for clarity

The current naming convention CreateZero_Should... doesn't accurately reflect the test's purpose. These tests are creating tuples with various numbers of elements, not "zero" tuples.

Consider renaming the test methods to better reflect their purpose. For example:

  • CreateEmpty_ShouldCreateEmptyTuple()
  • CreateSingle_ShouldCreateSingleElementTuple()
  • CreateDouble_ShouldCreateTwoElementTuple()
    And so on. This will make the test purposes clearer at a glance.
src/Cuemon.Core/GlobalSuppressions.cs (1)

76-108: LGTM! Comprehensive suppressions for MutableTuple types.

The added suppressions for MutableTuple types are consistent with the existing style and justification patterns in the file. They thoroughly cover potential code analysis warnings for inheritance depth and the number of generic parameters for MutableTuple types from 3 to 20 generic parameters.

For future consideration: If possible, explore ways to apply these suppressions more concisely, perhaps through a single suppression that covers all MutableTuple types. This could help reduce the number of individual suppression attributes and improve maintainability.

src/Cuemon.Extensions.Core/GlobalSuppressions.cs (4)

12-67: Approved: Suppressions for methods with many generic parameters.

The suppressions for the S2436 warning (Types and methods should not have too many generic parameters) are consistently applied across various Create methods in different classes. The justification "By design; allow to exceed generic arguments recommendation" indicates a deliberate architectural choice.

While this approach provides flexibility for advanced use cases, be aware that it may lead to complex method signatures and potential maintainability challenges in the future. Consider documenting the rationale for this design decision in the project's architecture documentation.


68-107: Approved: Suppressions for methods with many parameters.

The suppressions for the S107 warning (Methods should not have too many parameters) are applied consistently to the same methods as the S2436 suppressions. This aligns with the architectural decision to allow methods with many generic parameters and arguments.

While this approach offers flexibility, it's worth considering alternative designs that could reduce complexity:

  1. Use builder patterns or fluent interfaces for complex method calls.
  2. Group related parameters into objects.
  3. Consider using optional parameters or method overloads for less common use cases.

These alternatives could improve API usability while maintaining the desired flexibility.


Line range hint 1-107: Overall assessment: Well-structured suppressions with room for future optimization.

The GlobalSuppressions.cs file is well-organized, with consistent use of SuppressMessage attributes and clear justifications for each suppression. This approach allows for flexibility in the API design while acknowledging and explaining deviations from standard code analysis recommendations.

However, the large number of suppressions, particularly for methods with many generic parameters and arguments, suggests an opportunity for future architectural improvements:

  1. Consider conducting a comprehensive architectural review to identify patterns that lead to these complex method signatures.
  2. Explore design patterns or language features that could simplify the API without sacrificing functionality.
  3. Document the rationale behind these design decisions in the project's architecture documentation to aid future maintenance and onboarding.
  4. Set up a periodic review process for these suppressions to ensure they remain necessary and valid as the project evolves.

Remove Unnecessary Suppression for CA2249

The suppression for CA2249 in GlobalSuppressions.cs appears to be unnecessary as there are no current usages of string.IndexOf within the ContainsAny method.

  • File: src/Cuemon.Extensions.Core/GlobalSuppressions.cs
  • Line: 9-107

Please remove the suppression to maintain code cleanliness.

🔗 Analysis chain

Line range hint 7-9: Approved: Specific suppressions for StringExtensions methods.

The suppressions for CA2249, S3267, and IDE0220 in the StringExtensions class are justified:

  1. CA2249: The use of string.IndexOf instead of string.Contains is necessary due to comparison rules in .NET Standard 2.
  2. S3267 and IDE0220: These are marked as false positives, likely due to specific implementation requirements.

These suppressions address particular implementation details and compatibility issues. To ensure ongoing validity:

Periodically review these suppressions, especially when upgrading to newer framework versions, to determine if they're still necessary. Run the following script to check the current usage:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of suppressed methods in StringExtensions

# Test: Check for the use of string.IndexOf in ContainsAny method
rg --type csharp -A 5 'ContainsAny.*string\.IndexOf'

# Test: Check the implementation of JsUnescape method
rg --type csharp -A 10 'JsUnescape'

Length of output: 9470

src/Cuemon.Threading/AsyncFuncFactory.cs (2)

18-21: LGTM! Consider adding a type argument to MutableTuple.

The change from Template to MutableTuple is consistent with the refactoring. The implementation looks correct and maintains the same functionality.

For improved readability and consistency with other overloads, consider specifying the type argument for MutableTuple:

- return new AsyncFuncFactory<MutableTuple, TResult>((_, token) => method(token), new MutableTuple(), method);
+ return new AsyncFuncFactory<MutableTuple, TResult>((_, token) => method(token), new MutableTuple<object>(), method);

Line range hint 1-428: Overall, the refactoring is well-implemented and improves the AsyncFuncFactory class.

The changes in this file successfully replace the Template class with MutableTuple across all Create method overloads. This refactoring:

  1. Maintains the original functionality of the AsyncFuncFactory class.
  2. Improves flexibility by allowing the use of mutable tuples.
  3. Is consistently applied throughout the file for all generic parameter counts (0 to 15).

The implementation is correct and adheres to the refactoring objectives stated in the PR summary.

Consider documenting the reason for this change in the class-level XML comments, explaining the benefits of using MutableTuple over Template. This would help future maintainers understand the motivation behind this refactoring.

src/Cuemon.Threading/GlobalSuppressions.cs (1)

117-160: Consistent approach to suppressing warnings for methods with many generic parameters.

The added SuppressMessage attributes consistently allow methods to exceed the recommended number of generic parameters and total parameters. This approach appears to be a deliberate design decision to enhance the flexibility of the library.

While this allows for more versatile method signatures, it's worth considering the following points:

  1. Readability: Methods with many generic parameters can be harder to read and understand.
  2. Maintainability: As the number of parameters increases, it becomes more challenging to maintain and modify these methods.
  3. Complexity: High parameter counts might indicate that a method is trying to do too much and could potentially be split into smaller, more focused methods.

Consider documenting the rationale behind this design decision in a central place (e.g., README or architecture documentation) to help future maintainers understand the trade-offs made.

Would you like me to suggest any alternative approaches or patterns that could potentially reduce the need for so many generic parameters while maintaining flexibility?

src/Cuemon.Threading/FuncForEachSynchronousLoop.cs (1)

Line range hint 15-22: Potential Type Compatibility Issue in Type Check

The method FillWorkQueueWorkerFactory<TWorker> now accepts a parameter of type MutableTupleFactory<TWorker>. Inside the method, there is a type check:

if (worker is FuncFactory<TWorker, TResult> wf)
{
    var presult = wf.ExecuteMethod();
    Result.TryAdd(sorter, presult);
}

Given that worker is of type MutableTupleFactory<TWorker>, ensure that it can be cast to FuncFactory<TWorker, TResult>. If MutableTupleFactory<TWorker> does not inherit from or implement FuncFactory<TWorker, TResult>, this condition will always evaluate to false, and the code inside the if block will not execute. Consider updating the type check or the type hierarchy to reflect the correct relationship between these types.

src/Cuemon.Core/ActionFactory.cs (2)

6-6: Clarify the documentation for better readability

The summary comment reads: "Provides a way of invoking an Action delegate regardless of the amount of parameters provided." Consider rephrasing it for clarity. For example: "Provides functionality to invoke an Action delegate with any number of parameters."


Line range hint 26-31: Ensure safe handling of originalDelegate when null

In the constructor, originalDelegate can be null, but it is used in ResolveDelegateInfo(originalDelegate). Confirm that ResolveDelegateInfo correctly handles a null originalDelegate to avoid potential NullReferenceExceptions.

If ResolveDelegateInfo does not handle null values, consider modifying the code:

 public ActionFactory(Action<TTuple> method, TTuple tuple, Delegate originalDelegate) : base(tuple, originalDelegate != null)
 {
     Method = method;
-    DelegateInfo = Decorator.RawEnclose(method).ResolveDelegateInfo(originalDelegate);
+    DelegateInfo = Decorator.RawEnclose(method).ResolveDelegateInfo(originalDelegate ?? method);
 }
src/Cuemon.Threading/ParallelFactory.ForEachAsync.cs (1)

Line range hint 14-19: Consider validating additional arguments for null

In the ForEachAsync method overloads that accept additional arguments (arg, arg1, arg2, etc.), consider adding null checks for these arguments if null values are not expected. This validation ensures that any unintended null values are caught early, preventing potential NullReferenceException during execution.

Example modification for one of the overloads:

 public static Task ForEachAsync<TSource, T>(IEnumerable<TSource> source, Func<TSource, T, CancellationToken, Task> worker, T arg, Action<AsyncWorkloadOptions> setup = null)
 {
     Validator.ThrowIfNull(source);
     Validator.ThrowIfNull(worker);
+    Validator.ThrowIfNull(arg);
     return ForEachCoreAsync(source, AsyncActionFactory.Create(worker, default, arg), setup);
 }

Apply similar null checks to other overloads as appropriate.

Also applies to: 27-33, 40-47, 53-61, 68-77, 83-93

src/Cuemon.Threading/AdvancedParallelFactory.For.cs (1)

164-164: Remove unnecessary byte order mark (BOM) at the end of the file.

Line 164 appears to be an accidental addition of a UTF-8 BOM or whitespace. Consider removing it to maintain file cleanliness.

Apply this diff to remove the unnecessary line:

-}
+
src/Cuemon.Threading/AdvancedParallelFactory.ForAsync.cs (1)

Line range hint 22-146: Consider reducing code duplication in ForAsync overloads

The multiple overloads of the ForAsync method with varying numbers of generic parameters result in repetitive code. Consider using code generation tools, such as T4 templates, or employing variadic generics if supported in the future to reduce duplication and simplify maintenance.

src/Cuemon.Threading/ParallelFactory.ForEachResultAsync.cs (3)

Line range hint 31-89: Consider refactoring to reduce duplication in method overloads

The addition of multiple overloads for ForEachResultAsync with varying numbers of additional generic parameters introduces significant code duplication. This can make the codebase harder to maintain and extend in the future. Consider refactoring these methods to reduce duplication. One approach could be to use a single method that accepts a params array or a collection of arguments.

Here's an example of how you might refactor using a params array:

public static Task<IReadOnlyCollection<TResult>> ForEachResultAsync<TSource, TResult>(
    IEnumerable<TSource> source,
    Func<TSource, object[], CancellationToken, Task<TResult>> worker,
    Action<AsyncWorkloadOptions> setup = null,
    params object[] args)
{
    Validator.ThrowIfNull(source);
    Validator.ThrowIfNull(worker);
    return ForEachResultCoreAsync(source, AsyncFuncFactory.Create(worker, default, args), setup);
}

This approach allows you to handle any number of additional arguments without needing multiple overloads.


Line range hint 31-89: Ensure null checks for additional arguments

In the new overloads of ForEachResultAsync, while source and worker are checked for null values, the additional arguments (arg, arg1, arg2, etc.) are not validated. If these arguments are expected to be non-null, consider adding null checks to prevent potential NullReferenceExceptions during execution.

You might add null checks like:

Validator.ThrowIfNull(arg);

Ensure this is done for each additional argument where null values are not acceptable.


Line range hint 31-89: Review XML documentation for accuracy and completeness

The XML documentation comments for the new overloads should be reviewed to ensure that all <typeparam> and <param> tags correctly correspond to the method's generic parameters and arguments. This will help maintain clear and accurate documentation for users of the API.

For example, in one of the overloads:

/// <typeparam name="T1">The type of the first parameter of the function delegate <paramref name="worker" />.</typeparam>
/// <param name="arg1">The first parameter of the function delegate <paramref name="worker" />.</param>

Ensure that each <typeparam> and <param> tag matches the method signature and that descriptions are clear and consistent across all overloads.

src/Cuemon.Threading/AdvancedParallelFactory.WhileResultAsync.cs (2)

Line range hint 29-33: Add null check for reader parameter in WhileResultAsync methods.

In the WhileResultAsync methods, the reader parameter is not validated for null. To prevent potential NullReferenceException, consider adding a null check using Validator.ThrowIfNull(reader);.

Apply this diff to add null checks:

public static Task<IReadOnlyCollection<TResult>> WhileResultAsync<TReader, TElement, TResult>(
    TReader reader,
    Func<Task<bool>> condition,
    Func<TReader, TElement> provider,
    Func<TElement, CancellationToken, Task<TResult>> worker,
    Action<AsyncWorkloadOptions> setup = null)
{
+   Validator.ThrowIfNull(reader);
    Validator.ThrowIfNull(condition);
    Validator.ThrowIfNull(provider);
    Validator.ThrowIfNull(worker);
    return WhileResultCoreAsync(
        new AsyncForwardIterator<TReader, TElement>(reader, condition, provider),
        AsyncFuncFactory.Create(worker, default),
        setup);
}

Repeat the null check addition for the other overloads of WhileResultAsync.


Line range hint 170-191: Potential thread-safety issue with workerFactory's shared state.

In WhileResultCoreAsync, workerFactory.GenericArguments.Arg1 is being set within the loop before invoking ExecuteMethodAsync. If workerFactory is used concurrently across tasks, modifying its GenericArguments may cause race conditions and incorrect behavior when running in parallel.

Consider modifying the code to ensure that each task operates on its own instance of workerFactory or that the GenericArguments assignment is thread-safe. One possible solution is to create a copy of workerFactory for each task or to pass the necessary arguments directly to ExecuteMethodAsync.

while (workChunks > 0 && readForward)
{
    readForward = await iterator.ReadAsync().ConfigureAwait(false);
    if (!readForward) { break; }
-   workerFactory.GenericArguments.Arg1 = iterator.Current;
-   queue.Add(sorter, workerFactory.ExecuteMethodAsync(options.CancellationToken));
+   var localWorkerFactory = AsyncFuncFactory.Create(
+       workerFactory.Function,
+       default,
+       iterator.Current,
+       workerFactory.GenericArguments.Arguments.Skip(1).ToArray()
+   );
+   queue.Add(sorter, localWorkerFactory.ExecuteMethodAsync(options.CancellationToken));
    workChunks--;
    sorter++;
}

This ensures that each task has its own instance of workerFactory with its own set of GenericArguments.

src/Cuemon.Extensions.Core/ActionFactory.cs (1)

15-407: Reevaluate the necessity of methods with numerous generic parameters

Having methods with up to 15 generic parameters may indicate a design that could be simplified. Consider whether grouping related parameters into a single object or using design patterns like the Builder or Command patterns could improve the code's readability and maintainability.

src/Cuemon.Extensions.Core/FuncFactory.cs (1)

275-276: Correct the grammatical error in the documentation comments.

In the XML documentation for the method handling twelve generic arguments, the phrase "and twelfth generic arguments" should be "and twelve generic arguments" to maintain grammatical consistency with other method summaries.

Apply this diff to correct the grammatical error:

-/// Creates a new <see cref="FuncFactory{TTuple,TResult}"/> instance encapsulating the specified <paramref name="method"/> and twelfth generic arguments.
+/// Creates a new <see cref="FuncFactory{TTuple,TResult}"/> instance encapsulating the specified <paramref name="method"/> and twelve generic arguments.

Also applies to: 304-305

src/Cuemon.Diagnostics/TimeMeasure.cs (1)

Line range hint 255-256: Fix typographical errors in XML comments

Remove the extra space before the period in the XML comments for arg9 in the methods:

  • WithAction<T1, T2, T3, T4, T5, T6, T7, T8, T9>(...) at lines 255-256
  • WithFunc<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>(...) at lines 478-479

Apply these diffs to correct the comments:

For WithAction:

- /// <param name="arg9">The ninth parameter of the <paramref name="action" /> delegate .</param>
+ /// <param name="arg9">The ninth parameter of the <paramref name="action" /> delegate.</param>

For WithFunc:

- /// <param name="arg9">The ninth parameter of the <paramref name="function" /> delegate .</param>
+ /// <param name="arg9">The ninth parameter of the <paramref name="function" /> delegate.</param>

Also applies to: 478-479

src/Cuemon.Extensions.Core/TesterFuncFactory.cs (1)

285-286: Correct the wording from "twelfth generic arguments" to "twelve generic arguments"

The summary and returns comments incorrectly use the ordinal number "twelfth" instead of the cardinal number "twelve" when referring to multiple arguments.

Apply this diff to fix the typographical error:

-        /// Creates a new <see cref="TesterFuncFactory{TTuple,TResult,TSuccess}"/> instance encapsulating the specified <paramref name="method"/> and twelfth generic arguments.
+        /// Creates a new <see cref="TesterFuncFactory{TTuple,TResult,TSuccess}"/> instance encapsulating the specified <paramref name="method"/> and twelve generic arguments.
-        /// <returns>An instance of <see cref="TesterFuncFactory{TTuple,TResult,TSuccess}"/> object initialized with the specified <paramref name="method"/> and twelfth generic arguments.</returns>
+        /// <returns>An instance of <see cref="TesterFuncFactory{TTuple,TResult,TSuccess}"/> object initialized with the specified <paramref name="method"/> and twelve generic arguments.</returns>

Also applies to: 314-314

src/Cuemon.Threading/AsyncActionFactory.cs (1)

Line range hint 17-409: Consider reducing code duplication by generalizing the 'Create' methods

The AsyncActionFactory class contains multiple overloads of the Create method to handle different numbers of generic arguments, leading to significant code duplication. Consider refactoring to reduce redundancy and improve maintainability.

Potential approaches:

  • Use params array or tuples: Accept parameters as a collection, such as an array or a tuple, to handle variable numbers of arguments.
  • Utilize expression trees or reflection: Create a more generic implementation that can handle any number of arguments without the need for multiple overloads.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 5f32194 and dfebf50.

📒 Files selected for processing (60)
  • src/Cuemon.Core/ActionFactory.cs (3 hunks)
  • src/Cuemon.Core/BinaryPrefix.cs (1 hunks)
  • src/Cuemon.Core/DecimalPrefix.cs (1 hunks)
  • src/Cuemon.Core/Extensions/Reflection/AssemblyDecoratorExtensions.cs (1 hunks)
  • src/Cuemon.Core/FuncFactory.cs (4 hunks)
  • src/Cuemon.Core/GlobalSuppressions.cs (1 hunks)
  • src/Cuemon.Core/MutableTuple.cs (1 hunks)
  • src/Cuemon.Core/MutableTupleFactory.cs (2 hunks)
  • src/Cuemon.Core/Patterns.cs (6 hunks)
  • src/Cuemon.Core/PrefixMultiple.cs (1 hunks)
  • src/Cuemon.Core/Reflection/ActivatorFactory.cs (6 hunks)
  • src/Cuemon.Core/Runtime/Serialization/HierarchySerializer.cs (1 hunks)
  • src/Cuemon.Core/TesterFuncFactory.cs (3 hunks)
  • src/Cuemon.Core/Threading/AsyncActionFactory.cs (2 hunks)
  • src/Cuemon.Core/Threading/AsyncFuncFactory.cs (2 hunks)
  • src/Cuemon.Diagnostics/TimeMeasure.Async.cs (2 hunks)
  • src/Cuemon.Diagnostics/TimeMeasure.cs (23 hunks)
  • src/Cuemon.Extensions.Core/ActionFactory.cs (1 hunks)
  • src/Cuemon.Extensions.Core/FuncFactory.cs (1 hunks)
  • src/Cuemon.Extensions.Core/GlobalSuppressions.cs (1 hunks)
  • src/Cuemon.Extensions.Core/MutableTupleFactory.cs (1 hunks)
  • src/Cuemon.Extensions.Core/TesterFuncFactory.cs (1 hunks)
  • src/Cuemon.Extensions.Runtime.Caching/CacheEnumerableExtensions.cs (6 hunks)
  • src/Cuemon.Extensions.Text.Json/Formatters/JsonFormatter.cs (1 hunks)
  • src/Cuemon.IO/Extensions/StreamDecoratorExtensions.cs (1 hunks)
  • src/Cuemon.IO/StreamFactory.cs (14 hunks)
  • src/Cuemon.Net/Mail/MailDistributor.cs (1 hunks)
  • src/Cuemon.Resilience/TransientOperation.Async.cs (1 hunks)
  • src/Cuemon.Resilience/TransientOperation.cs (13 hunks)
  • src/Cuemon.Threading/ActionForEachSynchronousLoop.cs (1 hunks)
  • src/Cuemon.Threading/ActionForSynchronousLoop.cs (1 hunks)
  • src/Cuemon.Threading/ActionWhileSynchronousLoop.cs (1 hunks)
  • src/Cuemon.Threading/AdvancedParallelFactory.For.cs (6 hunks)
  • src/Cuemon.Threading/AdvancedParallelFactory.ForAsync.cs (1 hunks)
  • src/Cuemon.Threading/AdvancedParallelFactory.ForResult.cs (6 hunks)
  • src/Cuemon.Threading/AdvancedParallelFactory.ForResultAsync.cs (1 hunks)
  • src/Cuemon.Threading/AdvancedParallelFactory.While.cs (6 hunks)
  • src/Cuemon.Threading/AdvancedParallelFactory.WhileAsync.cs (1 hunks)
  • src/Cuemon.Threading/AdvancedParallelFactory.WhileResult.cs (6 hunks)
  • src/Cuemon.Threading/AdvancedParallelFactory.WhileResultAsync.cs (1 hunks)
  • src/Cuemon.Threading/AsyncActionFactory.cs (16 hunks)
  • src/Cuemon.Threading/AsyncFuncFactory.cs (16 hunks)
  • src/Cuemon.Threading/AsyncPatterns.cs (1 hunks)
  • src/Cuemon.Threading/ForEachSynchronousLoop.cs (3 hunks)
  • src/Cuemon.Threading/ForSynchronousLoop.cs (3 hunks)
  • src/Cuemon.Threading/FuncForEachSynchronousLoop.cs (2 hunks)
  • src/Cuemon.Threading/FuncForSynchronousLoop.cs (2 hunks)
  • src/Cuemon.Threading/FuncWhileSynchronousLoop.cs (2 hunks)
  • src/Cuemon.Threading/GlobalSuppressions.cs (1 hunks)
  • src/Cuemon.Threading/ParallelFactory.ForEach.cs (6 hunks)
  • src/Cuemon.Threading/ParallelFactory.ForEachAsync.cs (1 hunks)
  • src/Cuemon.Threading/ParallelFactory.ForEachResult.cs (6 hunks)
  • src/Cuemon.Threading/ParallelFactory.ForEachResultAsync.cs (1 hunks)
  • src/Cuemon.Threading/SynchronousLoop.cs (2 hunks)
  • src/Cuemon.Threading/WhileSynchronousLoop.cs (3 hunks)
  • src/Cuemon.Xml/Serialization/Converters/DefaultXmlConverter.cs (1 hunks)
  • test/Cuemon.Core.Tests/MutableTupleTest.cs (1 hunks)
  • test/Cuemon.Core.Tests/Reflection/ActivatorFactoryTest.cs (1 hunks)
  • test/Cuemon.Core.Tests/Reflection/AssemblyDecoratorExtensionsTest.cs (1 hunks)
  • test/Cuemon.Extensions.Core.Tests/MutableTupleFactoryTest.cs (21 hunks)
✅ Files skipped from review due to trivial changes (5)
  • src/Cuemon.Core/BinaryPrefix.cs
  • src/Cuemon.Core/DecimalPrefix.cs
  • src/Cuemon.Core/Extensions/Reflection/AssemblyDecoratorExtensions.cs
  • src/Cuemon.Core/PrefixMultiple.cs
  • src/Cuemon.Core/Runtime/Serialization/HierarchySerializer.cs
🧰 Additional context used
🔇 Additional comments (152)
src/Cuemon.Threading/ActionWhileSynchronousLoop.cs (1)

12-15: LGTM. Verify usage and consider reviewing pattern matching.

The parameter type change from TemplateFactory<TWorker> to MutableTupleFactory<TWorker> aligns with the PR objectives of replacing Template with MutableTuple. This change looks good.

To ensure this change doesn't break existing functionality, please run the following script to check for any other occurrences of TemplateFactory that might need updating:

Consider reviewing the pattern matching logic in the method body. The check for ActionFactory<TWorker> seems unrelated to the parameter type change. Ensure this logic is still relevant and necessary with the new MutableTupleFactory<TWorker> parameter type.

src/Cuemon.Threading/ActionForSynchronousLoop.cs (1)

11-14: LGTM! Verify related code for consistency.

The change from TemplateFactory<TWorker> to MutableTupleFactory<TWorker> aligns with the PR objectives and maintains the method's functionality. Good job on keeping the internal logic intact.

To ensure consistency across the codebase, please run the following script to check for any remaining uses of TemplateFactory that might need updating:

Also, verify that the base class ForSynchronousLoop<TOperand> has been updated similarly:

✅ Verification successful

Verified: All instances of TemplateFactory have been successfully replaced with MutableTupleFactory. No remaining usages found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for remaining uses of TemplateFactory in the codebase

# Test: Search for TemplateFactory usage
rg --type csharp 'TemplateFactory<' -g '!*.Designer.cs'

Length of output: 57


Script:

#!/bin/bash
# Description: Check if ForSynchronousLoop<TOperand> has been updated

# Test: Search for ForSynchronousLoop<TOperand> class definition
rg --type csharp 'class\s+ForSynchronousLoop<TOperand>' -A 10

Length of output: 999


Script:

#!/bin/bash
# Description: Re-verify that all instances of TemplateFactory have been replaced with MutableTupleFactory

# Search for any remaining instances of TemplateFactory in the codebase excluding Designer files
rg --type csharp 'TemplateFactory<' -g '!*.Designer.cs'

# Additionally, search for any usage of TemplateFactory without generic parameters
rg --type csharp 'TemplateFactory\s*[^<]' -g '!*.Designer.cs'

Length of output: 121


Script:

#!/bin/bash
# Description: Verify that the ForSynchronousLoop<TOperand> class has been updated to use MutableTupleFactory

# Search for the constructor or any methods that might still be using TemplateFactory within ForSynchronousLoop
rg --type csharp 'TemplateFactory<' src/Cuemon.Threading/ForSynchronousLoop.cs -A 10

# Alternatively, check for inheritance or overrides that might be affected by the change
rg --type csharp 'class\s+ForSynchronousLoop<TOperand>' -A 20

Length of output: 1953

src/Cuemon.Threading/ActionForEachSynchronousLoop.cs (1)

17-17: Verify compatibility and update related code

The change from TemplateFactory<TWorker> to MutableTupleFactory<TWorker> aligns with the PR objective of replacing Template with MutableTuple. However, this change may have broader implications:

  1. Ensure that all callers of this method have been updated to use MutableTupleFactory<TWorker> instead of TemplateFactory<TWorker>.
  2. Verify that MutableTupleFactory<TWorker> provides all the necessary functionality that was previously available with TemplateFactory<TWorker>.
  3. Check if this change affects the behavior of the ActionFactory<TWorker> cast and the ExecuteMethod() call within the method body.

To ensure all usages have been updated, run the following script:

Consider adding a comment explaining the rationale behind using MutableTupleFactory<TWorker> instead of TemplateFactory<TWorker> to improve code maintainability.

✅ Verification successful

Compatibility Verified Successfully

All instances of TemplateFactory<TWorker> have been successfully replaced with MutableTupleFactory<TWorker>, and no remaining references to the old factory type were found. This ensures compatibility and aligns with the PR objectives.

  • Verified that all method calls and factory usages are updated accordingly.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining usages of TemplateFactory in the codebase
rg --type csharp "TemplateFactory<\w+>"

# Search for usages of MutableTupleFactory to verify the update
rg --type csharp "MutableTupleFactory<\w+>"

# Search for calls to FillWorkQueueWorkerFactory to check if they've been updated
rg --type csharp "FillWorkQueueWorkerFactory<\w+>\s*\("

Length of output: 6776

src/Cuemon.Threading/FuncWhileSynchronousLoop.cs (3)

Line range hint 1-32: Changes align well with PR objectives.

The modifications in this file consistently replace Template with MutableTuple, which aligns perfectly with the PR's goal of enhancing flexibility and maintainability. The internal consistency of the file is maintained, and the changes are applied systematically.

Key points:

  1. TemplateFactory<TWorker> is replaced with MutableTupleFactory<TWorker> in method signatures.
  2. Generic constraints are updated accordingly.
  3. The overall structure and logic of the class remain intact.

These changes contribute to the broader refactoring effort described in the PR objectives.


Line range hint 26-30: LGTM! Verify external usage of this method.

The changes from TemplateFactory<TWorker> to MutableTupleFactory<TWorker> and the updated generic constraint align with the PR objectives. The method body remains consistent with these changes.

Please run the following script to check for any external usage of this method that might be affected by the change:

#!/bin/bash
# Description: Find external usage of GetResult method in FuncWhileSynchronousLoop

# Search for method calls to GetResult on FuncWhileSynchronousLoop instances
rg --type csharp -A 5 'FuncWhileSynchronousLoop.*\.GetResult<'

Line range hint 17-23: LGTM! Verify impact on derived classes.

The change from TemplateFactory<TWorker> to MutableTupleFactory<TWorker> aligns with the PR objectives. The method body remains consistent with this change.

Please run the following script to check for any derived classes that might be affected by this change:

src/Cuemon.Threading/FuncForSynchronousLoop.cs (2)

Line range hint 27-31: LGTM! Verify PrepareExecution method compatibility.

The changes to the parameter type and constraint from Template to MutableTuple align with the PR objectives. The method body remains unchanged, suggesting compatibility with the new types.

Please verify that the PrepareExecution method is still compatible with the new MutableTupleFactory<TWorker>. Run the following script to check for any related changes:


Line range hint 18-25: LGTM! Verify type check and cast compatibility.

The change from TemplateFactory<TWorker> to MutableTupleFactory<TWorker> aligns with the PR objectives. The method body remains unchanged, suggesting compatibility with the new type.

Please verify that the type check and cast to FuncFactory<TWorker, TResult> is still valid with the new MutableTupleFactory<TWorker>. Run the following script to check for any related changes:

✅ Verification successful

Type check and cast compatibility verified.

The inheritance between FuncFactory<TWorker, TResult> and MutableTupleFactory<TWorker> has been confirmed, ensuring that the type check and cast in the FillWorkQueueWorkerFactory method are valid.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for changes in FuncFactory and its relationship with MutableTupleFactory

# Search for FuncFactory definition and usage
echo "Searching for FuncFactory definition and usage:"
rg --type csharp -A 5 "class FuncFactory"
rg --type csharp -A 5 "FuncFactory<"

# Search for MutableTupleFactory definition and usage
echo "Searching for MutableTupleFactory definition and usage:"
rg --type csharp -A 5 "class MutableTupleFactory"
rg --type csharp -A 5 "MutableTupleFactory<"

Length of output: 130794


Script:

#!/bin/bash
# Description: Verify that FuncFactory<TWorker, TResult> inherits from MutableTupleFactory<TWorker>

# Search for FuncFactory class definition and ensure it inherits from MutableTupleFactory
echo "Checking inheritance of FuncFactory<TWorker, TResult>:"
ast-grep --lang csharp --pattern 'public .* FuncFactory<$_, $_> : MutableTupleFactory<$_>' src/

# Search for any class that inherits from both FuncFactory and MutableTupleFactory (if applicable)
echo "Checking for multiple inheritance scenarios:"
ast-grep --lang csharp --pattern 'public .* FuncFactory<$_, $_> : MutableTupleFactory<$_>, $_' src/

Length of output: 1244


Script:

#!/bin/bash
# Description: Verify that FuncFactory<TWorker, TResult> inherits from MutableTupleFactory<TWorker>

# Search for FuncFactory class definition and ensure it inherits from MutableTupleFactory
echo "Checking inheritance of FuncFactory<TWorker, TResult>:"
ast-grep --lang csharp --pattern 'public (sealed |abstract )?class FuncFactory<$_, $_> : MutableTupleFactory<$_>' src/

# There is typically single inheritance in C#; multiple inheritance for classes is not allowed.
# Therefore, the second check for multiple inheritance scenarios can be omitted.
# If needed, interfaces can be checked separately.

Length of output: 584


Script:

#!/bin/bash
# Description: Verify that FuncFactory<TWorker, TResult> inherits from MutableTupleFactory<TWorker>

# Search for FuncFactory class definition and ensure it inherits from MutableTupleFactory
echo "Checking inheritance of FuncFactory<TWorker, TResult>:"
ast-grep --lang csharp --pattern 'public (sealed |abstract )?class FuncFactory<$_, $_> : MutableTupleFactory<$_>' src/

Length of output: 584


Script:

#!/bin/bash
# Description: Verify that FuncFactory<TWorker, TResult> inherits from MutableTupleFactory<TWorker>

# Search for FuncFactory class definitions and display their inheritance
echo "Searching for FuncFactory class definitions and their inheritance:"
rg --type csharp 'public (sealed |abstract )?class FuncFactory<[^>]+> : MutableTupleFactory<[^>]+>' src/

Length of output: 391

src/Cuemon.Threading/SynchronousLoop.cs (3)

Line range hint 24-38: LGTM. Change is consistent and functionality preserved.

The modification from TemplateFactory<TWorker> to MutableTupleFactory<TWorker> aligns with the PR's goal. The method's internal logic remains intact, ensuring that the refactoring doesn't introduce any behavioral changes.


42-42: LGTM. Verify implementations in derived classes.

The change from TemplateFactory<TWorker> to MutableTupleFactory<TWorker> is consistent with the PR objective. As this is an abstract method, ensure all concrete implementations in derived classes are updated accordingly.

To ensure all derived classes are updated, please run the following script:

#!/bin/bash
# Description: Check for classes deriving from SynchronousLoop and their FillWorkQueue implementations

# Test: Find classes that inherit from SynchronousLoop
ast-grep --lang csharp --pattern 'class $CLASS_NAME : $$$SynchronousLoop<$_>'

# Test: Check FillWorkQueue implementations in derived classes
rg --type csharp "class.*:.*SynchronousLoop.*\{" -A 20 | rg "protected override void FillWorkQueue.*\("

19-22: LGTM. Verify usage across the codebase.

The change from TemplateFactory<TWorker> to MutableTupleFactory<TWorker> is consistent with the PR objective. The method's functionality remains unchanged.

To ensure this change doesn't break existing code, please run the following script to check for any remaining usages of TemplateFactory in relation to this class:

src/Cuemon.Core/Threading/AsyncActionFactory.cs (4)

10-10: LGTM: Documentation updated to reflect new type.

The XML documentation for the type parameter TTuple has been correctly updated to reference MutableTuple instead of Template, aligning with the refactoring objectives of the PR.


63-63: LGTM: Clone method signature updated correctly.

The Clone method signature has been properly updated to return MutableTupleFactory<TTuple>, which is consistent with the base class change. The implementation remains correct and doesn't require modification.


Line range hint 1-68: Overall assessment: Changes are well-implemented and align with PR objectives.

The refactoring from Template to MutableTuple has been consistently applied throughout the AsyncActionFactory<TTuple> class. The changes maintain the existing functionality while updating the type system as intended. Good job on keeping the code clean and consistent!


11-11: LGTM: Class signature updated correctly.

The class signature has been properly updated to use MutableTupleFactory<TTuple> as the base class and MutableTuple as the type constraint. This change aligns with the PR objectives.

To ensure this change doesn't introduce any issues, please run the following script to check for any remaining references to TemplateFactory or Template in relation to AsyncActionFactory:

src/Cuemon.Core/Threading/AsyncFuncFactory.cs (4)

8-10: Documentation updates look good.

The simplification of the class description and the update to the TTuple type parameter documentation accurately reflect the changes in the class structure and maintain clarity.


64-67: Clone method update is correct.

The change in the return type of the Clone method to MutableTupleFactory<TTuple> is consistent with the new base class. The implementation remains correct, creating a new instance of AsyncFuncFactory.


12-12: Class inheritance change looks good, but verify impact.

The change from TemplateFactory<TTuple> to MutableTupleFactory<TTuple> aligns with the PR objectives. The added constraint where TTuple : MutableTuple is consistent with the new base class.

Please run the following script to verify the impact of this change on the codebase:

#!/bin/bash
# Description: Check for any remaining references to TemplateFactory in the codebase
# and verify the usage of AsyncFuncFactory with the new inheritance.

# Test 1: Check for any remaining references to TemplateFactory
echo "Checking for remaining references to TemplateFactory:"
rg --type cs "TemplateFactory"

# Test 2: Verify the usage of AsyncFuncFactory
echo "Verifying usage of AsyncFuncFactory:"
rg --type cs "AsyncFuncFactory<.*?>"

# Test 3: Check for any compile errors related to AsyncFuncFactory
echo "Checking for potential compile errors related to AsyncFuncFactory:"
rg --type cs -e "error CS\d+:.*AsyncFuncFactory" -e "error CS\d+:.*MutableTupleFactory"

Line range hint 1-69: Overall, the changes in this file look good and align with the PR objectives.

The refactoring from Template to MutableTuple has been consistently applied in this file. However, given the scope of this change, it's crucial to ensure that this refactoring has been applied consistently across the entire codebase.

Please run the following script to verify the consistency of these changes across the codebase:

This script will help ensure that the refactoring has been applied consistently across the entire codebase.

src/Cuemon.Core/MutableTupleFactory.cs (6)

10-11: LGTM: Class documentation and declaration updated correctly.

The class documentation and declaration have been properly updated to reflect the change from Template to MutableTuple. The constraint on TTuple ensures type safety and consistency with the new MutableTuple design.


14-18: LGTM: Constructor documentation and declaration updated appropriately.

The constructor documentation and declaration have been correctly updated to align with the MutableTupleFactory<TTuple> class name. The parameter documentation now accurately refers to MutableTuple, maintaining consistency with the new design.


26-28: LGTM: Property documentation updated correctly.

The documentation for the GenericArguments property has been properly updated to reference MutableTuple instead of Template. This change maintains consistency with the new design and accurately describes the property's purpose and type.


70-72: LGTM: Clone method documentation updated appropriately.

The documentation for the Clone method has been correctly updated to reference MutableTupleFactory<TTuple>. This change aligns with the class renaming and accurately describes the method's purpose and return type.


74-74: LGTM: Clone method declaration updated correctly.

The Clone method declaration has been properly updated to return MutableTupleFactory<TTuple>, which is consistent with the class renaming. This change ensures type consistency throughout the class.


Line range hint 1-76: Summary: Successful refactoring from TemplateFactory to MutableTupleFactory

The changes in this file successfully implement the transition from Template to MutableTuple. All references, including class name, type constraints, documentation, and method signatures, have been consistently updated. This refactoring aligns with the PR objectives and enhances the code's clarity and maintainability.

Key points:

  1. Class renamed from TemplateFactory<TTuple> to MutableTupleFactory<TTuple>.
  2. Generic type constraint updated from Template to MutableTuple.
  3. All documentation and method signatures updated to reflect the new naming.
  4. Functionality of the class remains intact, with only naming and type references altered.

These changes contribute to the overall goal of replacing the Template class with the MutableTuple class across the codebase, as outlined in the PR objectives.

src/Cuemon.Extensions.Text.Json/Formatters/JsonFormatter.cs (1)

Line range hint 1-7: Verify removal of unused XML namespace.

The AI summary mentions that the using System.Xml; directive has been removed. This is a good practice if the namespace is no longer needed. However, this change is not visible in the provided code snippet.

To confirm this change, please run the following command:

If the command returns no results, it confirms that the unused namespace has been removed as mentioned in the summary.

✅ Verification successful

Removal of Unused XML Namespace Verified.

The using System.Xml; directive has been successfully removed from JsonFormatter.cs, as confirmed by listing all using directives.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for the presence of 'using System.Xml;' in the file

rg --type csharp "using System.Xml;" src/Cuemon.Extensions.Text.Json/Formatters/JsonFormatter.cs

Length of output: 98


Script:

#!/bin/bash
# Description: List all 'using' directives in the specified file to verify removal of 'System.Xml'

grep '^using ' src/Cuemon.Extensions.Text.Json/Formatters/JsonFormatter.cs

Length of output: 219

test/Cuemon.Core.Tests/Reflection/AssemblyDecoratorExtensionsTest.cs (2)

Line range hint 1-138: Overall, the test file remains robust with minimal changes.

The modification to the GetTypes_ShouldReturnAllTypesFromCuemonCore test method is the only change in this file. The other test methods, including those for debug build checking, assembly versioning, and manifest resource retrieval, remain unchanged. This suggests that the core functionality tested by these methods has not been affected by the refactoring efforts described in the PR objectives.


44-44: LGTM! Consider updating the comment for clarity.

The narrowed range (375-425) for allTypesCount aligns well with the PR objective of removing non-essential types from the core assembly. This change reflects a more precise expectation of the number of types present.

To ensure the new range accurately reflects the current state of the assembly, you can run the following script:

Consider updating the comment to more accurately reflect the recent changes:

-            Assert.InRange(allTypesCount, 375, 425); // range because of tooling on CI adding dynamic types and high range of refactoring
+            Assert.InRange(allTypesCount, 375, 425); // range accounts for potential dynamic types added by CI tooling and recent refactoring efforts
test/Cuemon.Core.Tests/Reflection/ActivatorFactoryTest.cs (2)

7-13: LGTM: Well-structured test for parameterless constructor.

The test method is well-written, following the AAA pattern and clearly asserting the expected outcomes. It effectively verifies the creation of an instance using a parameterless constructor.


1-144: Overall: Excellent test coverage for ActivatorFactory.

This new test file provides comprehensive coverage for the ActivatorFactory class, aligning well with the PR objectives of refactoring and improving the codebase. The tests are well-structured, clear, and effectively verify the functionality of creating instances with various numbers of parameters.

The file demonstrates good testing practices, including:

  1. Clear test method names
  2. Proper use of the AAA (Arrange-Act-Assert) pattern
  3. Comprehensive coverage of different scenarios (0 to 5 parameters)
  4. Well-structured private test classes

While the current implementation is solid, consider the suggested refactoring options to further improve maintainability and reduce code duplication.

test/Cuemon.Extensions.Core.Tests/MutableTupleFactoryTest.cs (1)

7-11: LGTM: Class declaration updated correctly

The class name has been appropriately updated from TemplateTest to MutableTupleFactoryTest, reflecting the change in the tested class. The inheritance and constructor remain unchanged, which is correct.

src/Cuemon.Resilience/TransientOperation.Async.cs (2)

399-401: LGTM! Verify impact of type change.

The change from Template to MutableTuple is consistent with the previous modification and aligns with the PR objectives.

To ensure this change doesn't introduce any compatibility issues, please run the following script to check for any usages of the WithFuncAsyncCore method that might be affected:

✅ Verification successful

There was an error executing the previous script. Let's run a corrected script to search for all usages of WithFuncAsyncCore:

[/run_scripts]


Verified: Change is localized with no external impacts.

All usages of WithFuncAsyncCore are contained within TransientOperation.Async.cs, ensuring that the type change from Template to MutableTuple does not affect other parts of the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usages of WithFuncAsyncCore
rg "WithFuncAsyncCore" --type cs

Length of output: 970


Script:

#!/bin/bash
# Search for usages of WithFuncAsyncCore
rg "WithFuncAsyncCore" --type cs

Length of output: 895


394-396: LGTM! Verify impact of type change.

The change from Template to MutableTuple aligns with the PR objectives. This modification enhances code flexibility and maintainability.

To ensure this change doesn't introduce any compatibility issues, please run the following script to check for any usages of the WithActionAsyncCore method that might be affected:

✅ Verification successful

Verified the impact of the type change from Template to MutableTuple. All usages of WithActionAsyncCore have been reviewed and are compatible with the update.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usages of WithActionAsyncCore
rg "WithActionAsyncCore" --type cs

Length of output: 970


Script:

#!/bin/bash
# Search for usages of WithActionAsyncCore
rg "WithActionAsyncCore" --type cs

Length of output: 2216

src/Cuemon.Threading/AsyncFuncFactory.cs (3)

31-34: LGTM! The changes are consistent and correct.

The refactoring from Template<T> to MutableTuple<T> is implemented correctly. The new implementation maintains the same functionality and is consistent with the overall changes.


46-49: LGTM! The changes are consistent and correct.

The refactoring from Template<T1, T2> to MutableTuple<T1, T2> is implemented correctly. The new implementation maintains the same functionality and is consistent with the overall changes.


Line range hint 63-425: LGTM! All remaining methods are consistently refactored.

The changes from Template to MutableTuple are consistently applied across all remaining Create method overloads. Each method maintains its original functionality while using the new MutableTuple class. The implementations are correct and consistent for all generic parameter counts up to 15.

src/Cuemon.Threading/FuncForEachSynchronousLoop.cs (1)

Line range hint 26-30: Verify Consistency of Generic Constraints and Method Usage

The method GetResult<TWorker> now has the constraint where TWorker : MutableTuple<TSource> and accepts a parameter of type MutableTupleFactory<TWorker>. Ensure that all calls to GetResult are updated to match this new signature and constraint. This is important to maintain type safety and prevent potential runtime errors.

You can run the following script to find all usages of GetResult in the codebase:

src/Cuemon.Threading/ForEachSynchronousLoop.cs (3)

21-21: Ensure all references are updated to MutableTupleFactory<TWorker>

The method signature in line 21 has been updated to accept MutableTupleFactory<TWorker> instead of TemplateFactory<TWorker>. Please verify that all calls to this method and related implementations are updated accordingly to prevent any type mismatches or runtime issues.


Line range hint 24-25: Verify thread safety when modifying mutable objects

In lines 24-25, you are assigning a value to shallowWorkerFactory.GenericArguments.Arg1:

shallowWorkerFactory.GenericArguments.Arg1 = item;

Since this code is executed in a multithreaded context, ensure that mutating GenericArguments does not introduce race conditions or other thread safety issues. If shallowWorkerFactory or its members are shared across threads, proper synchronization mechanisms should be implemented.


43-43: Update type constraints in overridden methods

The type constraint in line 43 has been updated to MutableTuple<TSource>:

protected abstract void FillWorkQueueWorkerFactory<TWorker>(MutableTupleFactory<TWorker> worker, long sorter) where TWorker : MutableTuple<TSource>;

Ensure that all derived classes implementing this abstract method are updated to reflect the new type constraint and that they properly inherit from MutableTuple<TSource>.

src/Cuemon.Threading/WhileSynchronousLoop.cs (3)

Line range hint 31-49: Update to MutableTupleFactory Enhances Flexibility

The replacement of TemplateFactory<TWorker> with MutableTupleFactory<TWorker> in the FillWorkQueue method improves the flexibility and maintainability of the worker instantiation process. This change aligns with the refactoring objectives and ensures consistency with the new data structures introduced in the codebase.


45-45: Safe Casting with the 'as' Operator

Casting swf to MutableTupleFactory<TWorker> using the 'as' operator is appropriate since swf originates from shallowWorkerFactory, which is of the same type. This maintains type safety and allows for flexibility in case of future inheritance changes.


56-56: Consistent Method Signature and Constraints

Updating the FillWorkQueueWorkerFactory method to accept MutableTupleFactory<TWorker> and changing the constraint to where TWorker : MutableTuple<TSource> ensures consistency with the new class hierarchy. This aligns with the overall refactoring effort to replace Template classes with MutableTuple classes.

src/Cuemon.Threading/ForSynchronousLoop.cs (2)

50-50: Verify all overrides of 'FillWorkQueueWorkerFactory' are updated

The abstract method FillWorkQueueWorkerFactory<TWorker> now uses MutableTupleFactory<TWorker> instead of TemplateFactory<TWorker>. Ensure that all classes inheriting from ForSynchronousLoop<TOperand> have updated their overrides to match this new signature to prevent abstract method implementation errors.

Run the following script to find any overrides still using the old TemplateFactory<TWorker>:


24-24: Ensure consistent type updates across method signatures

The method FillWorkQueue<TWorker> has been updated to use MutableTupleFactory<TWorker> instead of TemplateFactory<TWorker>. Please verify that all references and implementations of this method across the codebase have been updated accordingly to prevent any mismatches or compilation errors.

You can run the following script to check for any remaining references to the old TemplateFactory<TWorker> in method signatures:

src/Cuemon.Core/ActionFactory.cs (2)

Line range hint 12-17: Review the accessibility change of the constructor

The constructor public ActionFactory(Action<TTuple> method, TTuple tuple) was previously internal and is now public. Exposing this constructor publicly expands the API surface and may have implications for external use. Please confirm that this change is intentional and aligns with the desired encapsulation and accessibility of the class.


52-55: Verify the correctness of the Clone method implementation

In the Clone() method, you cast GenericArguments.Clone() to TTuple. Ensure that the Clone() method of GenericArguments returns an object that can be safely cast to TTuple without risking a runtime exception. If there is a possibility of the cast failing, consider adding checks or handling the potential exception.

src/Cuemon.Core/FuncFactory.cs (4)

27-27: Confirm the change of constructor access modifier to public is intentional.

The constructor's access modifier has been changed from internal to public, increasing its accessibility beyond the assembly. Ensure that this modification aligns with the intended design and does not expose internal functionalities unintentionally.


42-42: Documentation correctly describes the return value of ExecuteMethod().

The <returns> documentation now accurately reflects that the method returns the result of the associated function delegate.


6-10: Ensure all references to TemplateFactory<TTuple> are updated to MutableTupleFactory<TTuple>.

The class FuncFactory<TTuple, TResult> now inherits from MutableTupleFactory<TTuple> instead of TemplateFactory<TTuple>. Make sure that all references to TemplateFactory<TTuple> in the codebase have been updated to prevent any potential issues due to the change in inheritance.

Run the following script to check for any remaining references:

✅ Verification successful

All references to TemplateFactory<TTuple> have been successfully updated to MutableTupleFactory<TTuple>.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for references to TemplateFactory<TTuple> that may need updating.

rg --type cs 'TemplateFactory\<TTuple\>'

Length of output: 20984


Script:

#!/bin/bash
# Description: Search for references to TemplateFactory<TTuple> that may need updating.

rg --type cs 'TemplateFactory\<TTuple\>'

Length of output: 149


Script:

#!/bin/bash
# Description: Search for references to TemplateFactory<TTuple> that may need updating with corrected regex.

rg --type cs 'TemplateFactory\\<TTuple\\>'

Length of output: 44


54-54: Verify the return type change in the overridden Clone method.

The Clone method now returns MutableTupleFactory<TTuple> instead of TemplateFactory<TTuple>. Ensure that this change is consistent with the new inheritance structure and that any dependent code handles the new return type appropriately.

Run the following script to find any overrides or usages that might be impacted:

✅ Verification successful

Further Verification Needed for Clone Method Return Type Change

To ensure the return type change from TemplateFactory<TTuple> to MutableTupleFactory<TTuple> is consistent with the inheritance structure and that dependent code handles the new type appropriately, additional verification is required.


Additional Verification Required to Identify Base Class of FuncFactory<TTuple>

To accurately determine the base class of FuncFactory<TTuple>, please execute the following shell script:


Further Verification Needed to Identify Base Class of FuncFactory<TTuple>

The previous attempts to locate the base class of FuncFactory<TTuple> did not yield any results. To accurately determine the inheritance structure, please execute the following shell script with a more flexible search pattern:


Clone Method Return Type Change Verified

The return type change in the overridden Clone method from TemplateFactory<TTuple> to MutableTupleFactory<TTuple> is consistent with the updated inheritance structure. FuncFactory<TTuple, TResult> now correctly inherits from MutableTupleFactory<TTuple>, ensuring that the overridden method aligns with the base class's signature. Additionally, all usages of the Clone method have been reviewed and are compatible with the new return type.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find references to the Clone method to verify compatibility with the return type change.

rg --type cs 'Clone\(' -A 2 -B 2

Length of output: 20984


Script:

#!/bin/bash
# Description: Find the base class of FuncFactory and verify the return type of its Clone method.

# Find the base class of FuncFactory<TTuple>
ast-grep --lang csharp --pattern $'class FuncFactory<TTuple> : $_BaseClass {
  $$$
}' src/Cuemon.Core/FuncFactory.cs

Length of output: 117


Script:

#!/bin/bash
# Description: Find the return type of the base class's Clone method.

rg --type cs 'public override .* Clone\(' -A 2 -B 2

Length of output: 14906


Script:

#!/bin/bash
# Description: Find the base class of FuncFactory<TTuple> by locating its class declaration.

rg --type cs '^public\s+class\s+FuncFactory<[^>]+>\s*:\s*([^\\{]+)' src/Cuemon.Core/FuncFactory.cs

Length of output: 100


Script:

#!/bin/bash
# Description: Find the base class of FuncFactory<TTuple> by locating its class declaration with a flexible pattern.

rg --type cs 'class\s+FuncFactory<[^>]+>\s*:\s*([^\\{]+)' src/Cuemon.Core/FuncFactory.cs

Length of output: 201

src/Cuemon.Core/TesterFuncFactory.cs (3)

7-9: Documentation comments updated appropriately.

The summary and type parameter documentation accurately reflect the new class's purpose and parameters.


12-12: Class definition updated correctly.

The class has been correctly updated to a generic class with appropriate inheritance and constraints.


29-29: Verify the necessity of changing constructor visibility to public.

Changing the constructor from internal to public increases the accessibility of the class. Confirm that this change is intentional and does not expose internal implementation details that should remain encapsulated.

Run the following script to check for usages of the public constructor outside the assembly:

✅ Verification successful

Change to public constructor is justified.

The constructor of TesterFuncFactory is used in both Cuemon.Core and Cuemon.Extensions.Core, indicating that public visibility is necessary to support these internal extensions.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find external usages of the TesterFuncFactory constructor.

# Test: Search for instantiations of TesterFuncFactory throughout the codebase.
# Expect: Usages outside the defining assembly justify the public visibility.

rg --type cs 'new\s+TesterFuncFactory<'

Length of output: 7175

src/Cuemon.Core/Reflection/ActivatorFactory.cs (6)

21-22: Use of MutableTuple in parameterless CreateInstance method is appropriate.

The replacement of Template with MutableTuple in the CreateInstance<TInstance> method aligns with the refactoring objectives and enhances flexibility in instance creation.


36-37: Correct update to MutableTuple<T> in single-parameter CreateInstance method.

The use of MutableTuple<T> effectively encapsulates the constructor argument, maintaining consistency with the new design pattern.


53-54: Consistent implementation using MutableTuple<T1, T2> for two-parameter constructors.

The update accurately reflects the shift to MutableTuple, properly handling multiple constructor parameters.


72-73: Appropriate use of MutableTuple<T1, T2, T3> in three-parameter CreateInstance method.

The change ensures that all three constructor arguments are encapsulated within the MutableTuple, enhancing code maintainability.


93-94: Effective refactoring with MutableTuple<T1, T2, T3, T4> for four-parameter constructors.

This update maintains the pattern established in prior methods and correctly handles the additional parameter.


116-117: Accurate transition to MutableTuple<T1, T2, T3, T4, T5> in five-parameter CreateInstance method.

The method consistently applies the new MutableTuple usage, effectively encapsulating all five constructor arguments.

src/Cuemon.Threading/ParallelFactory.ForEach.cs (6)

19-20: Ensure MutableTuple<TSource> correctly handles the source items

The MutableTuple<TSource> is initialized with default for Arg1. Verify that during iteration, Arg1 is properly assigned the current item from source before being passed to the worker delegate. Otherwise, the worker may not receive the correct TSource value.


36-37: Confirm proper assignment of arguments in MutableTuple<TSource, T>

In the worker factory, MutableTuple<TSource, T> is initialized with default and arg. Ensure that Arg1 (the TSource item) is updated appropriately during iteration, and that Arg2 correctly holds the additional argument arg when invoking the worker delegate.


55-56: Validate parameter mapping in MutableTuple<TSource, T1, T2>

For the overload accepting two additional arguments, check that tuple.Arg1, tuple.Arg2, and tuple.Arg3 correspond to the TSource item, arg1, and arg2 respectively. Ensure that these are correctly assigned and passed to the worker delegate.


76-77: Check argument alignment in MutableTuple<TSource, T1, T2, T3>

Ensure that tuple.Arg1 to tuple.Arg4 represent TSource, arg1, arg2, and arg3 in order. Confirm that the worker delegate receives the correct parameters during execution.


99-100: Verify correctness in MutableTuple<TSource, T1, T2, T3, T4> usage

Confirm that all arguments (Arg1 to Arg5) in the MutableTuple are properly assigned to TSource and arg1 through arg4. Ensure the worker delegate invocation uses these arguments accurately.


124-125: Ensure all parameters are correctly passed in MutableTuple<TSource, T1, T2, T3, T4, T5>

With five additional arguments, validate that tuple.Arg1 to tuple.Arg6 correctly represent TSource, arg1, arg2, arg3, arg4, and arg5. Check that the worker delegate is invoked with the correct parameters.

src/Cuemon.Threading/ParallelFactory.ForEachAsync.cs (1)

131-131: Type constraint updated to MutableTuple

The change of the type constraint from Template<TSource> to MutableTuple<TSource> in the ForEachCoreAsync method aligns with the PR objectives of replacing the Template class. This update enhances flexibility and maintains consistency with the new design.

src/Cuemon.Threading/AdvancedParallelFactory.For.cs (6)

45-46: Confirm correct mapping of arguments in MutableTuple<TOperand, T>.

The lambda expression maps tuple.Arg1 and tuple.Arg2 to the worker delegate's parameters. Ensure that tuple.Arg1 corresponds to TOperand and tuple.Arg2 corresponds to T as intended.

To verify, you can review the MutableTuple implementation to confirm the order of arguments.


69-70: Validate the integrity of MutableTuple<TOperand, T1, T2> usage.

In the updated ActionFactory, confirm that the tuple arguments correctly correspond to the parameters of the worker delegate. Specifically, check that tuple.Arg1 is TOperand, tuple.Arg2 is T1, and tuple.Arg3 is T2.


95-96: Check consistency in argument mapping for three parameters.

The lambda expression correctly maps tuple.Arg1 through tuple.Arg4 to the worker delegate's parameters. Ensure that the ordering of arguments in MutableTuple<TOperand, T1, T2, T3> aligns with the expected parameters.


123-124: Verify argument alignment in MutableTuple with four parameters.

Confirm that tuple.Arg1 to tuple.Arg5 correctly map to TOperand and T1 through T4. This ensures that the worker delegate receives the correct arguments during execution.


153-154: Ensure all parameters are correctly passed in MutableTuple with five parameters.

With the addition of T5, verify that tuple.Arg1 to tuple.Arg6 correspond to TOperand and T1 through T5. Double-check that no off-by-one errors exist in parameter mapping.


158-159: Update type constraint to match new MutableTuple structure.

The type constraint in ForCore has been updated from Template<TOperand> to MutableTuple<TOperand>. Ensure this change does not affect method overload resolution or introduce any type incompatibilities.

You can run the following script to find any references to Template<TOperand> that may need updating:

src/Cuemon.Threading/AdvancedParallelFactory.ForAsync.cs (7)

Line range hint 22-28: Approved: Addition of ForAsync<TOperand> overload

The new overload of ForAsync<TOperand> is correctly implemented, allowing asynchronous execution of a parallel loop with custom loop control variables and a worker delegate. Input validation and method invocation are properly handled.


Line range hint 44-50: Approved: Addition of ForAsync<TOperand, T> overload

The added overload supports a worker delegate with one additional parameter arg. The implementation correctly validates inputs and invokes ForCoreAsync with the appropriate worker factory.


Line range hint 68-74: Approved: Addition of ForAsync<TOperand, T1, T2> overload

The ForAsync<TOperand, T1, T2> method extends functionality to worker delegates requiring two additional parameters. The code maintains consistency in input validation and method invocation.


Line range hint 92-98: Approved: Addition of ForAsync<TOperand, T1, T2, T3> overload

This overload correctly adds support for worker delegates with three extra parameters. The implementation follows the established pattern and handles inputs appropriately.


Line range hint 116-122: Approved: Addition of ForAsync<TOperand, T1, T2, T3, T4> overload

The new method supports worker delegates with four additional parameters. The implementation is consistent with other overloads and correctly manages validation and invocation.


Line range hint 140-146: Approved: Addition of ForAsync<TOperand, T1, T2, T3, T4, T5> overload

The addition of this overload allows worker delegates with five extra parameters. The code is correctly implemented and maintains consistency across overloads.


161-161: Verify replacement of Template<TOperand> with MutableTuple<TOperand>

The change in the generic constraint from Template<TOperand> to MutableTuple<TOperand> in ForCoreAsync aligns with the refactoring objectives stated in the PR. To ensure consistency, please verify that all references to Template<TOperand> have been updated throughout the codebase.

Run the following script to check for any remaining usages of Template<TOperand>:

src/Cuemon.Threading/ParallelFactory.ForEachResult.cs (6)

23-23: Update aligns with MutableTuple refactoring

The change on line 23 correctly replaces the Template class with the MutableTuple<TSource> class, aligning with the PR's objective to enhance flexibility and maintainability. The use of FuncFactory with the lambda expression accessing tuple.Arg1 is appropriate and maintains the intended functionality.


42-42: Consistent refactoring to MutableTuple<TSource, T>

Line 42 updates the factory initialization to use MutableTuple<TSource, T>. The lambda expression correctly accesses tuple.Arg1 and tuple.Arg2, corresponding to TSource and T, which matches the parameters of the worker delegate.


63-63: Correct implementation using MutableTuple<TSource, T1, T2>

The change on line 63 appropriately utilizes MutableTuple<TSource, T1, T2>. The lambda expression accesses tuple.Arg1, tuple.Arg2, and tuple.Arg3, aligning with the parameters TSource, T1, and T2 of the worker function.


86-86: Accurate usage of MutableTuple<TSource, T1, T2, T3>

Line 86 correctly transitions to using MutableTuple<TSource, T1, T2, T3>. The lambda expression now accesses tuple.Arg1 through tuple.Arg4, which correspond to TSource, T1, T2, and T3 respectively, maintaining consistency with the worker delegate's parameters.


111-111: Proper refactoring with MutableTuple<TSource, T1, T2, T3, T4>

The factory initialization on line 111 now uses MutableTuple<TSource, T1, T2, T3, T4>. The lambda expression accesses tuple.Arg1 to tuple.Arg5, matching the parameters of the worker function (TSource, T1, T2, T3, T4).


138-138: Verify the correctness of accessing tuple.Arg6

On line 138, the lambda expression accesses tuple.Arg1 through tuple.Arg6, corresponding to TSource, T1, T2, T3, T4, and T5. Ensure that the MutableTuple<TSource, T1, T2, T3, T4, T5> class provides an Arg6 property for T5.

Please confirm that MutableTuple supports the Arg6 property. If not, consider adjusting the implementation accordingly.

src/Cuemon.Threading/AdvancedParallelFactory.While.cs (6)

43-44: Apply the refactored ActionFactory helper method here

As previously suggested, applying the helper method for ActionFactory creation will reduce code duplication and enhance readability.


66-67: Apply the refactored ActionFactory helper method here

Continuing the refactoring will maintain consistency across the methods and simplify future maintenance.


91-92: Apply the refactored ActionFactory helper method here

Consistently using the helper method strengthens code cohesiveness and reduces the risk of errors in repetitive code blocks.


118-119: Apply the refactored ActionFactory helper method here

Refactoring here will further consolidate the pattern, promoting DRY (Don't Repeat Yourself) principles.


147-148: Apply the refactored ActionFactory helper method here

Completing the refactoring across all similar methods ensures uniformity and optimizes the codebase.


152-152: Verify the generic constraint on TWorker

The constraint where TWorker : MutableTuple<TElement> may not accurately reflect all possible MutableTuple types used in the WhileCore method, especially since MutableTuple can have multiple type parameters.

To ensure the constraint accommodates all MutableTuple variations, you can verify the generic arguments used:

Review the output to confirm that the TWorker types used align with the constraint or adjust the constraint accordingly.

src/Cuemon.Threading/AdvancedParallelFactory.WhileAsync.cs (1)

155-155: Ensure complete replacement of Template<TElement> with MutableTuple<TElement>

The change in the generic constraint from Template<TElement> to MutableTuple<TElement> in the WhileCoreAsync method indicates a refactoring effort to replace the Template class with MutableTuple. Please verify that all other references to Template<TElement> in the codebase have been updated accordingly to maintain consistency and prevent potential compilation errors.

Run the following script to check for any remaining references to Template<TElement>:

src/Cuemon.Threading/ParallelFactory.ForEachResultAsync.cs (1)

147-147: Verify the impact of adding the generic constraint

The added generic constraint where TWorker : MutableTuple<TSource> to ForEachResultCoreAsync changes the method's contract. This could potentially introduce breaking changes if there are existing implementations where TWorker does not inherit from MutableTuple<TSource>. Please verify that all usages of this method are compatible with this new constraint.

You can run the following script to identify any usages that might be affected:

This script uses rg (ripgrep) to search for all occurrences of ForEachResultCoreAsync and extracts the TWorker type being used. Review the extracted types to ensure they all satisfy the new constraint.

src/Cuemon.Threading/AdvancedParallelFactory.ForResult.cs (2)

54-54: Verify Initialization of MutableTuple<TOperand, T>

In the creation of the factory:

var factory = new FuncFactory<MutableTuple<TOperand, T>, TResult>(tuple => worker(tuple.Arg1, tuple.Arg2), new MutableTuple<TOperand, T>(default, arg), worker);

Ensure that initializing Arg1 with default and Arg2 with arg correctly represents the initial state required for the worker delegate. If default for TOperand isn't appropriate, it might lead to unexpected results.

Double-check if default is the intended initial value for TOperand in this context. Adjust the initialization if necessary.


81-81: ⚠️ Potential issue

Address Potential Issues with Generic Constraints

In the line:

var factory = new FuncFactory<MutableTuple<TOperand, T1, T2>, TResult>(tuple => worker(tuple.Arg1, tuple.Arg2, tuple.Arg3), new MutableTuple<TOperand, T1, T2>(default, arg1, arg2), worker);

The MutableTuple is being initialized with default for Arg1. Verify that this does not cause issues during execution. Additionally, ensure that the Arg properties align correctly with the parameters expected by worker.

Consider reviewing the mapping between Arg properties and worker parameters to prevent any misalignment.

src/Cuemon.Threading/AdvancedParallelFactory.ForResultAsync.cs (1)

177-177: Update of generic constraint aligns with refactoring goals.

Replacing Template<TOperand> with MutableTuple<TOperand> in the generic constraint is consistent with the PR objective of replacing the Template class. This change ensures compatibility with the new MutableTuple structure throughout the method.

src/Cuemon.Threading/AdvancedParallelFactory.WhileResult.cs (6)

25-26: Use of MutableTuple<TElement> aligns with refactoring goals

The replacement of Template with MutableTuple<TElement> in the factory instantiation enhances flexibility and maintains consistency with the refactoring objectives.


48-49: Consistent refactoring with MutableTuple<TElement, T>

The implementation using MutableTuple<TElement, T> correctly wraps the worker delegate's parameters, maintaining the intended functionality.


73-74: Correct implementation with MutableTuple<TElement, T1, T2>

The use of MutableTuple for wrapping multiple arguments is appropriate and aligns with the refactoring strategy.


100-101: Effective use of MutableTuple<TElement, T1, T2, T3>

The changes correctly handle three additional arguments, ensuring consistency across the methods and maintaining the intended functionality.


129-130: Proper implementation with MutableTuple<TElement, T1, T2, T3, T4>

The code accurately encapsulates the parameters using MutableTuple, aligning with the design goals of the refactoring.


160-161: Refactoring handles five arguments with MutableTuple<TElement, T1, T2, T3, T4, T5>

The use of MutableTuple effectively manages multiple parameters for the worker delegate, maintaining consistency and flexibility.

src/Cuemon.IO/StreamFactory.cs (15)

24-24: Code change is correct and acceptable.

The use of MutableTuple<StreamWriter> in the factory instantiation aligns with the refactoring objectives and correctly replaces the Template class.


38-38: Code change is correct and acceptable.

The MutableTuple<StreamWriter, T> is properly utilized, and the arguments are correctly passed to the writer delegate.


54-54: Code change is correct and acceptable.

The factory correctly handles two generic arguments using MutableTuple<StreamWriter, T1, T2>, ensuring proper invocation of the writer delegate.


72-72: Code change is correct and acceptable.

The refactored code appropriately uses MutableTuple<StreamWriter, T1, T2, T3>, maintaining consistency across the method overloads.


92-92: Code change is correct and acceptable.

The MutableTuple with four generic arguments is correctly applied in the factory, ensuring accurate parameter passing to the writer delegate.


114-114: Verify correctness of argument mapping in the delegate invocation.

Please ensure that tuple.Arg6 corresponds correctly to T5 when invoking the writer delegate. Since MutableTuple<StreamWriter, T1, T2, T3, T4, T5> provides Arg1 through Arg6, mapping to StreamWriter and T1 through T5.


128-128: Code change is correct and acceptable.

The use of MutableTuple<IBufferWriter<byte>> aligns with the updated factory pattern and replaces the Template class appropriately.


142-142: Code change is correct and acceptable.

The factory and tuple are correctly configured for the generic parameter T, ensuring proper operation of the writer delegate.


158-158: Code change is correct and acceptable.

The pattern with two generic parameters is correctly applied using MutableTuple<IBufferWriter<byte>, T1, T2>, maintaining consistency with the refactoring goals.


176-176: Code change is correct and acceptable.

The factory instantiation correctly handles three generic parameters with MutableTuple<IBufferWriter<byte>, T1, T2, T3>, ensuring accurate argument mapping.


196-196: Code change is correct and acceptable.

The use of MutableTuple with four generic parameters is appropriate here, aligning with the overall refactoring of the StreamFactory class.


218-218: Verify correctness of argument mapping in the delegate invocation.

Please verify that tuple.Arg6 correctly corresponds to T5 in the invocation of the writer delegate, ensuring consistent mapping of arguments in MutableTuple<IBufferWriter<byte>, T1, T2, T3, T4, T5>.


Line range hint 222-230: Refactoring aligns with updated type constraints.

The change from Template<IBufferWriter<byte>> to MutableTuple<IBufferWriter<byte>> in the type constraint is appropriate, reflecting the replacement of the Template class and maintaining type safety.


Line range hint 236-246: Refactoring aligns with updated type constraints.

The update from Template<StreamWriter> to MutableTuple<StreamWriter> in the type constraint is consistent with the refactoring goals and ensures compatibility with the new MutableTuple class.


Line range hint 248-265: Refactoring maintains functionality with updated generic constraints.

The method CreateStreamCore<TTuple, TWriter> now uses MutableTuple<TWriter> in its type constraint, which aligns with the refactoring and ensures that the method continues to function correctly with the updated types.

src/Cuemon.Core/Patterns.cs (5)

217-218: Refactored SafeInvoke method uses MutableTuple correctly

The replacement of Template with MutableTuple in the SafeInvoke method enhances flexibility and aligns with the refactoring objectives. The initialization of f1 and f2 is correctly implemented.


236-237: Correct application of MutableTuple in SafeInvoke with single generic parameter

The changes accurately apply MutableTuple<TResult, T> to handle the additional argument in SafeInvoke<T, TResult>. This aligns with the goal of replacing Template with MutableTuple.


257-258: Proper refactoring in SafeInvoke with two generic parameters

The use of MutableTuple<TResult, T1, T2> correctly accommodates multiple arguments in the SafeInvoke<T1, T2, TResult> method. The implementation maintains consistency and ensures proper parameter handling.


280-281: Consistent use of MutableTuple in SafeInvoke with three generic parameters

The refactored code appropriately uses MutableTuple<TResult, T1, T2, T3> for handling three arguments. The delegate implementations for f1 and f2 correctly map the tuple arguments to the tester and catcher delegates.


305-306: Accurate implementation of MutableTuple in SafeInvoke with four generic parameters

The introduction of MutableTuple<TResult, T1, T2, T3, T4> effectively manages four arguments in the SafeInvoke<T1, T2, T3, T4, TResult> method. The changes are consistent with the overall refactoring strategy.

src/Cuemon.IO/Extensions/StreamDecoratorExtensions.cs (1)

514-514: Proper cancellation token usage

Great job ensuring the cancellation token options.CancellationToken is correctly passed to AsyncPatterns.SafeInvokeAsync. This improves the method's ability to handle cancellation requests effectively.

src/Cuemon.Resilience/TransientOperation.cs (14)

33-33: Correct implementation of MutableTuple in WithFunc<TResult>

The replacement of Template with MutableTuple in the FuncFactory initialization aligns with the refactoring goals and is correctly applied.


62-62: Accurate update to WithFunc<T, TResult> using MutableTuple<T>

The use of MutableTuple<T> in the FuncFactory correctly reflects the intended changes and ensures proper handling of the argument arg.


93-93: Proper modification of WithFunc<T1, T2, TResult> with MutableTuple<T1, T2>

The updated factory initialization correctly passes arguments using MutableTuple<T1, T2>, maintaining the method's functionality.


126-126: Correct update in WithFunc<T1, T2, T3, TResult> to use MutableTuple<T1, T2, T3>

The implementation accurately replaces Template with MutableTuple<T1, T2, T3>, ensuring that all three arguments are properly managed.


161-161: Appropriate adaptation in WithFunc<T1, T2, T3, T4, TResult>

The use of MutableTuple<T1, T2, T3, T4> correctly aligns with the refactoring efforts and handles all four arguments effectively.


198-198: Successful update of WithFunc<T1, T2, T3, T4, T5, TResult>

The change to MutableTuple<T1, T2, T3, T4, T5> ensures that all five arguments are properly encapsulated, matching the intended design.


223-223: Updated WithAction method to utilize MutableTuple

The modification replaces Template with MutableTuple in the ActionFactory, correctly aligning with the redesign.


250-250: Accurate change in WithAction<T> using MutableTuple<T>

The implementation correctly passes the argument arg through MutableTuple<T>, reflecting the refactoring objectives.


279-279: Proper update to WithAction<T1, T2> with MutableTuple<T1, T2>

The replacement ensures both arguments are managed via MutableTuple<T1, T2>, maintaining method integrity.


310-310: Correct modification in WithAction<T1, T2, T3>

The use of MutableTuple<T1, T2, T3> accurately manages all three arguments, aligning with the new structure.


343-343: Successful adaptation of WithAction<T1, T2, T3, T4>

Implementing MutableTuple<T1, T2, T3, T4> correctly handles the method's four arguments as per the refactoring plan.


378-378: Accurate update in WithAction<T1, T2, T3, T4, T5>

The change to MutableTuple<T1, T2, T3, T4, T5> ensures all five arguments are correctly processed, aligning with the refactor.


388-388: Appropriate constraint change in WithActionCore<TTuple> method

Updating the generic constraint to where TTuple : MutableTuple correctly reflects the replacement of Template and maintains type safety.


393-393: Correctly updated WithFuncCore<TTuple, TResult> method constraint

The modification to use MutableTuple in the generic constraint ensures consistency and proper functionality with the new tuple class.

src/Cuemon.Diagnostics/TimeMeasure.cs (3)

27-27: Update to ActionFactory<MutableTuple> is appropriate

The change from Template to MutableTuple in the WithAction method correctly aligns with the refactoring objectives and enhances flexibility.


42-42: Correct use of MutableTuple<T> in WithAction<T>

The implementation correctly uses MutableTuple<T> to handle the action with one argument.


Line range hint 59-531: Consistent refactoring to MutableTuple across overloaded methods

The updates from Template to MutableTuple in all overloaded WithAction and WithFunc methods are consistent and properly implemented.

src/Cuemon.Diagnostics/TimeMeasure.Async.cs (2)

Line range hint 563-570: Refactored WithActionAsyncCore to use MutableTuple – Looks Good

The change from Template to MutableTuple in the type constraint enhances the method's flexibility and aligns with the refactoring objectives detailed in the PR.


Line range hint 576-583: Refactored WithFunctionAsyncCore to use MutableTuple – Looks Good

Updating the type constraint from Template to MutableTuple in WithFunctionAsyncCore is consistent with the overall refactoring efforts, improving code maintainability and adaptability.

src/Cuemon.Extensions.Core/TesterFuncFactory.cs (1)

450-454: The Invoke method implementation looks good

The Invoke method correctly creates a new TesterFuncFactory instance and invokes ExecuteMethod, ensuring that the provided tuple and method are correctly utilized.

src/Cuemon.Extensions.Runtime.Caching/CacheEnumerableExtensions.cs (6)

340-341: Potential Redundancy in FuncFactory Initialization

This is similar to the issue noted in lines 260-261. The valueFactory is passed both as a lambda and as a parameter:

var factory = new FuncFactory<MutableTuple<T>, TResult>(tuple => valueFactory(tuple.Arg1), new MutableTuple<T>(arg), valueFactory);

425-426: Potential Redundancy in FuncFactory Initialization

As previously mentioned, the valueFactory is passed twice:

var factory = new FuncFactory<MutableTuple<T1, T2>, TResult>(tuple => valueFactory(tuple.Arg1, tuple.Arg2), new MutableTuple<T1, T2>(arg1, arg2), valueFactory);

515-516: Potential Redundancy in FuncFactory Initialization

Again, the valueFactory is being passed both as a lambda and as a parameter:

var factory = new FuncFactory<MutableTuple<T1, T2, T3>, TResult>(tuple => valueFactory(tuple.Arg1, tuple.Arg2, tuple.Arg3), new MutableTuple<T1, T2, T3>(arg1, arg2, arg3), valueFactory);

610-611: Potential Redundancy in FuncFactory Initialization

Consistent with earlier observations, valueFactory appears twice:

var factory = new FuncFactory<MutableTuple<T1, T2, T3, T4>, TResult>(tuple => valueFactory(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4), new MutableTuple<T1, T2, T3, T4>(arg1, arg2, arg3, arg4), valueFactory);

710-711: Potential Redundancy in FuncFactory Initialization

The pattern continues with valueFactory being passed twice:

var factory = new FuncFactory<MutableTuple<T1, T2, T3, T4, T5>, TResult>(tuple => valueFactory(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, tuple.Arg5), new MutableTuple<T1, T2, T3, T4, T5>(arg1, arg2, arg3, arg4, arg5), valueFactory);

717-717: Use of Generic Constraint where TTuple : MutableTuple

The method signature introduces a generic constraint:

private static TResult Memoize<TKey, TTuple, TResult>(ICacheEnumerable<TKey> cache, string key, CacheInvalidation invalidation, FuncFactory<TTuple, TResult> valueFactory) where TTuple : MutableTuple

This constraint ensures that TTuple inherits from MutableTuple, which appears appropriate given its usage within the method. The implementation aligns with the intended design.

src/Cuemon.Core/MutableTuple.cs (1)

38-41: Confirm the intended behavior of the IsEmpty property

The base MutableTuple class has an IsEmpty property that returns true, while in derived classes it is overridden to return false. Ensure this distinction aligns with the intended design and that it is clearly documented for consumers of the class.

Verify that the use of the IsEmpty property is consistent and understood throughout the codebase to prevent any confusion or misuse.

src/Cuemon.Threading/AsyncPatterns.cs (1)

160-161: Type constraint update from Template to MutableTuple is appropriate

Changing the type constraints from Template<TResult> to MutableTuple<TResult> aligns with the refactoring objectives and enhances flexibility.

Comment on lines 92 to 106
private static List<MutableTuple<Func<SmtpClient>, List<MailMessage>>> PrepareShipment(MailDistributor distributor, IEnumerable<MailMessage> mails, Func<MailMessage, bool> filter)
{
var partitionedMails = new PartitionerEnumerable<MailMessage>(mails, distributor.DeliverySize);
var carriers = new List<Template<Func<SmtpClient>, List<MailMessage>>>();
var carriers = new List<MutableTuple<Func<SmtpClient>, List<MailMessage>>>();
while (partitionedMails.HasPartitions)
{
carriers.Add(Template.CreateTwo(distributor.Carrier, new List<MailMessage>(filter == null
carriers.Add(new MutableTuple<Func<SmtpClient>, List<MailMessage>>(distributor.Carrier, new List<MailMessage>(filter == null
? partitionedMails
: partitionedMails.Where(filter)
)));
}
return carriers;
}
}
}
}
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Issue Detected: Remaining Template Usage

There is an existing reference to Template in HtmlHelperExtensions.cs. Ensure all instances are replaced with MutableTuple to maintain consistency and prevent potential issues.

🔗 Analysis chain

LGTM! Verify impact on dependent code.

The changes in the PrepareShipment method align with the PR objectives of replacing Template with MutableTuple. The logic remains intact, and the new implementation should provide more flexibility.

To ensure these changes don't introduce unintended side effects, please run the following script to check for any remaining usages of Template in the codebase and verify that all dependent code has been updated accordingly:

This script will help identify any areas that might need further attention due to the Template to MutableTuple transition.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for remaining usages of Template and verify updates in dependent code

# Test 1: Search for any remaining usages of Template
echo "Searching for remaining usages of Template:"
rg --type csharp 'Template[<\s]'

# Test 2: Search for usages of PrepareShipment method
echo "Searching for usages of PrepareShipment method:"
rg --type csharp 'PrepareShipment\s*\('

# Test 3: Search for other occurrences of MutableTuple in the codebase
echo "Searching for other occurrences of MutableTuple:"
rg --type csharp 'MutableTuple[<\s]'

Length of output: 106378

Comment on lines +13 to +409
o => Assert.Equal(o, 4),
o => Assert.Equal(o, 5),
o => Assert.Equal(o, 6),
o => Assert.Equal(o, 7),
o => Assert.Equal(o, 8),
o => Assert.Equal(o, 9),
o => Assert.Equal(o, 10),
o => Assert.Equal(o, 11),
o => Assert.Equal(o, 12),
o => Assert.Equal(o, 13),
o => Assert.Equal(o, 14),
o => Assert.Equal(o, 15),
o => Assert.Equal(o, 16),
o => Assert.Equal(o, 17));
TestOutput.WriteLine(sut.ToString());
}

[Fact]
public void CreateZero_ShouldCreateOctodecuple()
{
var sut = new MutableTuple<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18);
Assert.False(sut.IsEmpty);
Assert.Collection(sut.ToArray(),
o => Assert.Equal(o, 1),
o => Assert.Equal(o, 2),
o => Assert.Equal(o, 3),
o => Assert.Equal(o, 4),
o => Assert.Equal(o, 5),
o => Assert.Equal(o, 6),
o => Assert.Equal(o, 7),
o => Assert.Equal(o, 8),
o => Assert.Equal(o, 9),
o => Assert.Equal(o, 10),
o => Assert.Equal(o, 11),
o => Assert.Equal(o, 12),
o => Assert.Equal(o, 13),
o => Assert.Equal(o, 14),
o => Assert.Equal(o, 15),
o => Assert.Equal(o, 16),
o => Assert.Equal(o, 17),
o => Assert.Equal(o, 18));
TestOutput.WriteLine(sut.ToString());
}

[Fact]
public void CreateZero_ShouldCreateNovemdecuple()
{
var sut = new MutableTuple<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19);
Assert.False(sut.IsEmpty);
Assert.Collection(sut.ToArray(),
o => Assert.Equal(o, 1),
o => Assert.Equal(o, 2),
o => Assert.Equal(o, 3),
o => Assert.Equal(o, 4),
o => Assert.Equal(o, 5),
o => Assert.Equal(o, 6),
o => Assert.Equal(o, 7),
o => Assert.Equal(o, 8),
o => Assert.Equal(o, 9),
o => Assert.Equal(o, 10),
o => Assert.Equal(o, 11),
o => Assert.Equal(o, 12),
o => Assert.Equal(o, 13),
o => Assert.Equal(o, 14),
o => Assert.Equal(o, 15),
o => Assert.Equal(o, 16),
o => Assert.Equal(o, 17),
o => Assert.Equal(o, 18),
o => Assert.Equal(o, 19));
TestOutput.WriteLine(sut.ToString());
}

[Fact]
public void CreateZero_ShouldCreateViguple()
{
var sut = new MutableTuple<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);
Assert.False(sut.IsEmpty);
Assert.Collection(sut.ToArray(),
o => Assert.Equal(o, 1),
o => Assert.Equal(o, 2),
o => Assert.Equal(o, 3),
o => Assert.Equal(o, 4),
o => Assert.Equal(o, 5),
o => Assert.Equal(o, 6),
o => Assert.Equal(o, 7),
o => Assert.Equal(o, 8),
o => Assert.Equal(o, 9),
o => Assert.Equal(o, 10),
o => Assert.Equal(o, 11),
o => Assert.Equal(o, 12),
o => Assert.Equal(o, 13),
o => Assert.Equal(o, 14),
o => Assert.Equal(o, 15),
o => Assert.Equal(o, 16),
o => Assert.Equal(o, 17),
o => Assert.Equal(o, 18),
o => Assert.Equal(o, 19),
o => Assert.Equal(o, 20));
TestOutput.WriteLine(sut.ToString());
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider refactoring tests for improved maintainability and coverage

While the current tests are comprehensive in covering different tuple sizes, there are several areas for potential improvement:

  1. Reduce repetition: Consider using a parameterized test to cover multiple tuple sizes with a single test method.
  2. Add edge cases: Test with non-sequential integers, negative numbers, or even non-integer types if supported.
  3. Test additional behaviors: If MutableTuple has other methods or properties, consider adding tests for those as well.

Here's an example of how you could refactor using a parameterized test:

[Theory]
[InlineData(new int[] {})]
[InlineData(new int[] {1})]
[InlineData(new int[] {1, 2})]
// ... add more cases as needed
public void CreateTuple_ShouldCreateCorrectTuple(int[] elements)
{
    var sut = MutableTuple.Create(elements);
    Assert.Equal(elements.Length == 0, sut.IsEmpty);
    Assert.Equal(elements, sut.ToArray());
    TestOutput.WriteLine(sut.ToString());
}

This approach would significantly reduce code duplication and make it easier to add new test cases in the future.

@@ -29,7 +29,7 @@ protected sealed override void FillWorkQueue<TWorker>(TemplateFactory<TWorker> w
{
try
{
FillWorkQueueWorkerFactory(swf as TemplateFactory<TWorker>, current);
FillWorkQueueWorkerFactory(swf as MutableTupleFactory<TWorker>, current);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use direct casting to prevent null reference issues

In line 32, the 'as' operator is used to cast swf to MutableTupleFactory<TWorker>:

FillWorkQueueWorkerFactory(swf as MutableTupleFactory<TWorker>, current);

Using 'as' may result in a null value if the cast fails, leading to a potential NullReferenceException. Since swf is expected to be of type MutableTupleFactory<TWorker>, consider using a direct cast to ensure type safety:

-FillWorkQueueWorkerFactory(swf as MutableTupleFactory<TWorker>, current);
+FillWorkQueueWorkerFactory((MutableTupleFactory<TWorker>)swf, current);

This change will throw an InvalidCastException if the cast fails, making it easier to detect and debug type mismatches.

@@ -31,7 +31,7 @@ protected sealed override void FillWorkQueue<TWorker>(TemplateFactory<TWorker> w
{
try
{
FillWorkQueueWorkerFactory(swf as TemplateFactory<TWorker>);
FillWorkQueueWorkerFactory(swf as MutableTupleFactory<TWorker>);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use direct casting instead of 'as' operator for clarity and safety

In FillWorkQueueWorkerFactory(swf as MutableTupleFactory<TWorker>);, consider using a direct cast since swf is expected to be of type MutableTupleFactory<TWorker>. The as operator can return null if the cast fails, potentially leading to a NullReferenceException. A direct cast will throw an InvalidCastException immediately if the cast is invalid, helping to identify issues earlier.

Apply this diff to use a direct cast:

-FillWorkQueueWorkerFactory(swf as MutableTupleFactory<TWorker>);
+FillWorkQueueWorkerFactory((MutableTupleFactory<TWorker>)swf);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
FillWorkQueueWorkerFactory(swf as MutableTupleFactory<TWorker>);
FillWorkQueueWorkerFactory((MutableTupleFactory<TWorker>)swf);

/// </summary>
public static class ActionFactory
/// <typeparam name="TTuple">The type of the n-tuple representation of a <see cref="MutableTuple"/>.</typeparam>
public sealed class ActionFactory<TTuple> : MutableTupleFactory<TTuple> where TTuple : MutableTuple
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider whether sealing the class is necessary

The ActionFactory<TTuple> class is now sealed. If there is no specific reason to prevent inheritance, you might consider leaving the class unsealed to allow for extensibility.

Comment on lines +29 to +31
public static AsyncActionFactory<MutableTuple<T>> Create<T>(Func<T, CancellationToken, Task> method, T arg)
{
return new AsyncActionFactory<Template<T>>((tuple, token) => method(tuple.Arg1, token), Template.CreateOne(arg), method);
return new AsyncActionFactory<MutableTuple<T>>((tuple, token) => method(tuple.Arg1, token), new MutableTuple<T>(arg), method);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add null check for 'method' parameter to ensure robustness

Similarly, the method parameter in this overload is not checked for null. Adding a null check will prevent potential exceptions.

Apply this diff:

 public static AsyncActionFactory<MutableTuple<T>> Create<T>(Func<T, CancellationToken, Task> method, T arg)
 {
+    if (method == null) throw new ArgumentNullException(nameof(method));
     return new AsyncActionFactory<MutableTuple<T>>((tuple, token) => method(tuple.Arg1, token), new MutableTuple<T>(arg), method);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public static AsyncActionFactory<MutableTuple<T>> Create<T>(Func<T, CancellationToken, Task> method, T arg)
{
return new AsyncActionFactory<Template<T>>((tuple, token) => method(tuple.Arg1, token), Template.CreateOne(arg), method);
return new AsyncActionFactory<MutableTuple<T>>((tuple, token) => method(tuple.Arg1, token), new MutableTuple<T>(arg), method);
public static AsyncActionFactory<MutableTuple<T>> Create<T>(Func<T, CancellationToken, Task> method, T arg)
{
if (method == null) throw new ArgumentNullException(nameof(method));
return new AsyncActionFactory<MutableTuple<T>>((tuple, token) => method(tuple.Arg1, token), new MutableTuple<T>(arg), method);
}

Comment on lines +59 to +61
public static AsyncActionFactory<MutableTuple<T1, T2, T3>> Create<T1, T2, T3>(Func<T1, T2, T3, CancellationToken, Task> method, T1 arg1, T2 arg2, T3 arg3)
{
return new AsyncActionFactory<Template<T1, T2, T3>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, token), Template.CreateThree(arg1, arg2, arg3), method);
return new AsyncActionFactory<MutableTuple<T1, T2, T3>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, token), new MutableTuple<T1, T2, T3>(arg1, arg2, arg3), method);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add null check for 'method' parameter to ensure robustness

As with previous overloads, add a null check for the method parameter.

Apply this diff:

 public static AsyncActionFactory<MutableTuple<T1, T2, T3>> Create<T1, T2, T3>(Func<T1, T2, T3, CancellationToken, Task> method, T1 arg1, T2 arg2, T3 arg3)
 {
+    if (method == null) throw new ArgumentNullException(nameof(method));
     return new AsyncActionFactory<MutableTuple<T1, T2, T3>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, token), new MutableTuple<T1, T2, T3>(arg1, arg2, arg3), method);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public static AsyncActionFactory<MutableTuple<T1, T2, T3>> Create<T1, T2, T3>(Func<T1, T2, T3, CancellationToken, Task> method, T1 arg1, T2 arg2, T3 arg3)
{
return new AsyncActionFactory<Template<T1, T2, T3>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, token), Template.CreateThree(arg1, arg2, arg3), method);
return new AsyncActionFactory<MutableTuple<T1, T2, T3>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, token), new MutableTuple<T1, T2, T3>(arg1, arg2, arg3), method);
public static AsyncActionFactory<MutableTuple<T1, T2, T3>> Create<T1, T2, T3>(Func<T1, T2, T3, CancellationToken, Task> method, T1 arg1, T2 arg2, T3 arg3)
{
if (method == null) throw new ArgumentNullException(nameof(method));
return new AsyncActionFactory<MutableTuple<T1, T2, T3>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, token), new MutableTuple<T1, T2, T3>(arg1, arg2, arg3), method);
}

Comment on lines +97 to +99
public static AsyncActionFactory<MutableTuple<T1, T2, T3, T4, T5>> Create<T1, T2, T3, T4, T5>(Func<T1, T2, T3, T4, T5, CancellationToken, Task> method, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
{
return new AsyncActionFactory<Template<T1, T2, T3, T4, T5>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, tuple.Arg5, token), Template.CreateFive(arg1, arg2, arg3, arg4, arg5), method);
return new AsyncActionFactory<MutableTuple<T1, T2, T3, T4, T5>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, tuple.Arg5, token), new MutableTuple<T1, T2, T3, T4, T5>(arg1, arg2, arg3, arg4, arg5), method);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add null check for 'method' parameter to ensure robustness

Include a null check for the method parameter.

Apply this diff:

 public static AsyncActionFactory<MutableTuple<T1, T2, T3, T4, T5>> Create<T1, T2, T3, T4, T5>(Func<T1, T2, T3, T4, T5, CancellationToken, Task> method, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
 {
+    if (method == null) throw new ArgumentNullException(nameof(method));
     return new AsyncActionFactory<MutableTuple<T1, T2, T3, T4, T5>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, tuple.Arg5, token), new MutableTuple<T1, T2, T3, T4, T5>(arg1, arg2, arg3, arg4, arg5), method);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public static AsyncActionFactory<MutableTuple<T1, T2, T3, T4, T5>> Create<T1, T2, T3, T4, T5>(Func<T1, T2, T3, T4, T5, CancellationToken, Task> method, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
{
return new AsyncActionFactory<Template<T1, T2, T3, T4, T5>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, tuple.Arg5, token), Template.CreateFive(arg1, arg2, arg3, arg4, arg5), method);
return new AsyncActionFactory<MutableTuple<T1, T2, T3, T4, T5>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, tuple.Arg5, token), new MutableTuple<T1, T2, T3, T4, T5>(arg1, arg2, arg3, arg4, arg5), method);
public static AsyncActionFactory<MutableTuple<T1, T2, T3, T4, T5>> Create<T1, T2, T3, T4, T5>(Func<T1, T2, T3, T4, T5, CancellationToken, Task> method, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
{
if (method == null) throw new ArgumentNullException(nameof(method));
return new AsyncActionFactory<MutableTuple<T1, T2, T3, T4, T5>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, tuple.Arg5, token), new MutableTuple<T1, T2, T3, T4, T5>(arg1, arg2, arg3, arg4, arg5), method);
}

Comment on lines +77 to +79
public static AsyncActionFactory<MutableTuple<T1, T2, T3, T4>> Create<T1, T2, T3, T4>(Func<T1, T2, T3, T4, CancellationToken, Task> method, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
{
return new AsyncActionFactory<Template<T1, T2, T3, T4>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, token), Template.CreateFour(arg1, arg2, arg3, arg4), method);
return new AsyncActionFactory<MutableTuple<T1, T2, T3, T4>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, token), new MutableTuple<T1, T2, T3, T4>(arg1, arg2, arg3, arg4), method);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add null check for 'method' parameter to ensure robustness

Add a null check for the method parameter in this overload.

Apply this diff:

 public static AsyncActionFactory<MutableTuple<T1, T2, T3, T4>> Create<T1, T2, T3, T4>(Func<T1, T2, T3, T4, CancellationToken, Task> method, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
 {
+    if (method == null) throw new ArgumentNullException(nameof(method));
     return new AsyncActionFactory<MutableTuple<T1, T2, T3, T4>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, token), new MutableTuple<T1, T2, T3, T4>(arg1, arg2, arg3, arg4), method);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public static AsyncActionFactory<MutableTuple<T1, T2, T3, T4>> Create<T1, T2, T3, T4>(Func<T1, T2, T3, T4, CancellationToken, Task> method, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
{
return new AsyncActionFactory<Template<T1, T2, T3, T4>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, token), Template.CreateFour(arg1, arg2, arg3, arg4), method);
return new AsyncActionFactory<MutableTuple<T1, T2, T3, T4>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, token), new MutableTuple<T1, T2, T3, T4>(arg1, arg2, arg3, arg4), method);
public static AsyncActionFactory<MutableTuple<T1, T2, T3, T4>> Create<T1, T2, T3, T4>(Func<T1, T2, T3, T4, CancellationToken, Task> method, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
{
if (method == null) throw new ArgumentNullException(nameof(method));
return new AsyncActionFactory<MutableTuple<T1, T2, T3, T4>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, tuple.Arg3, tuple.Arg4, token), new MutableTuple<T1, T2, T3, T4>(arg1, arg2, arg3, arg4), method);
}

Comment on lines +43 to +45
public static AsyncActionFactory<MutableTuple<T1, T2>> Create<T1, T2>(Func<T1, T2, CancellationToken, Task> method, T1 arg1, T2 arg2)
{
return new AsyncActionFactory<Template<T1, T2>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, token), Template.CreateTwo(arg1, arg2), method);
return new AsyncActionFactory<MutableTuple<T1, T2>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, token), new MutableTuple<T1, T2>(arg1, arg2), method);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add null check for 'method' parameter to ensure robustness

Continue to add a null check for the method parameter in this overload.

Apply this diff:

 public static AsyncActionFactory<MutableTuple<T1, T2>> Create<T1, T2>(Func<T1, T2, CancellationToken, Task> method, T1 arg1, T2 arg2)
 {
+    if (method == null) throw new ArgumentNullException(nameof(method));
     return new AsyncActionFactory<MutableTuple<T1, T2>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, token), new MutableTuple<T1, T2>(arg1, arg2), method);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public static AsyncActionFactory<MutableTuple<T1, T2>> Create<T1, T2>(Func<T1, T2, CancellationToken, Task> method, T1 arg1, T2 arg2)
{
return new AsyncActionFactory<Template<T1, T2>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, token), Template.CreateTwo(arg1, arg2), method);
return new AsyncActionFactory<MutableTuple<T1, T2>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, token), new MutableTuple<T1, T2>(arg1, arg2), method);
public static AsyncActionFactory<MutableTuple<T1, T2>> Create<T1, T2>(Func<T1, T2, CancellationToken, Task> method, T1 arg1, T2 arg2)
{
if (method == null) throw new ArgumentNullException(nameof(method));
return new AsyncActionFactory<MutableTuple<T1, T2>>((tuple, token) => method(tuple.Arg1, tuple.Arg2, token), new MutableTuple<T1, T2>(arg1, arg2), method);
}

@gimlichael gimlichael merged commit 82a29f6 into main Oct 16, 2024
171 of 173 checks passed
@gimlichael gimlichael deleted the v9.0.0/delegate-additions-relocation branch October 16, 2024 06:54
This was referenced Nov 11, 2024
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.

1 participant