ikyriak / IdempotentAPI

A .NET library that handles the HTTP write operations (POST and PATCH) that can affect only once for the given request data and idempotency-key by using an ASP.NET Core attribute (filter).
MIT License
279 stars 40 forks source link

Self referencing loop detected #81

Closed csimonsson closed 2 months ago

csimonsson commented 2 months ago

Hi,

I'm having issues when using minimal API and dependency injection for my DbContext, where my DbContext is serialized with an exception:

Self referencing loop detected
at IdempotentAPI.Core.Idempotency.PrepareMinimalApiIdempotencyAsync

How do I avoid that some of my arguments (DI) to the API functions are treated as arguments when they should not be included in the hash?

Example:

    private static async Task<Results<Created<CustomerDTO>> CreateCustomer(
        [FromServices] DbContext context,
        [FromBody] CreateCustomerRequest request
        )
    {
        ...
    }

The issue seems to be similar to #67

ikyriak commented 2 months ago

Hello @csimonsson,

Thank you for reporting this issue. I have prepared a backward-compatible solution to define the special types to be excluded from serialization in the IIdempotencyOptionsProvider. For example:

NuGet Packages:

Program.cs

// ...
builder.Services.AddIdempotentMinimalAPI(new IdempotencyOptionsProvider());
// ...

IdempotencyOptionsProvider.cs

using IdempotentAPI.Core;
using IdempotentAPI.MinimalAPI;
using IdempotentAPI.TestWebMinimalAPIs.ApiContext;
using Microsoft.EntityFrameworkCore;

namespace IdempotentAPI.TestWebMinimalAPIs
{
    public class IdempotencyOptionsProvider : IIdempotencyOptionsProvider
    {
        private readonly List<Type> ExcludeRequestSpecialTypes = new()
        {
            typeof(DbContext),
            typeof(ApiDbContext),
        };

        public IIdempotencyOptions GetIdempotencyOptions(IHttpContextAccessor httpContextAccessor)
        {
            // WARNING: This example implementation shows we can provide different IdempotencyOptions per case.
            //switch (httpContextAccessor?.HttpContext?.Request.Path)
            //{
            //    case "/v6/TestingIdempotentAPI/test":
            //        return new IdempotencyOptions()
            //        {
            //            ExpireHours = 1,
            //            ExcludeRequestSpecialTypes = ExcludeRequestSpecialTypes,
            //        };
            //}

            return new IdempotencyOptions()
            {
                ExcludeRequestSpecialTypes = ExcludeRequestSpecialTypes,
            };
        }
    }
}
csimonsson commented 2 months ago

Thanks, I will try it out!

csimonsson commented 2 months ago

Got it working with some minor changes #82 , thanks again!