TaskHub.Shared

Using Repositories

TaskHub.Shared promotes a clean separation of concerns by using repositories to abstract data access.

Repository Types

The TaskHub.Shared.Persistence.Repository module defines several specialized interfaces:

IReadRepository<TId, TModel>

Used for fetching data.

IWriteRepository<TId, TModel>

Used for persisting data.

IOwnershipRepository

Specialized interface for checking if a resource belongs to a specific owner (e.g., UserId).

Automated Registration

One of the most powerful features of TaskHub.Shared is Automated Dependency Discovery.

  1. Define your Repository:
    public interface IMyRepository : IReadRepository<Guid, MyEntity>;
    
    public class MyRepository(MyDbContext db) : IMyRepository
    {
        public async Task<MyEntity?> GetAsync(Guid id, CancellationToken ct) => 
            await db.Set<MyEntity>().FindAsync([id], ct);
            
        public async Task<bool> IsExistAsync(Guid id, CancellationToken ct) => 
            await db.Set<MyEntity>().AnyAsync(x => x.Id == id, ct);
    }
    
  2. Bootstrap: In your FullHostBuilder or using AddAppDependencies<IRepository>(), the system will scan your assemblies, find MyRepository, and register it as IMyRepository.

    // Inside FullHostBuilder.AppStart()
    Builder.Services.AddAppDependencies<IRepository>();
    

Example Usage

Inject the repository into your command handlers or services.

public class CompleteOrderHandler(IOrderRepository repository, IUnitOfWork unitOfWork) 
    : ICommandHandler<CompleteOrderCommand, Result>
{
    public async Task<Result> HandleAsync(CompleteOrderCommand cmd, CancellationToken ct)
    {
        var order = await repository.GetAsync(cmd.OrderId, ct);
        if (order == null) return ResultFactory.OnFailed(404, "Order not found");

        order.Complete();
        await unitOfWork.SaveAsync(ct);
        
        return ResultFactory.OnSuccess();
    }
}