Changes in / [806f4ee:728eb31]
- Location:
- src
- Files:
-
- 22 added
- 4 deleted
- 27 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Clients/Angular/finki-chattery/src/app/core/state/question-facade.service.ts
r806f4ee r728eb31 2 2 import { Injectable } from '@angular/core'; 3 3 import { Action, Store } from '@ngrx/store'; 4 import { Observable, Subject , throwError} from 'rxjs';5 import { catchError, filter, map} from 'rxjs/operators';4 import { Observable, Subject } from 'rxjs'; 5 import { filter } from 'rxjs/operators'; 6 6 7 7 import { … … 9 9 PreviewQuestionViewModel, 10 10 QuestionStateViewModel, 11 SearchQuestionsQueryViewModel 11 SearchQuestionsQueryViewModel, 12 VoteType 12 13 } from 'src/app/shared-app/models'; 13 14 import { … … 16 17 GetPreviewQuestionsPopular, 17 18 GetQuestionState, 18 GetSearchQuestions 19 GetSearchQuestions, 20 VoteAnswer 19 21 } from './question-state/question.actions'; 20 22 import { questionStateQuery } from './question-state/question.selectors'; … … 30 32 31 33 constructor(private store: Store<QuestionState>) { 32 this.effectWorking$ = this.store.select(questionStateQuery.effectWorking).pipe( 33 filter((effect) => effect !== null), 34 map((effect) => { 35 if (effect instanceof HttpErrorResponse) { 36 throw effect; 37 } else { 38 return effect; 39 } 40 }), 41 catchError((err) => { 42 return throwError(err); 43 }) 44 ); 34 this.effectWorking$ = this.store.select(questionStateQuery.effectWorking).pipe(filter((effect) => effect !== null)); 45 35 } 46 36 … … 81 71 } 82 72 73 public voteAnswer(answerUid: string, questionUid: string, voteType: VoteType): void { 74 this.dispatchEffect(new VoteAnswer(questionUid, answerUid, voteType)); 75 } 76 83 77 public fetchQuestion(questionUid: string): void { 84 78 this.dispatchEffect(new GetQuestionState(questionUid)); -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.actions.ts
r806f4ee r728eb31 2 2 import { Action } from '@ngrx/store'; 3 3 4 import { PreviewQuestionViewModel, QuestionStateViewModel, SearchQuestionsQueryViewModel } from 'src/app/shared-app/models'; 4 import { 5 PreviewQuestionViewModel, 6 QuestionStateViewModel, 7 SearchQuestionsQueryViewModel, 8 VoteAnswerViewModel, 9 VoteType 10 } from 'src/app/shared-app/models'; 5 11 6 12 export enum QuestionActionTypes { … … 13 19 GetSearchQuestions = '[Question] Get search questions', 14 20 GetSearchQuestionsSuccess = '[Question] Get search questions Success', 21 VoteAnswer = '[Question] Vote answer', 22 VoteAnswerSuccess = '[Question] Vote answer Success', 15 23 EffectStartedWorking = '[Question] Effect Started Working', 16 24 EffectFinishedWorking = '[Question] Effect Finished Working', … … 66 74 } 67 75 76 export class VoteAnswer implements Action { 77 readonly type = QuestionActionTypes.VoteAnswer; 78 79 constructor(public questionUid: string, public answerUid: string, public voteType: VoteType) {} 80 } 81 82 export class VoteAnswerSuccess implements Action { 83 readonly type = QuestionActionTypes.VoteAnswerSuccess; 84 85 constructor(public payload: VoteAnswerViewModel) {} 86 } 87 68 88 export class EffectStartedWorking implements Action { 69 89 readonly type = QuestionActionTypes.EffectStartedWorking; … … 89 109 | GetPreviewQuestionsPopularSuccess 90 110 | GetSearchQuestionsSuccess 111 | VoteAnswerSuccess 91 112 | EffectStartedWorking 92 113 | EffectFinishedWorking -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.effects.ts
r806f4ee r728eb31 7 7 import { BaseApiService } from 'src/app/shared-app/services/base-api.service'; 8 8 import { QuestionFacadeService } from '../question-facade.service'; 9 import { PreviewQuestionResponse, QuestionStateResponse } from './question-state.models'; 9 import { VoteAnswerRequest } from './question-state-request.models'; 10 import { PreviewQuestionResponse, QuestionStateResponse, VoteAnswerResponse } from './question-state-response.models'; 10 11 import { 11 12 EffectFinishedWorking, … … 19 20 GetSearchQuestions, 20 21 GetSearchQuestionsSuccess, 21 QuestionActionTypes 22 QuestionActionTypes, 23 VoteAnswer, 24 VoteAnswerSuccess 22 25 } from './question.actions'; 23 26 import { QuestionMapper } from './question.mapper'; … … 103 106 ); 104 107 }); 108 109 voteAnswer$ = createEffect(() => { 110 return this.actions$.pipe( 111 ofType<VoteAnswer>(QuestionActionTypes.VoteAnswer), 112 mergeMap((action) => { 113 const body = new VoteAnswerRequest(action.voteType); 114 return this.api.post<VoteAnswerResponse>(`v1/questions/${action.questionUid}/answers/${action.answerUid}/votes`, body).pipe( 115 switchMap((state) => [new VoteAnswerSuccess(QuestionMapper.ToVoteAnswerViewModel(state)), new EffectFinishedWorking()]), 116 catchError((err) => [new EffectFinishedWorkingError(err)]) 117 ); 118 }) 119 ); 120 }); 105 121 } -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.mapper.ts
r806f4ee r728eb31 10 10 QuestionStateViewModel, 11 11 StudentQuestionStateViewModel, 12 TeamQuestionStateViewModel 12 TeamQuestionStateViewModel, 13 VoteAnswerViewModel 13 14 } from 'src/app/shared-app/models'; 14 15 import { TranslateFromJsonService } from 'src/app/shared-app/services'; 15 import { PreviewQuestionResponse, QuestionStateResponse } from './question-state.models';16 import { PreviewQuestionResponse, QuestionStateResponse, VoteAnswerResponse } from './question-state-response.models'; 16 17 17 18 export class QuestionMapper { … … 51 52 x.correctAnswer, 52 53 moment(x.createdOn), 53 x. upvotesCount,54 x.votesCount, 54 55 answerStudent, 55 56 answerResponses … … 113 114 return questions; 114 115 } 116 117 public static ToVoteAnswerViewModel(response: VoteAnswerResponse): VoteAnswerViewModel { 118 return new VoteAnswerViewModel(response.answerUid, response.voteUid, response.voteType); 119 } 115 120 } -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.reducers.ts
r806f4ee r728eb31 1 import { VoteType } from 'src/app/shared-app/models'; 1 2 import { QuestionAction, QuestionActionTypes } from './question.actions'; 2 3 import { initialState, QuestionState } from './question.state'; … … 25 26 searchQuestionsQuery: action.query 26 27 }; 28 case QuestionActionTypes.VoteAnswerSuccess: { 29 if (state.question) { 30 return { 31 ...state, 32 question: { 33 ...state.question, 34 answers: state.question.answers.map((x) => { 35 if (x.uid === action.payload.answerUid) { 36 let votesCountNew = x.votesCount; 37 38 switch (action.payload.voteType) { 39 case VoteType.Upvote: 40 votesCountNew++; 41 break; 42 case VoteType.Downvote: 43 votesCountNew--; 44 break; 45 } 46 47 return { 48 ...x, 49 votesCount: votesCountNew 50 }; 51 } 52 53 return x; 54 }) 55 } 56 }; 57 } 58 59 return { 60 ...state 61 }; 62 } 27 63 case QuestionActionTypes.EffectStartedWorking: { 28 64 return { -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.ts
r806f4ee r728eb31 1 1 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; 2 import { VoteType } from 'src/app/shared-app/models'; 2 3 import { ButtonType } from '../button/button.models'; 3 4 export enum VoteType {5 Upvote,6 Downvote7 }8 4 9 5 @Component({ -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.html
r806f4ee r728eb31 14 14 <mat-card-content> 15 15 <div fxLayout="row wrap" fxLayoutAlign="space-around none"> 16 <app-vote [voteCount]="answer.upvotesCount" [correct]="answer.correctAnswer" fxFlex="6%"></app-vote> 16 <app-vote 17 [voteCount]="answer.votesCount" 18 [correct]="answer.correctAnswer" 19 (voteClicked)="answerVoted($event, answer.uid, question.uid)" 20 fxFlex="6%" 21 ></app-vote> 17 22 <div fxFlex="92%"> 18 23 <app-text-editor -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.ts
r806f4ee r728eb31 1 import { HttpErrorResponse } from '@angular/common/http'; 1 2 import { Component, OnInit } from '@angular/core'; 3 import { NotificationService } from 'src/app/core/services/notification.service'; 2 4 import { QuestionFacadeService } from 'src/app/core/state/question-facade.service'; 3 5 4 import { QuestionStateViewModel } from 'src/app/shared-app/models';6 import { QuestionStateViewModel, VoteType } from 'src/app/shared-app/models'; 5 7 import { ButtonType } from '../../generic/button/button.models'; 6 8 … … 14 16 working = true; 15 17 ButtonType = ButtonType; 16 constructor(private questionFacade: QuestionFacadeService ) {}18 constructor(private questionFacade: QuestionFacadeService, private notification: NotificationService) {} 17 19 18 20 ngOnInit(): void { … … 21 23 this.working = false; 22 24 }); 25 26 this.questionFacade.effectWorking$.subscribe((effect) => { 27 if (effect instanceof HttpErrorResponse) { 28 this.notification.handleErrorsNotification(effect.error); 29 } 30 }); 31 } 32 33 answerVoted(voteType: VoteType, answerUid: string, questionUid: string): void { 34 this.questionFacade.voteAnswer(answerUid, questionUid, voteType); 23 35 } 24 36 } -
src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-enums.models.ts
r806f4ee r728eb31 3 3 Popular 4 4 } 5 6 export enum VoteType { 7 Upvote, 8 Downvote 9 } -
src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-view-models.models.ts
r806f4ee r728eb31 1 import { VoteType } from '.'; 2 1 3 export class QuestionStateViewModel { 2 4 constructor( … … 32 34 public correctAnswer: boolean, 33 35 public createdOn: moment.Moment, 34 public upvotesCount: number,36 public votesCount: number, 35 37 public student: AnswerStudentQuestionStateViewModel, 36 38 public answerResponses: AnswerResponseQuestionStateViewModel[] … … 73 75 constructor(public text: string) {} 74 76 } 77 78 export class VoteAnswerViewModel { 79 constructor(public answerUid: string, public voteUid: string, public voteType: VoteType) {} 80 } -
src/Clients/Angular/finki-chattery/src/assets/translations/en.json
r806f4ee r728eb31 53 53 "ask-question-stepper-ask": "Ask question", 54 54 "ask-question-ask-button-back": "Edit question", 55 "ask-question-ask-button": "Ask question" 55 "ask-question-ask-button": "Ask question", 56 "AnswerAlreadyUpvoted": "You have already upvoted this answer", 57 "AnswerAlreadyDownvoted": "You have already downvoted this answer", 58 "StudentHasBadReputation": "You have bad reputation and can not vote" 56 59 } -
src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/Mapper/QuestionMapper.cs
r806f4ee r728eb31 54 54 var answerStudent = new AnswerStudentQuestionStateResponse(x.StudentDto.Id, x.StudentDto.Uid, x.StudentDto.Index, x.StudentDto.ImageUrl, x.StudentDto.Reputation); 55 55 56 return new AnswerQuestionStateResponse(x.Id, x.Uid, x.Text, x.CorrectAnswer, x.CreatedOn, x. UpvotesCount, answerStudent, answerResponses);56 return new AnswerQuestionStateResponse(x.Id, x.Uid, x.Text, x.CorrectAnswer, x.CreatedOn, x.VotesCount, answerStudent, answerResponses); 57 57 }); 58 58 } -
src/FinkiChattery/FinkiChattery.Api/Services/RegisterServices.cs
r806f4ee r728eb31 1 1 using FinkiChattery.Api.ApplicationServices.Authentication; 2 using FinkiChattery.Api.ApplicationServices.Questioning.EventHandlers; 2 3 using FinkiChattery.Api.Services; 3 4 using FinkiChattery.Commands.Questioning; … … 31 32 services.AddScoped<IEventService, EventService>(); 32 33 services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>)); 33 services.AddMediatR(typeof(AskQuestionCommand), typeof(GetQuestionStateQuery) );34 services.AddMediatR(typeof(AskQuestionCommand), typeof(GetQuestionStateQuery), typeof(UpdateAnswerVotesEventHandler)); 34 35 } 35 36 … … 54 55 }); 55 56 services.AddHangfireServer(); 57 58 services.AddScoped<IBackgroundJobClient>(provider => 59 { 60 return new BackgroundJobClient(JobStorage.Current); 61 }); 56 62 } 57 63 -
src/FinkiChattery/FinkiChattery.Commands/Questioning/QuestioningErrorCodes.cs
r806f4ee r728eb31 9 9 public const string CategoriesDontExist = "CategoriesDontExist"; 10 10 public const string TeamDontExist = "TeamDontExist"; 11 public const string AnswerAlreadyUpvoted = "AnswerAlreadyUpvoted"; 12 public const string AnswerAlreadyDownvoted = "AnswerAlreadyDownvoted"; 13 public const string StudentHasBadReputation = "StudentHasBadReputation"; 11 14 } 12 15 } -
src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/CategoriesUidsExist.cs
r806f4ee r728eb31 1 using FinkiChattery.Persistence.Repositories; 2 using FinkiChattery.Persistence.UnitOfWork; 1 using FinkiChattery.Persistence.UnitOfWork; 3 2 using FluentValidation.Validators; 4 3 using System; -
src/FinkiChattery/FinkiChattery.Contracts/Questioning/GetQuestionState/QuestionStateResponse.cs
r806f4ee r728eb31 89 89 public class AnswerQuestionStateResponse 90 90 { 91 public AnswerQuestionStateResponse(long id, Guid uid, string text, bool correctAnswer, DateTime createdOn, long upvotesCount, AnswerStudentQuestionStateResponse studentResponse, IEnumerable<AnswerResponseQuestionStateResponse> answerResponsesResponse)91 public AnswerQuestionStateResponse(long id, Guid uid, string text, bool correctAnswer, DateTime createdOn, long votesCount, AnswerStudentQuestionStateResponse studentResponse, IEnumerable<AnswerResponseQuestionStateResponse> answerResponsesResponse) 92 92 { 93 93 Id = id; … … 96 96 CorrectAnswer = correctAnswer; 97 97 CreatedOn = createdOn; 98 UpvotesCount = upvotesCount;98 VotesCount = votesCount; 99 99 StudentResponse = studentResponse; 100 100 AnswerResponsesResponse = answerResponsesResponse; … … 107 107 public bool CorrectAnswer { get; } 108 108 public DateTime CreatedOn { get; } 109 public long UpvotesCount { get; }109 public long VotesCount { get; } 110 110 public AnswerStudentQuestionStateResponse StudentResponse { get; } 111 111 public IEnumerable<AnswerResponseQuestionStateResponse> AnswerResponsesResponse { get; } -
src/FinkiChattery/FinkiChattery.Database/FinkiChattery.Database.sqlproj
r806f4ee r728eb31 75 75 <Folder Include="dbo\Tables\QuestionCategory" /> 76 76 <Folder Include="Snapshots" /> 77 <Folder Include="dbo\Tables\Vote" /> 77 78 </ItemGroup> 78 79 <ItemGroup> … … 81 82 <Build Include="dbo\Tables\StudentTeam.sql" /> 82 83 <Build Include="dbo\Tables\TeacherTeam.sql" /> 83 <Build Include="dbo\Tables\Upvote.sql" />84 84 <Build Include="dbo\Tables\User\AspNetRoleClaims.sql" /> 85 85 <Build Include="dbo\Tables\User\AspNetRoles.sql" /> … … 100 100 <Build Include="dbo\Tables\QuestionCategory\QuestionCategory.sql" /> 101 101 <None Include="dbo\Tables\QuestionCategory\QuestionCategory.Debug.Seed.sql" /> 102 <Build Include="dbo\Tables\Vote\Vote.sql" /> 102 103 </ItemGroup> 103 104 <ItemGroup> -
src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Answer/Answer.Debug.Seed.sql
r806f4ee r728eb31 12 12 (3, N'cee193c3-9d36-4ed8-81b2-15eb4ff305f1', N'Answer 3', 2, 1, 1, GETUTCDATE(), 5), 13 13 (4, N'dee193c3-9d36-4ed8-81b2-15eb4ff305f1', N'Answer 4', 2, 1, 0, GETUTCDATE(), 5) 14 ) AS temp ([Id], [Uid], [Text], [QuestionFk], [StudentFk], [CorrectAnswer], [CreatedOn], [ UpvotesCount])14 ) AS temp ([Id], [Uid], [Text], [QuestionFk], [StudentFk], [CorrectAnswer], [CreatedOn], [VotesCount]) 15 15 ) AS S 16 16 ON T.[ID] = S.[ID] … … 21 21 T.[StudentFk] = S.[StudentFk], 22 22 T.[CorrectAnswer] = S.[CorrectAnswer], 23 T.[ UpvotesCount] = S.[UpvotesCount]23 T.[VotesCount] = S.[VotesCount] 24 24 WHEN NOT MATCHED THEN 25 25 INSERT … … 32 32 [CorrectAnswer], 33 33 [CreatedOn], 34 [ UpvotesCount]34 [VotesCount] 35 35 ) 36 36 VALUES 37 (S.[Id], S.[Uid], S.[Text], S.[QuestionFk], S.[StudentFk], S.[CorrectAnswer], S.[CreatedOn], S.[ UpvotesCount]);37 (S.[Id], S.[Uid], S.[Text], S.[QuestionFk], S.[StudentFk], S.[CorrectAnswer], S.[CreatedOn], S.[VotesCount]); 38 38 SET IDENTITY_INSERT [dbo].[Answer] OFF 39 39 END -
src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Answer/Answer.sql
r806f4ee r728eb31 7 7 [CorrectAnswer] BIT NOT NULL, 8 8 [CreatedOn] SMALLDATETIME NOT NULL, 9 [ UpvotesCount] BIGINT NOT NULL DEFAULT 0,9 [VotesCount] BIGINT NOT NULL DEFAULT 0, 10 10 CONSTRAINT [PK_Answer] PRIMARY KEY CLUSTERED ([Id] ASC), 11 11 CONSTRAINT [FK_Answer_Question_QuestionFk] FOREIGN KEY ([QuestionFk]) REFERENCES [dbo].[Question] ([Id]), -
src/FinkiChattery/FinkiChattery.Persistence/Configurations/AnswerConfig.cs
r806f4ee r728eb31 22 22 builder.Property(x => x.CorrectAnswer).HasColumnName(@"CorrectAnswer").HasColumnType("bit").IsRequired(); 23 23 builder.Property(x => x.CreatedOn).HasColumnName(@"CreatedOn").HasColumnType("smalldatetime").IsRequired(); 24 builder.Property(x => x. UpvotesCount).HasColumnName(@"UpvotesCount").HasColumnType("bigint").IsRequired().HasDefaultValue(0);24 builder.Property(x => x.VotesCount).HasColumnName(@"VotesCount").HasColumnType("bigint").IsRequired().HasDefaultValue(0); 25 25 26 26 builder.HasOne(x => x.Question).WithMany(x => x.Answers).HasForeignKey(x => x.QuestionFk).OnDelete(DeleteBehavior.Restrict); -
src/FinkiChattery/FinkiChattery.Persistence/Context/ApplicationDbContext.cs
r806f4ee r728eb31 23 23 public DbSet<TeacherTeam> TeacherTeams { get; set; } 24 24 public DbSet<Team> Teams { get; set; } 25 public DbSet< Upvote> Upvotes { get; set; }25 public DbSet<Vote> Votes { get; set; } 26 26 27 27 protected override void OnModelCreating(ModelBuilder builder) … … 42 42 builder.ApplyConfiguration(new TeacherTeamConfig(schema)); 43 43 builder.ApplyConfiguration(new TeamConfig(schema)); 44 builder.ApplyConfiguration(new UpvoteConfig(schema));44 builder.ApplyConfiguration(new VoteConfig(schema)); 45 45 } 46 46 } -
src/FinkiChattery/FinkiChattery.Persistence/Models/Answer.cs
r806f4ee r728eb31 20 20 public DateTime CreatedOn { get; set; } 21 21 22 public long UpvotesCount { get; set; }22 public long VotesCount { get; set; } 23 23 24 public virtual ICollection< Upvote> Upvotes { get; set; }24 public virtual ICollection<Vote> Votes { get; set; } 25 25 26 26 public virtual ICollection<AnswerResponse> AnswerResponses { get; set; } -
src/FinkiChattery/FinkiChattery.Persistence/Models/Student.cs
r806f4ee r728eb31 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 1 using System.Collections.Generic; 6 2 7 3 namespace FinkiChattery.Persistence.Models … … 22 18 23 19 public virtual ICollection<Question> Questions { get; set; } 24 20 25 21 public virtual ICollection<Answer> Answers { get; set; } 26 22 27 23 public virtual ICollection<StudentTeam> StudentTeams { get; set; } 28 24 } -
src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Question/QuestionStateDto.cs
r806f4ee r728eb31 84 84 public class AnswerQuestionStateDto 85 85 { 86 public AnswerQuestionStateDto(long id, Guid uid, string text, bool correctAnswer, DateTime createdOn, long upvotesCount, AnswerStudentQuestionStateDto studentDto, IEnumerable<AnswerResponseQuestionStateDto> answerResponsesDto)86 public AnswerQuestionStateDto(long id, Guid uid, string text, bool correctAnswer, DateTime createdOn, long votesCount, AnswerStudentQuestionStateDto studentDto, IEnumerable<AnswerResponseQuestionStateDto> answerResponsesDto) 87 87 { 88 88 Id = id; … … 91 91 CorrectAnswer = correctAnswer; 92 92 CreatedOn = createdOn; 93 UpvotesCount = upvotesCount;93 VotesCount = votesCount; 94 94 StudentDto = studentDto; 95 95 AnswerResponsesDto = answerResponsesDto; … … 101 101 public bool CorrectAnswer { get; } 102 102 public DateTime CreatedOn { get; } 103 public long UpvotesCount { get; }103 public long VotesCount { get; } 104 104 public AnswerStudentQuestionStateDto StudentDto { get; } 105 105 public IEnumerable<AnswerResponseQuestionStateDto> AnswerResponsesDto { get; } -
src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/QuestionRepo.cs
r806f4ee r728eb31 80 80 y.CorrectAnswer, 81 81 y.CreatedOn, 82 y. UpvotesCount,82 y.VotesCount, 83 83 new AnswerStudentQuestionStateDto( 84 84 y.Student.Id, -
src/FinkiChattery/FinkiChattery.Persistence/UnitOfWork/Contracts/IUnitOfWork.cs
r806f4ee r728eb31 11 11 IStudentRepo Students { get; } 12 12 ITeamRepo Teams { get; } 13 IVoteRepo Votes { get; } 14 IAnswerRepo Answers { get; } 13 15 Task<int> SaveAsync(); 14 16 } -
src/FinkiChattery/FinkiChattery.Persistence/UnitOfWork/Implementations/UnitOfWork.cs
r806f4ee r728eb31 12 12 private StudentRepo _students; 13 13 private TeamRepo _teams; 14 private VoteRepo _votes; 15 private AnswerRepo _answers; 14 16 15 17 public UnitOfWork(ApplicationDbContext dbContext) … … 70 72 } 71 73 74 public IVoteRepo Votes 75 { 76 get 77 { 78 if (_votes == null) 79 { 80 _votes = new VoteRepo(DbContext); 81 } 82 83 return _votes; 84 } 85 } 86 87 public IAnswerRepo Answers 88 { 89 get 90 { 91 if (_answers == null) 92 { 93 _answers = new AnswerRepo(DbContext); 94 } 95 96 return _answers; 97 } 98 } 99 72 100 public ApplicationDbContext DbContext { get; } 73 101
Note:
See TracChangeset
for help on using the changeset viewer.