Giter Club home page Giter Club logo

efcorehooks's Introduction

EFCoreHooks

This project provides a simple, attribute-based hooking system for all projects using all versions of Microsoft's Entity Framework Core 2.1 and above.

Installation

Make sure you have Nuget installed, the run

PM> Install-Package EFCoreHooks

Usage

First you must edit your ConfigureServices(IServiceCollection) so the hooking system can have access to the Dependency Injection Container

using EFCoreHooks;

/* ... */

public void ConfigureServices(IServiceColleciton services) {
   /* ... */
   services.ConfigureDbHooks();
   /* ... */
}

In most cases the only other thing you need to do is to have any dbcontext that you want to have hooks extends from HookedDbContext or HookedIdentityDbContext. Both classes are designed to be drop-in replacements for DbContext and IdentityDbContext respectively.

In cases where you need a base class other than DbContext or IdentityDbContext, you can use the extension methods directly by implementing IHookedDbContext, and overriding the SaveChanges and SaveChagnesAsync methods to call the extension methods instead of the base class.

public override int SaveChanges(bool acceptAllChangesOnSuccess)
{
    return this.HookedSaveChanges(acceptAllChangesOnSuccess);
}

public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess,
    CancellationToken cancellationToken = default(CancellationToken))
{
    return this.HookedSaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}

Implementing the IHookedDbContext interface is quite simple:

public class HookedDbContext : DbContext, IHookedDbContext
{
    public HookedDbContext(DbContextOptions options, HookManagerContainer hooks) : base(options)
    {
        Hooks = hooks;
        Hooks.InitializeForAll(this);
    }

    public HookManagerContainer Hooks { get; }

    public int SaveChangesBase(bool acceptAllChanges)
    {
        // Mirror the base classes saved changes so the extension methods can access them
        return base.SaveChanges(acceptAllChanges);
    }

    public Task<int> SaveChangesBaseAsync(bool acceptAllChanges,
        CancellationToken cancellationToken = default(CancellationToken))
    {
        // Mirror the base classes saved changes so the extension methods can access them
        return base.SaveChangesAsync(acceptAllChanges, cancellationToken);
    }

    public override int SaveChanges(bool acceptAllChangesOnSuccess)
    {
        // Run the extension method instead of the base class's method
        return this.HookedSaveChanges(acceptAllChangesOnSuccess);
    }

    public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess,
        CancellationToken cancellationToken = default(CancellationToken))
    {
        // Run the extension method instead of the base class's method
        return this.HookedSaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
    }
}

Hooks

The following hooks are available via attributes attached to static methods:

  • [OnBeforeCreate] - Before Model Created
  • [OnBeforeUpdate] - Before Model Modified
  • [OnBeforeSave] - Before Model Created or Modified
  • [OnBeforeDelete] - Before Model Delete
  • [OnAfterCreate] - Before Model Created
  • [OnAfterUpdate] - Before Model Modified
  • [OnAfterSave] - Before Model Created or Modified
  • [OnAfterDelete] - Before Model Delete

Each hook has a simple dependency injection container with the following types:

Type Value
EntityType The EntityType provided by the ChangeTracker
<Your DbContext> The DbContext the entity is part of. You may use DbContext if you just need the common properties
<Model Type> The entity object that trigger this hook.
IServiceProvider The main DI container your app is running in (useful for grabbing things like ILogger<>)

efcorehooks's People

Contributors

dustinlacewell avatar scottbot95 avatar

Watchers

 avatar

Forkers

dustinlacewell

efcorehooks's Issues

[Feature] Allow for aysnc hooks

Currently async hooks are just allowed to run in the background without being awaited. They should be awaited one by one to ensure no database collisions.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.