Changes in / [806f4ee:728eb31]


Ignore:
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  
    22import { Injectable } from '@angular/core';
    33import { Action, Store } from '@ngrx/store';
    4 import { Observable, Subject, throwError } from 'rxjs';
    5 import { catchError, filter, map } from 'rxjs/operators';
     4import { Observable, Subject } from 'rxjs';
     5import { filter } from 'rxjs/operators';
    66
    77import {
     
    99  PreviewQuestionViewModel,
    1010  QuestionStateViewModel,
    11   SearchQuestionsQueryViewModel
     11  SearchQuestionsQueryViewModel,
     12  VoteType
    1213} from 'src/app/shared-app/models';
    1314import {
     
    1617  GetPreviewQuestionsPopular,
    1718  GetQuestionState,
    18   GetSearchQuestions
     19  GetSearchQuestions,
     20  VoteAnswer
    1921} from './question-state/question.actions';
    2022import { questionStateQuery } from './question-state/question.selectors';
     
    3032
    3133  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));
    4535  }
    4636
     
    8171  }
    8272
     73  public voteAnswer(answerUid: string, questionUid: string, voteType: VoteType): void {
     74    this.dispatchEffect(new VoteAnswer(questionUid, answerUid, voteType));
     75  }
     76
    8377  public fetchQuestion(questionUid: string): void {
    8478    this.dispatchEffect(new GetQuestionState(questionUid));
  • src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.actions.ts

    r806f4ee r728eb31  
    22import { Action } from '@ngrx/store';
    33
    4 import { PreviewQuestionViewModel, QuestionStateViewModel, SearchQuestionsQueryViewModel } from 'src/app/shared-app/models';
     4import {
     5  PreviewQuestionViewModel,
     6  QuestionStateViewModel,
     7  SearchQuestionsQueryViewModel,
     8  VoteAnswerViewModel,
     9  VoteType
     10} from 'src/app/shared-app/models';
    511
    612export enum QuestionActionTypes {
     
    1319  GetSearchQuestions = '[Question] Get search questions',
    1420  GetSearchQuestionsSuccess = '[Question] Get search questions Success',
     21  VoteAnswer = '[Question] Vote answer',
     22  VoteAnswerSuccess = '[Question] Vote answer Success',
    1523  EffectStartedWorking = '[Question] Effect Started Working',
    1624  EffectFinishedWorking = '[Question] Effect Finished Working',
     
    6674}
    6775
     76export class VoteAnswer implements Action {
     77  readonly type = QuestionActionTypes.VoteAnswer;
     78
     79  constructor(public questionUid: string, public answerUid: string, public voteType: VoteType) {}
     80}
     81
     82export class VoteAnswerSuccess implements Action {
     83  readonly type = QuestionActionTypes.VoteAnswerSuccess;
     84
     85  constructor(public payload: VoteAnswerViewModel) {}
     86}
     87
    6888export class EffectStartedWorking implements Action {
    6989  readonly type = QuestionActionTypes.EffectStartedWorking;
     
    89109  | GetPreviewQuestionsPopularSuccess
    90110  | GetSearchQuestionsSuccess
     111  | VoteAnswerSuccess
    91112  | EffectStartedWorking
    92113  | EffectFinishedWorking
  • src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.effects.ts

    r806f4ee r728eb31  
    77import { BaseApiService } from 'src/app/shared-app/services/base-api.service';
    88import { QuestionFacadeService } from '../question-facade.service';
    9 import { PreviewQuestionResponse, QuestionStateResponse } from './question-state.models';
     9import { VoteAnswerRequest } from './question-state-request.models';
     10import { PreviewQuestionResponse, QuestionStateResponse, VoteAnswerResponse } from './question-state-response.models';
    1011import {
    1112  EffectFinishedWorking,
     
    1920  GetSearchQuestions,
    2021  GetSearchQuestionsSuccess,
    21   QuestionActionTypes
     22  QuestionActionTypes,
     23  VoteAnswer,
     24  VoteAnswerSuccess
    2225} from './question.actions';
    2326import { QuestionMapper } from './question.mapper';
     
    103106    );
    104107  });
     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  });
    105121}
  • src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.mapper.ts

    r806f4ee r728eb31  
    1010  QuestionStateViewModel,
    1111  StudentQuestionStateViewModel,
    12   TeamQuestionStateViewModel
     12  TeamQuestionStateViewModel,
     13  VoteAnswerViewModel
    1314} from 'src/app/shared-app/models';
    1415import { TranslateFromJsonService } from 'src/app/shared-app/services';
    15 import { PreviewQuestionResponse, QuestionStateResponse } from './question-state.models';
     16import { PreviewQuestionResponse, QuestionStateResponse, VoteAnswerResponse } from './question-state-response.models';
    1617
    1718export class QuestionMapper {
     
    5152          x.correctAnswer,
    5253          moment(x.createdOn),
    53           x.upvotesCount,
     54          x.votesCount,
    5455          answerStudent,
    5556          answerResponses
     
    113114    return questions;
    114115  }
     116
     117  public static ToVoteAnswerViewModel(response: VoteAnswerResponse): VoteAnswerViewModel {
     118    return new VoteAnswerViewModel(response.answerUid, response.voteUid, response.voteType);
     119  }
    115120}
  • src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.reducers.ts

    r806f4ee r728eb31  
     1import { VoteType } from 'src/app/shared-app/models';
    12import { QuestionAction, QuestionActionTypes } from './question.actions';
    23import { initialState, QuestionState } from './question.state';
     
    2526        searchQuestionsQuery: action.query
    2627      };
     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    }
    2763    case QuestionActionTypes.EffectStartedWorking: {
    2864      return {
  • src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.ts

    r806f4ee r728eb31  
    11import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
     2import { VoteType } from 'src/app/shared-app/models';
    23import { ButtonType } from '../button/button.models';
    3 
    4 export enum VoteType {
    5   Upvote,
    6   Downvote
    7 }
    84
    95@Component({
  • src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.html

    r806f4ee r728eb31  
    1414      <mat-card-content>
    1515        <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>
    1722          <div fxFlex="92%">
    1823            <app-text-editor
  • src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.ts

    r806f4ee r728eb31  
     1import { HttpErrorResponse } from '@angular/common/http';
    12import { Component, OnInit } from '@angular/core';
     3import { NotificationService } from 'src/app/core/services/notification.service';
    24import { QuestionFacadeService } from 'src/app/core/state/question-facade.service';
    35
    4 import { QuestionStateViewModel } from 'src/app/shared-app/models';
     6import { QuestionStateViewModel, VoteType } from 'src/app/shared-app/models';
    57import { ButtonType } from '../../generic/button/button.models';
    68
     
    1416  working = true;
    1517  ButtonType = ButtonType;
    16   constructor(private questionFacade: QuestionFacadeService) {}
     18  constructor(private questionFacade: QuestionFacadeService, private notification: NotificationService) {}
    1719
    1820  ngOnInit(): void {
     
    2123      this.working = false;
    2224    });
     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);
    2335  }
    2436}
  • src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-enums.models.ts

    r806f4ee r728eb31  
    33  Popular
    44}
     5
     6export 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  
     1import { VoteType } from '.';
     2
    13export class QuestionStateViewModel {
    24  constructor(
     
    3234    public correctAnswer: boolean,
    3335    public createdOn: moment.Moment,
    34     public upvotesCount: number,
     36    public votesCount: number,
    3537    public student: AnswerStudentQuestionStateViewModel,
    3638    public answerResponses: AnswerResponseQuestionStateViewModel[]
     
    7375  constructor(public text: string) {}
    7476}
     77
     78export 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  
    5353  "ask-question-stepper-ask": "Ask question",
    5454  "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"
    5659}
  • src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/Mapper/QuestionMapper.cs

    r806f4ee r728eb31  
    5454                    var answerStudent = new AnswerStudentQuestionStateResponse(x.StudentDto.Id, x.StudentDto.Uid, x.StudentDto.Index, x.StudentDto.ImageUrl, x.StudentDto.Reputation);
    5555
    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);
    5757                });
    5858            }
  • src/FinkiChattery/FinkiChattery.Api/Services/RegisterServices.cs

    r806f4ee r728eb31  
    11using FinkiChattery.Api.ApplicationServices.Authentication;
     2using FinkiChattery.Api.ApplicationServices.Questioning.EventHandlers;
    23using FinkiChattery.Api.Services;
    34using FinkiChattery.Commands.Questioning;
     
    3132            services.AddScoped<IEventService, EventService>();
    3233            services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
    33             services.AddMediatR(typeof(AskQuestionCommand), typeof(GetQuestionStateQuery));
     34            services.AddMediatR(typeof(AskQuestionCommand), typeof(GetQuestionStateQuery), typeof(UpdateAnswerVotesEventHandler));
    3435        }
    3536
     
    5455            });
    5556            services.AddHangfireServer();
     57
     58            services.AddScoped<IBackgroundJobClient>(provider =>
     59            {
     60                return new BackgroundJobClient(JobStorage.Current);
     61            });
    5662        }
    5763
  • src/FinkiChattery/FinkiChattery.Commands/Questioning/QuestioningErrorCodes.cs

    r806f4ee r728eb31  
    99        public const string CategoriesDontExist = "CategoriesDontExist";
    1010        public const string TeamDontExist = "TeamDontExist";
     11        public const string AnswerAlreadyUpvoted = "AnswerAlreadyUpvoted";
     12        public const string AnswerAlreadyDownvoted = "AnswerAlreadyDownvoted";
     13        public const string StudentHasBadReputation = "StudentHasBadReputation";
    1114    }
    1215}
  • src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/CategoriesUidsExist.cs

    r806f4ee r728eb31  
    1 using FinkiChattery.Persistence.Repositories;
    2 using FinkiChattery.Persistence.UnitOfWork;
     1using FinkiChattery.Persistence.UnitOfWork;
    32using FluentValidation.Validators;
    43using System;
  • src/FinkiChattery/FinkiChattery.Contracts/Questioning/GetQuestionState/QuestionStateResponse.cs

    r806f4ee r728eb31  
    8989    public class AnswerQuestionStateResponse
    9090    {
    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)
    9292        {
    9393            Id = id;
     
    9696            CorrectAnswer = correctAnswer;
    9797            CreatedOn = createdOn;
    98             UpvotesCount = upvotesCount;
     98            VotesCount = votesCount;
    9999            StudentResponse = studentResponse;
    100100            AnswerResponsesResponse = answerResponsesResponse;
     
    107107        public bool CorrectAnswer { get; }
    108108        public DateTime CreatedOn { get; }
    109         public long UpvotesCount { get; }
     109        public long VotesCount { get; }
    110110        public AnswerStudentQuestionStateResponse StudentResponse { get; }
    111111        public IEnumerable<AnswerResponseQuestionStateResponse> AnswerResponsesResponse { get; }
  • src/FinkiChattery/FinkiChattery.Database/FinkiChattery.Database.sqlproj

    r806f4ee r728eb31  
    7575    <Folder Include="dbo\Tables\QuestionCategory" />
    7676    <Folder Include="Snapshots" />
     77    <Folder Include="dbo\Tables\Vote" />
    7778  </ItemGroup>
    7879  <ItemGroup>
     
    8182    <Build Include="dbo\Tables\StudentTeam.sql" />
    8283    <Build Include="dbo\Tables\TeacherTeam.sql" />
    83     <Build Include="dbo\Tables\Upvote.sql" />
    8484    <Build Include="dbo\Tables\User\AspNetRoleClaims.sql" />
    8585    <Build Include="dbo\Tables\User\AspNetRoles.sql" />
     
    100100    <Build Include="dbo\Tables\QuestionCategory\QuestionCategory.sql" />
    101101    <None Include="dbo\Tables\QuestionCategory\QuestionCategory.Debug.Seed.sql" />
     102    <Build Include="dbo\Tables\Vote\Vote.sql" />
    102103  </ItemGroup>
    103104  <ItemGroup>
  • src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Answer/Answer.Debug.Seed.sql

    r806f4ee r728eb31  
    1212            (3, N'cee193c3-9d36-4ed8-81b2-15eb4ff305f1', N'Answer 3', 2, 1, 1, GETUTCDATE(), 5),
    1313            (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])
    1515    ) AS S
    1616    ON T.[ID] = S.[ID]
     
    2121                   T.[StudentFk] = S.[StudentFk],
    2222                   T.[CorrectAnswer] = S.[CorrectAnswer],
    23                    T.[UpvotesCount] = S.[UpvotesCount]
     23                   T.[VotesCount] = S.[VotesCount]
    2424    WHEN NOT MATCHED THEN
    2525        INSERT
     
    3232            [CorrectAnswer],
    3333            [CreatedOn],
    34             [UpvotesCount]
     34            [VotesCount]
    3535        )
    3636        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]);
    3838    SET IDENTITY_INSERT [dbo].[Answer] OFF
    3939END
  • src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Answer/Answer.sql

    r806f4ee r728eb31  
    77    [CorrectAnswer] BIT              NOT NULL,
    88    [CreatedOn]     SMALLDATETIME    NOT NULL,
    9     [UpvotesCount] BIGINT NOT NULL DEFAULT 0,
     9    [VotesCount] BIGINT NOT NULL DEFAULT 0,
    1010    CONSTRAINT [PK_Answer] PRIMARY KEY CLUSTERED ([Id] ASC),
    1111    CONSTRAINT [FK_Answer_Question_QuestionFk] FOREIGN KEY ([QuestionFk]) REFERENCES [dbo].[Question] ([Id]),
  • src/FinkiChattery/FinkiChattery.Persistence/Configurations/AnswerConfig.cs

    r806f4ee r728eb31  
    2222            builder.Property(x => x.CorrectAnswer).HasColumnName(@"CorrectAnswer").HasColumnType("bit").IsRequired();
    2323            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);
    2525
    2626            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  
    2323        public DbSet<TeacherTeam> TeacherTeams { get; set; }
    2424        public DbSet<Team> Teams { get; set; }
    25         public DbSet<Upvote> Upvotes { get; set; }
     25        public DbSet<Vote> Votes { get; set; }
    2626
    2727        protected override void OnModelCreating(ModelBuilder builder)
     
    4242            builder.ApplyConfiguration(new TeacherTeamConfig(schema));
    4343            builder.ApplyConfiguration(new TeamConfig(schema));
    44             builder.ApplyConfiguration(new UpvoteConfig(schema));
     44            builder.ApplyConfiguration(new VoteConfig(schema));
    4545        }
    4646    }
  • src/FinkiChattery/FinkiChattery.Persistence/Models/Answer.cs

    r806f4ee r728eb31  
    2020        public DateTime CreatedOn { get; set; }
    2121
    22         public long UpvotesCount { get; set; }
     22        public long VotesCount { get; set; }
    2323
    24         public virtual ICollection<Upvote> Upvotes { get; set; }
     24        public virtual ICollection<Vote> Votes { get; set; }
    2525
    2626        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;
     1using System.Collections.Generic;
    62
    73namespace FinkiChattery.Persistence.Models
     
    2218
    2319        public virtual ICollection<Question> Questions { get; set; }
    24        
     20
    2521        public virtual ICollection<Answer> Answers { get; set; }
    26        
     22
    2723        public virtual ICollection<StudentTeam> StudentTeams { get; set; }
    2824    }
  • src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Question/QuestionStateDto.cs

    r806f4ee r728eb31  
    8484    public class AnswerQuestionStateDto
    8585    {
    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)
    8787        {
    8888            Id = id;
     
    9191            CorrectAnswer = correctAnswer;
    9292            CreatedOn = createdOn;
    93             UpvotesCount = upvotesCount;
     93            VotesCount = votesCount;
    9494            StudentDto = studentDto;
    9595            AnswerResponsesDto = answerResponsesDto;
     
    101101        public bool CorrectAnswer { get; }
    102102        public DateTime CreatedOn { get; }
    103         public long UpvotesCount { get; }
     103        public long VotesCount { get; }
    104104        public AnswerStudentQuestionStateDto StudentDto { get; }
    105105        public IEnumerable<AnswerResponseQuestionStateDto> AnswerResponsesDto { get; }
  • src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/QuestionRepo.cs

    r806f4ee r728eb31  
    8080                                                    y.CorrectAnswer,
    8181                                                    y.CreatedOn,
    82                                                     y.UpvotesCount,
     82                                                    y.VotesCount,
    8383                                                    new AnswerStudentQuestionStateDto(
    8484                                                        y.Student.Id,
  • src/FinkiChattery/FinkiChattery.Persistence/UnitOfWork/Contracts/IUnitOfWork.cs

    r806f4ee r728eb31  
    1111        IStudentRepo Students { get; }
    1212        ITeamRepo Teams { get; }
     13        IVoteRepo Votes { get; }
     14        IAnswerRepo Answers { get; }
    1315        Task<int> SaveAsync();
    1416    }
  • src/FinkiChattery/FinkiChattery.Persistence/UnitOfWork/Implementations/UnitOfWork.cs

    r806f4ee r728eb31  
    1212        private StudentRepo _students;
    1313        private TeamRepo _teams;
     14        private VoteRepo _votes;
     15        private AnswerRepo _answers;
    1416
    1517        public UnitOfWork(ApplicationDbContext dbContext)
     
    7072        }
    7173
     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
    72100        public ApplicationDbContext DbContext { get; }
    73101
Note: See TracChangeset for help on using the changeset viewer.