IntoItIf

It's kinda Unit of Work, Repository things, done intuitively in EF AND EF Core.

IntoItIf

AppVeyor Github All Releases Github Releases GitHub

It’s kinda Unit of Work, Repository things, done intuitively in EF AND EF Core.

Project NuGet Frameworks Dependencies NuGet Downloads
IntoItIf.Dsl NuGet net471 and up, netstandard20 and up IntoItIf.Dal NuGet
IntoItIf.Dal NuGet net471 and up, netstandard20 and up IntoItIf.Core NuGet
IntoItIf.Core NuGet net471 and up, netstandard20 and up None NuGet
IntoItIf.Dsl.AutoMapper NuGet net471 and up, netstandard20 and up IntoItIf.Dsl NuGet
IntoItIf.Dsl.BatMap NuGet net471 and up, netstandard20 and up IntoItIf.Dsl NuGet
IntoItIf.Dsl.Mapster NuGet net471 and up, netstandard20 and up IntoItIf.Dsl NuGet

Setting it Up

You must setting up your DbContext class first, either by inheriting EfCoreDbContext (EF Core) or EfDbContext (EF):

public class MyDbContext : EfCoreDbContext // Inherit from EfDbContext if you are using EF6 or above
{
   public DbSet<MyEntity> Entities { get; set; }
}

where MyEntity must inherit from IEntity or from base templating class BaseEntity<TEntity>:

public class MyEntity : BaseEntity<MyEntity>
{
   [Key]
   public int Id { get; set; }
   
   public string Name { get; set; }
}

next, define your MyDto class for mapping from MyEntity. This MyDto class must inherit from IDto, or better from BaseDto<TDto, TValidator> class:

public class MyDto: BaseDto<MyDto, MyDtoFluentValidator>
{
   public int Id { get; set; }
   public string Name { get; set; }
}

don’t forget to define you MyDto validator class, by inheriting BaseFluentValidator<T> (using FluentValidator) or BaseValitValidator<T> (using Valit):

public class MyDtoFluentValidator: BaseFluentValidator<MyDto>
{
   public MyDtoFluentValidator()
   {
      RuleFor(x => x.Id).NotEmpty();
      RuleFor(x => x.Name).NotEmpty();
   }
}

(BaseValitValidator<T> version):

public class MyDtoValitValidator : BaseValitValidator<MyDto>
{
   public MyDtoValitValitator()
   {
      Valitator = ValitRules<MyDto>.Create()
        .Ensure(x => x.Id, x => x.IsNonZero())
        .Ensure(x => x.Name, x => x.Required())
        .CreateValitator();
   }
   
   protected override IValitator<MyDto> Valitator { get; }
}

next, create you IMapperProfile derived class to maps MyEntity to MyDto and vice-versa:

public class MyMapperProfile : IMapperProfile
{
   public Option<(Type Source, Type Destination)>[] GetBinds()
   {
      return new Option<(Type Source, Type Destination)>[]
      {
         (typeof(MyEntity), typeof(MyDto)),
         (typeof(MyDto), typeof(MyEntity)),
      };
   }
}

And, lastly, at your startup class, inject the IMapperService like so:

// Use AutoMapper if you want to support Value-Object pattern
var mapperSvc = new AutoMapperService(); // Choose between AutoMapperService, BatMapMapperService, or MapsterMapperService
mapperSvc.Initialize<IMapperProfile>(new MyMapperProfile());
DslInjecterGetter.SetBaseMapperService(mapperSvc);
var uow = new EfCoreUnitOfWork(new MyDbContext()); // Or use EfUnitOfWork, if you are using EF6 or above.
DslInjecterGetter.SetBaseUnitOfWork(uow);

Usage

It’s quite daunting to setting it up huh? But wait, this is how you can utilize my charming library:

Option<CancellationToken> ctok = CancellationToken.None;
var dto = new MyDto();

var createResult = Create<MyEntity, MyDto, MyCreateInterceptor>.Handle(dto, ctok);
var deleteResult = Delete<MyEntity, MyDto, MyDeleteInterceptor>.Handle(dto, ctok);
var readLookupResult = ReadLookup<MyEntity, MyDto, MyReadLookupInterceptor>.Handle(false, ctok);
var readOneResult = ReadOne<MyEntity, MyDto, MyReadOneInterceptor>.Handle(dto, ctok);
var readPagedResult = ReadPaged<MyEntity, MyDto, MyReadPagedInterceptor>.Handle(1, 1, null, "Bla", ctok);
var updateResult = Update<MyEntity, MyDto, MyUpdateInterceptor>.Handle(dto, ctok);

And if you need transactional DB processing, you would do it like this:

using (var trx = uow.GetDbTransaction<MyDbContext>())
{
   try
   {
      var createResult = Create<MyEntity, MyDto, MyCreateInterceptor>.Handle(dto, ctok);
      var deleteResult = Delete<MyEntity, MyDto, MyDeleteInterceptor>.Handle(dto, ctok);
      var readLookupResult = ReadLookup<MyEntity, MyDto, MyReadLookupInterceptor>.Handle(false, ctok);
      var readOneResult = ReadOne<MyEntity, MyDto, MyReadOneInterceptor>.Handle(dto, ctok);
      var readPagedResult = ReadPaged<MyEntity, MyDto, MyReadPagedInterceptor>.Handle(1, 1, null, "Bla", ctok);
      var updateResult = Update<MyEntity, MyDto, MyUpdateInterceptor>.Handle(dto, ctok);
      trx.Commit();
   }
   catch (Exception ex)
   {
      trx.Rollback();
   }
}

Yes, of course, you will ask: what MyCreateInterceptor, MyDeleteInterceptor, MyReadLookupInterceptor, MyReadOneInterceptor, MyReadOneInterceptor, MyReadPagedInterceptor, and MyUpdateInterceptor are all about. It’s your task to find what they are….