Using Both
To use both you have to combine two methods. First create the IMyRepository Interface to implement additional methods:
public interface IMyRepository<TEntity> : IRENRepository<TEntity> where TEntity : class
{
Task MyCustomFunction(CancellationToken cancellationToken = default);
}
Then create MyRepository class that inherits from RENRepository and IMyRepository and contains overriden method(s):
public class MyRepository<TEntity> : RENRepository<TEntity>, IMyRepository<TEntity> where TEntity : class
{
public MyRepository(RENDbContext context) : base(context) { }
public override Task<TEntity?> GetSingleAsync(Expression<Func<TEntity, bool>> filter,
Expression<Func<IQueryable<TEntity>, IQueryable<TEntity>>>? include = null,
bool isReadOnly = false,
CancellationToken cancellationToken = default)
{
Console.WriteLine("Getting custom async......");
// Other custom implementations
return base.GetSingleAsync(filter, null, include, isReadOnly, cancellationToken);
}
public Task MyCustomFunction(CancellationToken cancellationToken = default)
{
return Task.Factory.StartNew(() =>
{
cancellationToken.ThrowIfCancellationRequested();
Console.WriteLine("This is my custom Function");
// other custom implementations!
}, cancellationToken);
}
}
To use MyRepository class with the interface, we created IMyRepository interface. We need to add a repository getter function to get repositories in IMyRepository type instead of IRENRepository. We need that because IRENRepository does not contain our custom function!
public interface IMyUnitOfWork<TDbContext>: IRENUnitOfWork<TDbContext> where TDbContext : RENDbContext
{
IMyRepository<TEntity>? GetMyRepository<TEntity>() where TEntity : class;
}
public class MyUnitOfWork<TDbContext> : RENUnitOfWork<TDbContext>, IMyUnitOfWork<TDbContext> where TDbContext : RENDbContext
{
public MyUnitOfWork(TDbContext context) : base(context) { }
public IMyRepository<TEntity>? GetMyRepository<TEntity>() where TEntity: class
{
return (IMyRepository<TEntity>?)Activator.CreateInstance(typeof(MyRepository<TEntity>), new object[] { _context });
}
}
In Program.cs we need to register MyUnitOfWork class from interface IMyUnitOfWork since it contains the repository getter method.
builder.Services.AddScoped(typeof(IMyUnitOfWork<>), typeof(MyUnitOfWork<>));
Then you can use your final Repository and Unit Of Work classes like this:
public class HomeController : ControllerBase
{
private readonly IMyRepository<User> _customUserRepository;
private readonly ICacheService _cacheService;
public HomeController(IMyUnitOfWork<RENDbContext> uow)
{
_customUserRepository = uow.GetMyRepository<User>();
}
[HttpGet, Route("Index")]
public async Task<IActionResult> Index()
{
await _customUserRepository.MyCustomFunction(); // our custom function
await _customUserRepository.GetSingleAsync(_ => _.Id == 1); // our overriden function
return Ok();
}
}
Last updated