FuryTechs.BLM.NetStandard 7.0.0

dotnet add package FuryTechs.BLM.NetStandard --version 7.0.0                
NuGet\Install-Package FuryTechs.BLM.NetStandard -Version 7.0.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FuryTechs.BLM.NetStandard" Version="7.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add FuryTechs.BLM.NetStandard --version 7.0.0                
#r "nuget: FuryTechs.BLM.NetStandard, 7.0.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install FuryTechs.BLM.NetStandard as a Cake Addin
#addin nuget:?package=FuryTechs.BLM.NetStandard&version=7.0.0

// Install FuryTechs.BLM.NetStandard as a Cake Tool
#tool nuget:?package=FuryTechs.BLM.NetStandard&version=7.0.0                

FuryTech.BLM

Business Layer Management utils for Entity Framework 6

Concepts

The goal of the BLM packages is to create a separate layer for authorization, interpretation and event distributing logic between your data access layer (usually EF6) and your controller layer.

Usage

Dependency Injection

To use the EfRepository, you'll need to install the package FuryTechs.BLM.EntityFrameworkCore package. Add to the service collection using something like this:

public void ConfigureServices(IServiceCollection services)
{
  ...
  services.AddEntityFrameworkInMemoryDatabase();
  services.AddBLMEFCore();
  // This is otional, if you have only one DbContext, you can use this to resolve the EfRepository with only the EntityType generic parameter
  // services.AddBLMEFCoreDefaultDbContext<MyDbContext>();
  ...
}

EfRepository

You can use the EfRepository<T> in the same way as you did with Entity Framework's DbContext, it will take care about handling the custom logic you've implemented in your authorizers / listeners / interpreters.

public class MyEntityController : ControllerBase 
{
    private readonly EfRepository<MyEntityType> _repository;

    public MyController(EfRepository<MyDbContext, MyEntityType> reposotiry)
    {
        _repository = repository;
    }
}

or if you used the services.AddBLMEFCoreDefaultDbContext<MyDbContext>() in your ConfigureServices

public class MyEntityController : ControllerBase 
{
    private readonly EfRepository<MyEntityType> _repository;

    public MyController(EfRepository<MyEntityType> reposotiry)
    {
        _repository = repository;
    }
}

TODO: Work in progress, down below it's the old README

ContextInfo

This is a custom class passed to the business logic functions with the following properties:

  • IIdentity Identity - The user identity
  • Task<IQueryable<T>> GetAuthorizedEntitySetAsync<T> - One specified authorized entity set
  • IQueryable<T> GetFullEntitySet<T> - The unauthorized, full entity set (technically, EF's DbSet<T>)

Authorizers

You can implement your own authorization for the entity types with them. The package supports these types of authorizers, you should derive from their abstracts:

AuthorizeCollection

Triggered, when a user gets the EfRepository's 'Entities' attribute

public class MyCollectionAuthorizer : AuthorizeCollection<MyEntity>
{
    public override async Task<IQueryable<MyEntity>> AuthorizeCollectionAsync(IQueryable<MyEntity>
    entities, IContextInfo ctx)
    {
        var myUser = ctx.Identity.GetMyUser();
        if (user.IsAdmin)
        {
            return entities;
        }

        return entities.Where(r => r.IsPublic);
    }
}
AuthorizeCreate

Triggered on each entity, when a user calls Repository.Add/AddAsync/AddRange/AddRangeAsync and new entities when calling Repository.SaveChanges/SaveChangesAsync.

public class CreateAdminOnly : IAuthorizeCreate<ICreateAdminOnly>
{
    public async Task<AuthorizationResult> CanCreateAsync(ICreateAdminOnly entity,
    IContextInfo ctx)
    {
        if (ctx.Identity.GetTerUser().IsAdmin)
        {
            return AuthorizationResult.Success();
        }

        return AuthorizationResult.Fail($"Only admin users are authorized to create entity with type '{entity.GetType().FullName}'", entity);
    }
}
AuthorizeModify

Triggered before modifying entity in the DB. Very similar to AuthorizeCreate, but the unchanged and the updated entity are both passed.

AuthorizeRemove

Triggered before deleting an entity from DB. Similar to AuthorizeCreate.

Interpreters

They are to change a simple property value on the entity, before saving to the DB, you can eliminate DB triggers (BeforeInsert, BeforeUpdate) with them.

    public class CreatedByUserInterpreter : InterpretBeforeCreate<IHasCreator>
    {
        public override IHasCreator DoInterpret(IHasCreator entity, IContextInfo context)
        {
            var user = context.GetFullEntitySet<User>().FirstOrDefault(a => a.LoginName == context.Identity.Name);
            entity.CreatedByUser = user;
            return entity;
        }
    }

    public class ModifiedByInterpreter : InterpretBeforeModify<IHasModifiedBy>
    {
        public override IHasModifiedBy DoInterpret(IHasModifiedBy originalEntity, IHasModifiedBy modifiedEntity, IContextInfo context)
        {
            var modifier = context.GetFullEntitySet<User>().FirstOrDefault(a => a.LoginName == context.Identity.Name);
            modifiedEntity.ModifiedByUser = modifier;
            return modifiedEntity;
        }
    }

EventListeners

...Docs coming soon. 😃

BLM Inheritance Principles

If you've implemented an authorizer/interpreter/event listener for a base class and you have a repository with the derived class, the authorizer/interpreter/listener will kick in when you use the derived repository as well. This works with interfaces also.

FuryTechs.BLM.Base

FuryTechs.BLM.EF6

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on FuryTechs.BLM.NetStandard:

Package Downloads
FuryTechs.BLM.EntityFrameworkCore

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
7.0.0 415 1/20/2023
2.0.22 1,942 9/3/2019
2.0.21 700 9/3/2019
2.0.20 738 7/12/2019
2.0.19 732 5/28/2019
2.0.18 740 5/28/2019
2.0.16 726 5/28/2019
2.0.15 871 4/25/2019
2.0.14 793 3/26/2019
2.0.13 730 3/26/2019
2.0.12 743 3/22/2019
2.0.11 753 3/14/2019
2.0.10 762 2/26/2019
2.0.9 807 2/25/2019
2.0.8 691 1/31/2019
2.0.7-preview 840 6/21/2017
2.0.5-preview 861 6/20/2017
2.0.4-preview 847 6/18/2017
2.0.3-preview 765 6/18/2017
2.0.2-preview 766 6/16/2017
2.0.1 834 9/17/2018
2.0.1-preview 829 6/16/2017
2.0.0 748 9/16/2018
2.0.0-preview 777 6/16/2017
1.0.0 1,100 6/6/2017