Here is the scenario I met:
In the Controller I want to inject the Generic Repository function like following:
using (var scope = HttpContext.RequestServices.CreateScope())
{
switch (voteRecordDto.ContentType)
{
case ContentType.Question_Asking:
voteRecordType = "QuestionVoteRecord";
break;
case ContentType.Question_Answer:
voteRecordType = "AnswerVoteRecord";
break;
case ContentType.Question_AnswerComment:
voteRecordType = "CommentVoteRecord";
break;
default:
result = OperationResponse.Error("There is no accept Type!");
break;
}
using (var repository = scope.ServiceProvider.GetService<IVoteRecordRepository<QuestionVoteRecord>>())
{
//...
}
}
There have three entities QuestionVoteRecord,AnswerVoteRecord,CommentVoteRecord that all inherit from VoteRecord
The IVoteRepository interface is like:
public interface IVoteRecordRepository<T> : IDisposable
{
T Single(Guid voterGuid, int contentId);
Task<T> SingleAsync(Guid voterGuid, int contentId);
Task<bool> Add(T voteRecord);
}
The VoteRepository function is like that
public class VoteRecordRepository<T> : IVoteRecordRepository<T> where T : VoteRecord, IDisposable
{
private readonly EFDbContext _efDbContext;
private readonly IQueryable<T> _queryable;
public VoteRecordRepository(EFDbContext efDbContext)
{
_efDbContext = efDbContext;
_queryable = _efDbContext.Set<T>();
}
public async Task<bool> Add(T voteRecord)
{
_efDbContext.Add(voteRecord);
return await _efDbContext.SaveChangesAsync() > 0;
}
public T Single(Guid voterGuid, int contentId)
{
return _queryable
.FirstOrDefault(p => p.ContentId == contentId && p.VoterId == voterGuid);
}
public async Task<T> SingleAsync(Guid voterGuid, int contentId)
{
return await _queryable
.FirstOrDefaultAsync(p => p.ContentId == contentId && p.VoterId == voterGuid);
}
public void Dispose()
{
_efDbContext.Dispose();
}
}
What I wanted is that:
If the ContentType is Question_Asking I want to get the
IVoteRecordRepository<QuestionVoteRecord> in the GetService from ServiceProvider.
And when ContentType is Question_Answer I want is IVoteRecordRepository<AnswerVoteRecord> in the GetService from ServiceProvider.
PS:I am for you apology if my question is unclear or make u confused, cause my native language is not English. I hope u can help to edit it.
You are very close to the solution. In your switch operator save the type of desired repository to some variable and then use IServiceProvider.GetService(Type serviceType) call for this type:
Type voteRecordType = null;
using (var scope = HttpContext.RequestServices.CreateScope())
{
switch (voteRecordDto.ContentType)
{
case ContentType.Question_Asking:
voteRecordType = typeof(IVoteRecordRepository<QuestionVoteRecord>);
break;
case ContentType.Question_Answer:
voteRecordType = typeof(IVoteRecordRepository <AnswerVoteRecord>);
break;
case ContentType.Question_AnswerComment:
voteRecordType = typeof(IVoteRecordRepository<CommentVoteRecord>);
break;
default:
result = OperationResponse.Error("There is no accept Type!");
break;
}
if (voteRecordType != null)
{
using (var repository = (IDisposable)scope.ServiceProvider.GetService(voteRecordType))
{
//...
}
}
}
You have to bring in Microsoft.Extensions.DependencyInjection namespace to gain access to the generic
GetService<T>();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With