Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 30, 2025

When using EFCoreAdapter with dependency injection (e.g., casbin-aspnetcore), the adapter stores a direct reference to a scoped DbContext. When the scope ends, the DbContext is disposed but the long-lived Enforcer continues using the adapter, causing ObjectDisposedException on subsequent policy operations.

Changes

Added IServiceProvider-based constructor

  • Adapter resolves DbContext on-demand per operation instead of storing a reference
  • All database methods call GetOrResolveDbContext() to obtain fresh instances
  • Existing DbContext constructor unchanged for backward compatibility

Added DI registration extension methods

  • AddEFCoreAdapter<TKey>() and AddEFCoreAdapter<TKey, TPersistPolicy>()
  • Simplifies registration and ensures correct service provider injection

Added tests

  • Verifies ObjectDisposedException with DbContext constructor after scope disposal
  • Verifies successful operation across scopes with IServiceProvider constructor

Usage

// Register the adapter with extension method
services.AddDbContext<CasbinDbContext<int>>(options => 
    options.UseSqlServer(connectionString));
services.AddEFCoreAdapter<int>();

// Or use directly in casbin-aspnetcore
options.DefaultEnforcerFactory = (sp, model) =>
    new Enforcer(model, new EFCoreAdapter<int>(sp));

Resolves #[issue_number]

Original prompt

This section details on the original issue you should resolve

<issue_title>Having lots of issues with DI</issue_title>
<issue_description>Hello, I am trying to DI the enforcer and do things like Load/Add/Remove Policys.

    public class CasbinDbContext(DbContextOptions<CasbinDbContext> options)
        : CasbinDbContext<int>(options)
    {
    }

    builder.Services.AddDbContext<CasbinDbContext>(options =>
        options.UseSqlServer(builder.Configuration.GetConnectionString("Default")));

    // https://github.com/casbin-net/casbin-aspnetcore/blob/master/samples/WebApplicationWithEfcoreSample/Startup.cs
    builder.Services.AddCasbinAuthorization(options =>
    {
        options.DefaultModelPath = "model.conf";

        options.DefaultEnforcerFactory = (p, m) =>
            new Enforcer(m, new EFCoreAdapter<int>(p.GetRequiredService<CasbinDbContext>()));
        options.DefaultRequestTransformerType = typeof(BasicRequestTransformer);
    });

    // ...

    public class IndexModel(IEnforcerProvider enforcerProvider) : PageModel
    {
        private readonly IEnforcer enforcer = enforcerProvider.GetEnforcer()!;
        public void OnGet()
        {
            this.enforcer.LoadPolicy();
        }
    }

Error:

ObjectDisposedException: Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. Object name: 'CasbinDbContext'.

</issue_description>

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

@hsluoyz @sagilio @sociometry @AsakusaRinne

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@hsluoyz
Copy link
Member

hsluoyz commented Oct 30, 2025

@sagilio please review

@hsluoyz hsluoyz requested a review from sagilio October 30, 2025 15:43
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@hsluoyz hsluoyz marked this pull request as ready for review October 30, 2025 15:46
Copilot AI changed the title [WIP] Fix dependency injection issues with Casbin Fix ObjectDisposedException when using EFCoreAdapter with DI and long-lived services Oct 30, 2025
Copilot finished work on behalf of hsluoyz October 30, 2025 16:04
Copilot AI requested a review from hsluoyz October 30, 2025 16:04
@hsluoyz
Copy link
Member

hsluoyz commented Oct 30, 2025

@VictorioBerra plz review

@VictorioBerra
Copy link

@VictorioBerra plz review

I think this looks good. I would recommend updating https://github.com/casbin-net/casbin-aspnetcore/tree/master/samples/WebApplicationWithEfcoreSample as well once this is shipped to use the new extension methods.

I liked GetOrResolveDbContext.

@hsluoyz
Copy link
Member

hsluoyz commented Oct 31, 2025

@VictorioBerra plz review

I think this looks good. I would recommend updating https://github.com/casbin-net/casbin-aspnetcore/tree/master/samples/WebApplicationWithEfcoreSample as well once this is shipped to use the new extension methods.

I liked GetOrResolveDbContext.

@copilot modify based on the above comment

Copy link
Contributor Author

Copilot AI commented Oct 31, 2025

@VictorioBerra plz review

I think this looks good. I would recommend updating https://github.com/casbin-net/casbin-aspnetcore/tree/master/samples/WebApplicationWithEfcoreSample as well once...

I'm working in the efcore-adapter repository and don't have access to modify the casbin-aspnetcore repository. The sample update would need to be done separately in that repository once this PR is merged and the new version is published to NuGet.

All the changes needed for this fix are complete in this PR:

  • IServiceProvider constructor for resolving DbContext per operation
  • Extension methods AddEFCoreAdapter<TKey>() for easy DI registration
  • Updated README with DI usage examples
  • Comprehensive tests verifying the fix

The casbin-aspnetcore sample can be updated by the maintainers after this is released.

Copilot finished work on behalf of hsluoyz October 31, 2025 05:47
@hsluoyz hsluoyz changed the title Fix ObjectDisposedException when using EFCoreAdapter with DI and long-lived services feat: fix ObjectDisposedException when using EFCoreAdapter with DI and long-lived services Nov 1, 2025
@hsluoyz hsluoyz merged commit a60494f into master Nov 1, 2025
7 of 9 checks passed
@github-actions
Copy link

github-actions bot commented Nov 1, 2025

🎉 This PR is included in version 2.10.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Having lots of issues with DI

4 participants