2017-12-15 5 views
0

Hier ist das Szenario, das ich getroffen injizieren:Wie die Gattung IServiceProvide.GetService dynamisch in .net Kern

im Controller ich das Generic Repository-Funktion wie folgt injizieren will:

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>>()) 
       { 
        //... 
       } 
      } 

dort haben drei Einheiten QuestionVoteRecord, AnswerVoteRecord, CommentVoteRecord, die alle von VoteRecord erben Die IVoteRepository Schnittstelle ist wie:

public interface IVoteRecordRepository<T> : IDisposable 
{ 
    T Single(Guid voterGuid, int contentId); 

    Task<T> SingleAsync(Guid voterGuid, int contentId); 

    Task<bool> Add(T voteRecord); 
} 

Die VoteRepository Funktion ist wie die

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(); 
    } 
} 

Was ich wollte, ist, dass:

Wenn die ContentTypeQuestion_Asking ist ich die IVoteRecordRepository<QuestionVoteRecord> im GetService von Serviceprovider erhalten möchten.

Und wenn ContentType ist Question_Answer Ich möchte ist IVoteRecordRepository<AnswerVoteRecord> in der GetService von ServiceProvider.

PS: Ich bin für Sie Entschuldigung, wenn meine Frage unklar ist oder Sie verwirrt, weil meine Muttersprache nicht Englisch ist. Ich hoffe, du kannst helfen, es zu bearbeiten.

Antwort

0

Sie sind sehr nah an der Lösung. In Ihrem switch Betreiber die Art der gewünschten Repository zu einem gewissen Variablen speichern und dann IServiceProvider.GetService(Type serviceType) Aufruf für diese Art verwenden:

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)) 
     { 
      //... 
     } 
    } 
} 
+0

bekam ich den Fehler 'Objekt: Typ in einer using-Anweisung verwendet wird, muss implizit konvertierbar sein zu‚System.IDisposable '' – doublnt

+0

Überprüfen Sie die Aktualisierung meiner Antwort. Soweit 'GetService()' return type ein 'Objekt' ist, sollten Sie es in' IDisposable' umwandeln. Das ist in Ordnung, weil das aufgelöste Objekt 'VoteRecordRepository ' '' IDisposable' implementiert. – CodeFuller