How to Implement EF Core-Like Interceptors in .NET Framework with EF6

Fermin Perdomo Fermin Perdomo
schedule 2 min read

When working with .NET Core and EF Core, it's easy to plug in interceptors using the built-in AddDbContext and AddInterceptors methods:

services.AddDbContext<IApplicationDbContext, ApplicationDbContext>(
    (sp, options) => options
        .UseSqlServer(connectionString)
        .AddInterceptors(
            sp.GetRequiredService<UpdateAuditableInterceptor>(),
            sp.GetRequiredService<InsertOutboxMessagesInterceptor>()));

But what if you're working with a legacy .NET Framework 4.x project using Entity Framework 6.x?

In this post, I’ll show you how to implement similar behavior—using interceptors, dependency injection, and auditable logic—in a .NET Framework + EF6 setup.

Background: Interceptors in EF6 vs EF Core

FeatureEF Core (Modern)EF6 (in .NET Framework)
Interceptor support | AddInterceptors() (per context) | DbInterception.Add() (global)
Dependency Injection | Built-in with IServiceCollection | Manual or via DI container
SaveChanges Auditing | Supported via SaveChanges() | Supported via SaveChanges()


Goal

Recreate this EF Core-style setup in EF6:


services.AddSingleton<UpdateAuditableInterceptor>(); services.AddSingleton<InsertOutboxMessagesInterceptor>(); services.AddDbContext<IApplicationDbContext, ApplicationDbContext>( (sp, options) => options .UseSqlServer(connectionString) .AddInterceptors(...));

Step 1: Define EF6 Interceptors

In EF6, you can create interceptors by implementing interfaces like IDbCommandInterceptor.


public class UpdateAuditableInterceptor : IDbCommandInterceptor { public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) { // Add your auditing logic here } // You can leave the rest of the methods empty if not needed public void NonQueryExecuting(...) { } public void ScalarExecuting(...) { } // etc. }

You can do the same for your InsertOutboxMessagesInterceptor.

Step 2: Register Interceptors with EF6

EF6 does not support context-scoped interceptors. Instead, use the static DbInterception class:

Option A: Global Registration in Global.asax.cs


protected void Application_Start() { DbInterception.Add(new UpdateAuditableInterceptor()); DbInterception.Add(new InsertOutboxMessagesInterceptor()); }

Option B: Register via Dependency Injection

If you’re using Microsoft.Extensions.DependencyInjection (or any DI container), you can do this:


var services = new ServiceCollection(); services.AddSingleton<UpdateAuditableInterceptor>(); services.AddSingleton<InsertOutboxMessagesInterceptor>(); services.AddScoped<ApplicationDbContext>(provider => { var interceptor1 = provider.GetRequiredService<UpdateAuditableInterceptor>(); var interceptor2 = provider.GetRequiredService<InsertOutboxMessagesInterceptor>(); DbInterception.Add(interceptor1); DbInterception.Add(interceptor2); return new ApplicationDbContext("YourConnectionString"); });
⚠️ Important: EF6 interceptors are global and affect all DbContext instances in the AppDomain.

Bonus: SaveChanges Auditing Without Interceptors

For simple audit tracking like setting UpdatedAt timestamps, it's better to override SaveChanges() in your context:


public override int SaveChanges() { var entries = ChangeTracker.Entries<IAuditableEntity>(); foreach (var entry in entries) { if (entry.State == EntityState.Modified) { entry.Entity.UpdatedAt = DateTime.Now; } } return base.SaveChanges(); }

This is cleaner, more predictable, and avoids EF6 interceptor quirks.

Testing It All

Make sure to test with:

  • Inserts and updates for auditable entities
  • Scenarios where interceptors may not fire (e.g., raw SQL)
  • Multi-threaded contexts if using global interceptors

Summary

You can mimic EF Core's AddInterceptors() in EF6, but with some caveats:

  • Interceptors are global in EF6.
  • Manual DI setup is required.
  • For auditing, overriding SaveChanges() is often simpler and safer.

If you're maintaining a .NET Framework project but want to adopt some clean patterns from EF Core, this approach will help bridge that gap.


Reactions

lock You need to be logged in to react.
Log In

Newsletter

Get new posts delivered straight to your inbox.

mail

Great Tools for Developers

Git Tower

Git Tower

A powerful Git client for Mac and Windows that simplifies version control.

Visit arrow_forward
Mailcoach

Mailcoach

Self-hosted email marketing platform for sending newsletters and automated emails.

Visit arrow_forward
Uptimia

Uptimia

Website monitoring and performance testing tool to ensure your site is always up and running.

Visit arrow_forward
Cloudways

Cloudways

Managed cloud hosting platform that simplifies server management for developers.

Visit arrow_forward

Comments

No comments yet. Be the first to share your thoughts.

chat_bubble Join the conversation — log in to leave a comment.
Log In