[Fact]
public void AgeInYears_PersonBorn1970_AfterBirthdateIn2019_45()
{
var age = AgeInYears.Between
(new DateTime(1970, 6, 26),
new DateTime(2019, 11, 28));
age.Should().Be(49.Years());
}
[Fact]
public void AgeInYears_PersonBorn1980_BeforeBirthdateIn2021_41()
{
var age = AgeInYears.Between(new DateTime(1980, 6, 26),
new DateTime(2021, 5, 28));
age.Should().Be(41.Years());
}
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "Categories" (
"ID" INTEGER NOT NULL UNIQUE,
"UniqueId" TEXT NOT NULL,
"Version" INTEGER NOT NULL,
"DisplayName" TEXT,
"Name" TEXT,
"WhatWeAreLookingFor" TEXT,
PRIMARY KEY("ID" AUTOINCREMENT)
);
CREATE TABLE IF NOT EXISTS "CallForSpeakes" (
"Id" INTEGER NOT NULL UNIQUE,
"UniqueId" TEXT NOT NULL,
"Version" INTEGER NOT NULL,
"Number" TEXT NOT NULL,
"Status" INTEGER NOT NULL,
"PreliminaryDecision_DecisionBy" NUMERIC,
"PreliminaryDecision_Date" TEXT,
"FinalDecision_DecisionBy" INTEGER,
"FinalDecision_Date" TEXT,
"Speaker_Name_First" TEXT NOT NULL,
"Speaker_Name_Last" TEXT NOT NULL,
"Speaker_Adress_Country" TEXT NOT NULL,
"Speaker_Adress_ZipCode" TEXT NOT NULL,
"Speaker_Adress_City" TEXT NOT NULL,
"Speaker_Adress_Street" TEXT NOT NULL,
"Speaker_Websites_Facebook" TEXT,
"Speaker_Websites_Twitter" TEXT,
"Speaker_Websites_Instagram" TEXT,
"Speaker_Websites_LinkedIn" TEXT,
"Speaker_Websites_TikTok" TEXT,
"Speaker_Websites_Youtube" REAL,
"Speaker_Websites_FanPageOnFacebook" REAL,
"Speaker_Websites_GitHub" TEXT,
"Speaker_Websites_Blog" TEXT,
"Speaker_BIO" TEXT NOT NULL,
"Speaker_Contact_Phone" TEXT,
"Speaker_Contact_Email" TEXT NOT NULL,
"Speaker_Birthdate" TEXT,
"Speech_Title" TEXT NOT NULL,
"Speech_Description" TEXT NOT NULL,
"Speech_Tags" TEXT NOT NULL,
"Speech_ForWhichAudience" INTEGER NOT NULL,
"Speech_TechnologyOrBussinessStory" INTEGER NOT NULL,
"Registration_RegistrationDate" TEXT,
"CategoryId" INTEGER NOT NULL,
"Score_Score" INTEGER,
"Score_RejectExplanation" TEXT,
"Score_WarringExplanation" TEXT,
CONSTRAINT "FK_JudgeID_CallForSpeech_PreminaryDecision_DecysionBy" FOREIGN KEY("PreliminaryDecision_DecisionBy") REFERENCES "Judges",
CONSTRAINT "FK_CategoryID_CallForSpeakes" FOREIGN KEY("CategoryId") REFERENCES "Categories",
CONSTRAINT "FK_JudgeID_CallForSpeech_FinalDecision_DecysionBy" FOREIGN KEY("FinalDecision_DecisionBy") REFERENCES "Judges",
CONSTRAINT "PK_CallForSpeakes_PK" PRIMARY KEY("Id" AUTOINCREMENT)
);
CREATE TABLE IF NOT EXISTS "Judges" (
"ID" INTEGER NOT NULL UNIQUE,
"UniqueId" TEXT NOT NULL,
"Version" INTEGER NOT NULL,
"Login" TEXT NOT NULL,
"Password" TEXT NOT NULL,
"BirthDate" NUMERIC NOT NULL,
"Name_First" TEXT NOT NULL,
"Name_Last" TEXT NOT NULL,
"CategoryID" INTEGER NOT NULL,
CONSTRAINT "FK_CategoryId_Judges" FOREIGN KEY("CategoryID") REFERENCES "Categories",
CONSTRAINT "PK_Judges_KEY" PRIMARY KEY("ID" AUTOINCREMENT)
);
CREATE UNIQUE INDEX IF NOT EXISTS "CategoryID_Index" ON "Categories" (
"ID" DESC
);
CREATE UNIQUE INDEX IF NOT EXISTS "JudgesID_Index" ON "Judges" (
"ID" DESC
);
COMMIT;
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>
public class AppTime
{
public static Func<DateTime> CurrentTimeProvider
{ get; set; } = () => DateTime.Now;
public static DateTime Now() => CurrentTimeProvider();
}
public abstract class ValueObject<T> where T : ValueObject<T>
{
protected abstract IEnumerable<object> GetAttributesToIncludeInEqualityCheck();
public override bool Equals(object other)
{
return Equals(other as T);
}
public virtual bool Equals(T other)
{
if (other == null)
{
return false;
}
return GetAttributesToIncludeInEqualityCheck().SequenceEqual(other.GetAttributesToIncludeInEqualityCheck());
}
public static bool operator ==(ValueObject<T> left, ValueObject<T> right)
{
return Equals(left, right);
}
public static bool operator !=(ValueObject<T> left, ValueObject<T> right)
{
return !(left == right);
}
public override int GetHashCode()
{
var hash = 19;
foreach (var obj in this.GetAttributesToIncludeInEqualityCheck())
hash = hash * 31 + (obj == null ? 0 : obj.GetHashCode());
return hash;
}
}
public abstract class Entity<T1, T2>
{
public T1 Id { get; protected set; }
public T2 UniqueId { get; set; }
public int Version { get; set; }
//public string CreatedBy { get; set; }
//public DateTime CreatedDate { get; set; }
//public string LastModifiedBy { get; set; }
//public DateTime? LastModifiedDate { get; set; }
}
public abstract class Entity<T>
{
public T Id { get; protected set; }
//public Guid UniqueId { get; set; }
public int Version { get; set; }
//public string CreatedBy { get; set; }
//public DateTime CreatedDate { get; set; }
//public string LastModifiedBy { get; set; }
//public DateTime? LastModifiedDate { get; set; }
}
public abstract class Entity<T1, T2>
{
public T1 Id { get; protected set; }
public T2 UniqueId { get; set; }
public int Version { get; set; }
}
public class Category : Entity<CategoryId, CategoryUniqueId>
{
public string Name { get; init; }
public string DisplayName { get; init; }
public string WhatWeAreLookingFor { get; init; }
public Category(CategoryId Id, string name, string displayName,
string whatWeAreLookingFor) : base()
{
this.Id = Id;
Name = name;
DisplayName = displayName;
UniqueId = CategoryUniqueId.NewUniqueId();
WhatWeAreLookingFor = whatWeAreLookingFor;
}
//tylko do testów
public void InjectUniqueId(CategoryUniqueId uniqueId)
{
this.UniqueId = uniqueId;
}
public Category(CategoryId Id)
{
this.Id = Id;
UniqueId = CategoryUniqueId.NewUniqueId();
}
public Category()
{
UniqueId = CategoryUniqueId.NewUniqueId();
this.Id = CategoryId.Empty();
}
public CategoryIds Ids()
{
if (this.Id != null && this.Id.Value != default)
return new CategoryIds()
{
UniqueId = this.UniqueId,
CreatedId = this.Id
};
else
return new CategoryIds()
{
UniqueId = this.UniqueId,
CreatedId = this.Id,
Status = IdsStatus.DudeYouCantReturnCreatedIdWhenYouAreEventSourcing
};
}
}
public abstract class BaseId<T> : ValueObject<T>
where T : ValueObject<T>
{
public BaseId()
{
}
}
public class CategoryId : BaseId<CategoryId>
{
public int Value { get; set; }
public CategoryId(int value)
{
Value = value;
}
public CategoryId()
{
}
protected override IEnumerable<object>
GetAttributesToIncludeInEqualityCheck()
{
yield return Value;
}
public static CategoryId Empty()
{
return new CategoryId(0);
}
}
public abstract class BaseUniqueId<T> :
ValueObject<T> where T : ValueObject<T>
{
public abstract string ValueInString();
protected abstract string GetName();
public AggregateKey GetAggregateKey()
{
return new AggregateKey
{
Id = ValueInString(),
Type = GetName()
};
}
public BaseUniqueId()
{
}
}
public class AggregateKey : ValueObject<AggregateKey>
{
public string Type { get; set; }
public string Id { get; set; }
protected override IEnumerable<object>
GetAttributesToIncludeInEqualityCheck()
{
yield return Type;
yield return Id;
}
public static readonly AggregateKey Empty = new AggregateKey();
public override string ToString()
{
return Id;
}
}
public class CategoryUniqueId : BaseUniqueId<CategoryUniqueId>
{
public Guid Value { get; set; }
public CategoryUniqueId(Guid value)
{
Value = value;
}
//[JsonConstructor]
public CategoryUniqueId()
{
Value = Guid.NewGuid();
}
public static CategoryUniqueId Empty()
{
return new CategoryUniqueId(Guid.Empty);
}
protected override IEnumerable<object> GetAttributesToIncludeInEqualityCheck()
{
yield return Value;
}
public static CategoryUniqueId NewUniqueId()
{
return new CategoryUniqueId();
}
protected override string GetName()
{
return "Category";
}
public override string ValueInString() => Value.ToString();
}
public class Ids<T1, UniqueT2> where T1 : ValueObject<T1>
where UniqueT2 : ValueObject<UniqueT2>
{
public BaseId<T1> CreatedId { get; set; }
public BaseUniqueId<UniqueT2> UniqueId { get; set; }
public IdsStatus Status { get; set; }
}
public enum IdsStatus
{
CreateIdReturned = 0,
DudeYouCantReturnCreatedIdWhenYouAreEventSourcing = 1
}
public class CallForSpeechIds : Ids<CallForSpeechId, CallForSpeechUniqueId>
{
}
public class JudgeIds : Ids<JudgeId, JudgeUniqueId>
{
}
public class CategoryIds : Ids<CategoryId, CategoryUniqueId>
{
}
public abstract class Entity<T1, T2>
{
public T1 Id { get; protected set; }
public T2 UniqueId { get; set; }
public int Version { get; set; }
}
public class Category : Entity<CategoryId, CategoryUniqueId>
{
public string Name { get; init; }
public string DisplayName { get; init; }
public string WhatWeAreLookingFor { get; init; }
public Category(CategoryId Id, string name, string displayName,
string whatWeAreLookingFor) : base()
{
this.Id = Id;
Name = name;
DisplayName = displayName;
UniqueId = CategoryUniqueId.NewUniqueId();
WhatWeAreLookingFor = whatWeAreLookingFor;
}
//tylko do testów
//dobrze by było zaracać nową klasę
public void InjectUniqueId(CategoryUniqueId uniqueId)
{
this.UniqueId = uniqueId;
}
public Category(CategoryId Id)
{
this.Id = Id;
UniqueId = CategoryUniqueId.NewUniqueId();
}
public Category()
{
UniqueId = CategoryUniqueId.NewUniqueId();
this.Id = CategoryId.Empty();
}
public CategoryIds Ids()
{
if (this.Id != null && this.Id.Value != default)
return new CategoryIds()
{
UniqueId = this.UniqueId,
CreatedId = this.Id
};
else
return new CategoryIds()
{
UniqueId = this.UniqueId,
CreatedId = this.Id,
Status = IdsStatus.DudeYouCantReturnCreatedIdWhenYouAreEventSourcing
};
}
}
public abstract class Entity<T1, T2>
{
public T1 Id { get; protected set; }
public T2 UniqueId { get; set; }
public int Version { get; set; }
}
public class Judge : Entity<JudgeId, JudgeUniqueId>
{
public Login Login { get; init; }
public Password Password { get; init; }
public Name Name { get; init; }
public Category Category { get; init; }
//Stworzenie listy właściwości był debilnym pomysłem
//public List<Email> Emails { get; set; }
public DateTime Birthdate { get; set; }
public Judge(Login login, Password password, Name name, Category category)
{
Id = new JudgeId(0);
Login = login;
Password = password;
Name = name;
Category = category;
UniqueId = JudgeUniqueId.NewUniqueId();
Version = 0;
}
public Judge(int id, Login login, Password password, Name name, Category category)
{
Id = new JudgeId(id);
Login = login;
Password = password;
Name = name;
Category = category;
UniqueId = JudgeUniqueId.NewUniqueId();
Version = 0;
}
//To satisfy EF Core
public Judge()
{
UniqueId = JudgeUniqueId.NewUniqueId();
Version = 0;
}
public bool CanAccept(CategoryId categoryId)
{
if (Category != null)
return categoryId == Category.Id;
return false;
}
public AgeInYears AgeInYearsAt(DateTime date)
{
return AgeInYears.Between(Birthdate, date);
}
public JudgeIds Ids()
{
if (this.Id != null && this.Id.Value != default)
return new JudgeIds()
{
UniqueId = this.UniqueId,
CreatedId = this.Id
};
else
return new JudgeIds()
{
UniqueId = this.UniqueId,
CreatedId = this.Id,
Status = IdsStatus.DudeYouCantReturnCreatedIdWhenYouAreEventSourcing
};
}
}
public bool CanAccept(CategoryId categoryId)
{
if (Category != null)
return categoryId == Category.Id;
return false;
}
public AgeInYears AgeInYearsAt(DateTime date)
{
return AgeInYears.Between(Birthdate, date);
}
public class AgeInYears : ValueObject<AgeInYears>,
IComparable<AgeInYears>
{
private readonly int age;
public int Age
{
get { return age; }
}
public AgeInYears(int age)
{
this.age = age;
}
public static AgeInYears Between(DateTime start, DateTime end)
{
return new AgeInYears(end.Year - start.Year);
}
protected override IEnumerable<object> GetAttributesToIncludeInEqualityCheck()
{
yield return age;
}
public static bool operator >(AgeInYears one, AgeInYears two) => one.CompareTo(two) > 0;
public static bool operator <(AgeInYears one, AgeInYears two) => one.CompareTo(two) < 0;
public static bool operator >=(AgeInYears one, AgeInYears two) => one.CompareTo(two) >= 0;
public static bool operator <=(AgeInYears one, AgeInYears two) => one.CompareTo(two) <= 0;
public int CompareTo(AgeInYears other)
{
return this.age.CompareTo(other.age);
}
}
public static class AgeInYearsExtensions
{
public static AgeInYears Years(this int age)
=> new AgeInYears(age);
}
public class Judge : Entity<JudgeId, JudgeUniqueId>
{
public Login Login { get; init; }
public Password Password { get; init; }
public Name Name { get; init; }
public Category Category { get; init; }
public DateTime Birthdate { get; set; }
public class Login : ValueObject<Login>
{
public string Value { get; }
public Login(string value)
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("Login cannot be null or empty string");
Value = value;
}
public static Login Of(string login) => new Login(login);
public static implicit operator string(Login login) => login.Value;
public override string ToString()
{
return Value;
}
protected override IEnumerable<object> GetAttributesToIncludeInEqualityCheck()
{
yield return Value;
}
}
public class Password : ValueObject<Password>
{
public string Value { get; }
public Password(string value)
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("Password cannot be null or empty string");
Value = value;
}
public static Password Of(string value) => new Password(value);
public static implicit operator string(Password password) => password.Value;
protected override IEnumerable<object> GetAttributesToIncludeInEqualityCheck()
{
yield return Value;
}
}
public class Name : ValueObject<Name>
{
public Name(string first, string last)
{
if (string.IsNullOrWhiteSpace(first))
throw new ArgumentException("First name cannot be empty");
if (string.IsNullOrWhiteSpace(last))
throw new ArgumentException("First name cannot be empty");
First = first;
Last = last;
}
//Dla EF Core
protected Name()
{
}
public string First { get; }
public string Last { get; }
protected override IEnumerable<object> GetAttributesToIncludeInEqualityCheck()
{
yield return First;
yield return Last;
}
}
public abstract class Entity<T1, T2>
{
public T1 Id { get; protected set; }
public T2 UniqueId { get; set; }
public int Version { get; set; }
}
public class CallForSpeech : Entity<CallForSpeechId, CallForSpeechUniqueId>
{
public Speaker Speaker { get; set; }
public Speech Speech { get; set; }
public Registration Registration { get; set; }
public CallForSpeechNumber Number { get; set; }
public Category Category { get; private set; }
public CallForSpeechStatus Status { get; private set; }
public CallForSpeechScoringResult Score { get; private set; }
public Decision PreliminaryDecision { get; private set; }
public Decision FinalDecision { get; private set; }
public CallForSpeech(CallForSpeechNumber number, Speech speech,
Speaker speaker, Category cat)
: this(number, CallForSpeechStatus.New, speaker, speech, cat,
null, new Registration(AppTime.Now()), null, null,
new CallForSpeechId(0))
{
}
public CallForSpeech(
CallForSpeechNumber number,
CallForSpeechStatus status,
Speaker speaker,
Speech speech,
Category category,
CallForSpeechScoringResult score,
Registration registration,
Decision preliminaryDecision,
Decision finalDecision,
CallForSpeechId callForSpeechId)
{
if (category == null)
throw new ArgumentException("Category cannot be null");
if (number == null)
throw new ArgumentException("Number cannot be null");
if (speech == null)
throw new ArgumentException("speech cannot be null");
if (speaker == null)
throw new ArgumentException("speaker cannot be null");
if (registration == null)
throw new ArgumentException("Registration cannot be null");
Id = callForSpeechId;
Number = number;
Status = status;
Score = score;
Speech = speech;
Speaker = speaker;
Registration = registration;
PreliminaryDecision = preliminaryDecision;
FinalDecision = finalDecision;
Category = category;
Version = 0;
UniqueId = CallForSpeechUniqueId.NewUniqueId();
}
// Dla EF Core jeśli używany
protected CallForSpeech()
{
UniqueId = CallForSpeechUniqueId.NewUniqueId();
Version = 0;
}
public void Evaluate(ScoringRules rules)
{
if (Status != CallForSpeechStatus.New)
{
throw new ApplicationException
("Cannot accept application that isn't new");
}
Score = rules.Evaluate(this);
if (!Score.IsRed())
{
Status = CallForSpeechStatus.EvaluatedByMachine;
}
else
{
Status = CallForSpeechStatus.Rejected;
}
}
public void PreliminaryAccept(Judge decisionBy)
{
if (Status == CallForSpeechStatus.PreliminaryAcceptedByJudge)
{
throw new ApplicationException
("You already PreliminaryAcceptedByJudge this CallForSpeech");
}
if (Status != CallForSpeechStatus.EvaluatedByMachine)
{
throw new ApplicationException
("Cannot accept application that WASNT'T in EvaluatedByMachine");
}
if (Score == null)
{
throw new ApplicationException
("Cannot accept application before scoring");
}
if (!decisionBy.CanAccept(this.Category.Id))
{
throw new ApplicationException
("Judge is from diffrent category. Can't Accept");
}
Status = CallForSpeechStatus.PreliminaryAcceptedByJudge;
PreliminaryDecision = new Decision(AppTime.Now(), decisionBy);
}
public void Accept(Judge decisionBy)
{
if (Status == CallForSpeechStatus.AcceptedByJudge)
{
throw new ApplicationException
("You already Accepted this CallForSpeech");
}
if (Status == CallForSpeechStatus.Rejected)
{
throw new ApplicationException
("Cannot accept application that is already rejected");
}
if (Status != CallForSpeechStatus.PreliminaryAcceptedByJudge)
{
throw new ApplicationException
("Cannot accept application that wasn't PreliminaryAccepted FIRST");
}
if (Score == null)
{
throw new ApplicationException
("Cannot accept application before scoring");
}
if (!decisionBy.CanAccept(this.Category.Id))
{
throw new ApplicationException
("Judge is from diffrent category. Can't Accept");
}
Status = CallForSpeechStatus.AcceptedByJudge;
FinalDecision = new Decision(AppTime.Now(), decisionBy);
}
public void Reject(Judge decisionBy)
{
if (Status == CallForSpeechStatus.Rejected ||
Status == CallForSpeechStatus.AcceptedByJudge)
{
throw new ApplicationException
("Cannot reject application that is already accepted or rejected");
}
if (!decisionBy.CanAccept(this.Category.Id))
{
throw new ApplicationException
("Judge is from diffrent category. Can't Accept");
}
Status = CallForSpeechStatus.Rejected;
FinalDecision = new Decision(AppTime.Now(), decisionBy);
}
public CallForSpeechIds Ids()
{
if (this.Id != null && this.Id.Value != default)
return new CallForSpeechIds()
{
UniqueId = this.UniqueId,
CreatedId = this.Id
};
else
return new CallForSpeechIds()
{
UniqueId = this.UniqueId,
CreatedId = this.Id,
Status = IdsStatus.DudeYouCantReturnCreatedIdWhenYouAreEventSourcing
};
}
}
public class Speaker : ValueObject<Speaker>
{
public DateTime Birthdate { get; init; }
public Name Name { get; init; }
public Address Address { get; init; }
public SpeakerWebsites SpeakerWebsites { get; init; }
public string Biography { get; init; }
public Contact Contact { get; init; }
public Speaker(Name name, DateTime birthdate,
Address address, SpeakerWebsites speakerWebsites, string biography,
Contact contact)
{
if (contact == null)
throw new ArgumentException("Contact cannot be null");
if (biography == null)
throw new ArgumentException("biography cannot be null");
if (name == null)
throw new ArgumentException("Name cannot be null");
if (address == null)
throw new ArgumentException("Address cannot be null");
if (birthdate == default)
throw new ArgumentException("Birthdate cannot be empty");
if (speakerWebsites == default)
throw new ArgumentException("SpeakerWebsites cannot be empty");
Name = name;
Birthdate = birthdate;
Address = address;
SpeakerWebsites = speakerWebsites;
Biography = biography;
Contact = contact;
}
public AgeInYears AgeInYearsAt(DateTime date)
{
return AgeInYears.Between(Birthdate, date);
}
protected Speaker()
{
}
protected override IEnumerable<object> GetAttributesToIncludeInEqualityCheck()
{
return new List<object>
{
Name,
Birthdate,
Address
};
}
}
public class SpeakerWebsites : ValueObject<SpeakerWebsites>
{
public string Facebook { get; init; }
public string LinkedIN { get; init; }
public string Twitter { get; init; }
public string Instagram { get; init; }
public string TikTok { get; init; }
public string YouTube { get; init; }
public string FanPageOnFacebook { get; init; }
public string GitHub { get; init; }
public string Blog { get; init; }
public SpeakerWebsites(string facebook = null, string linkedIN = null,
string twitter = null, string instagram = null, string tikTok = null,
string gitHub = null, string blog = null)
{
Facebook = facebook;
LinkedIN = linkedIN;
Twitter = twitter;
Instagram = instagram;
TikTok = tikTok;
GitHub = gitHub;
Blog = blog;
}
public SpeakerWebsites()
{
}
public bool HaveSocialMedia()
{
if (!string.IsNullOrWhiteSpace(Facebook)
|| !string.IsNullOrWhiteSpace(LinkedIN)
|| !string.IsNullOrWhiteSpace(Twitter)
|| !string.IsNullOrWhiteSpace(Instagram)
|| !string.IsNullOrWhiteSpace(TikTok)
|| !string.IsNullOrWhiteSpace(YouTube)
|| !string.IsNullOrWhiteSpace(FanPageOnFacebook))
return true;
return false;
}
public bool HaveGitHub()
{
if (!string.IsNullOrWhiteSpace(GitHub))
return true;
return false;
}
public bool HaveBlog()
{
if (!string.IsNullOrWhiteSpace(Blog))
return true;
return false;
}
protected override IEnumerable<object> GetAttributesToIncludeInEqualityCheck()
{
yield return Facebook;
yield return LinkedIN;
yield return Twitter;
yield return Instagram;
yield return TikTok;
yield return GitHub;
yield return Blog;
}
}
public class Contact : ValueObject<Contact>
{
public string Phone { get; }
public string Email { get; }
public Contact(string phone, string email)
{
if (phone == null)
throw new ArgumentException("phone cannot be null");
if (email == null)
throw new ArgumentException("email cannot be null");
Phone = phone;
Email = email;
}
protected Contact()
{
}
protected override IEnumerable<object> GetAttributesToIncludeInEqualityCheck()
{
return new List<object>
{
Phone,
Email
};
}
}
public class Address : ValueObject<Address>
{
public string Country { get; }
public string ZipCode { get; }
public string City { get; }
public string Street { get; }
public Address(string country, string zipCode, string city, string street)
{
if (string.IsNullOrWhiteSpace(country))
throw new ArgumentException("Country cannot be empty.");
if (string.IsNullOrWhiteSpace(zipCode))
throw new ArgumentException("Zip code cannot be empty.");
if (string.IsNullOrWhiteSpace(city))
throw new ArgumentException("City cannot be empty.");
if (string.IsNullOrWhiteSpace(street))
throw new ArgumentException("Street cannot be empty.");
if (!new Regex("[0-9]{2}-[0-9]{3}").Match(zipCode).Success)
throw new ArgumentException("Zip code must be NN-NNN format.");
Country = country;
ZipCode = zipCode;
City = city;
Street = street;
}
protected Address()
{
}
protected override IEnumerable<object> GetAttributesToIncludeInEqualityCheck()
{
yield return Country;
yield return ZipCode;
yield return City;
yield return Street;
}
}
public class Speech : ValueObject<Speech>
{
public string Title { get; init; }
public string Description { get; init; }
public string[] Tags { get; init; }
public ForWhichAudience ForWhichAudience { get; init; }
public TechnologyOrBussinessStory TechnologyOrBussinessStory { get; init; }
protected Speech()
{
}
public Speech(string title, string description, string[] tags,
ForWhichAudience forWhichAudience, TechnologyOrBussinessStory technologyOrBussinessStory)
{
Title = title;
Description = description;
Tags = tags;
ForWhichAudience = forWhichAudience;
TechnologyOrBussinessStory = technologyOrBussinessStory;
}
protected override IEnumerable<object> GetAttributesToIncludeInEqualityCheck()
{
return new List<object>
{
Title,
Description,
Tags
};
}
}
public enum ForWhichAudience
{
Beginers = 0,
Intermediate = 1,
Experts = 2,
GrandMasters = 3
}
public enum TechnologyOrBussinessStory
{
OnlyAboutTechnologyAndTricks = 0,
MoreAboutTechnologyAndTricksAndLessMyPersonalBussinessStory = 1,
InTheMiddle = 2,
LessAboutTechnologyAndTricksAndMoreMyPersonalBussinessStory = 3,
OnlyMyPersonalBussinessStory = 4
}
public class CallForSpeech :
Entity<CallForSpeechId, CallForSpeechUniqueId>
{
public Speaker Speaker { get; set; }
public Speech Speech { get; set; }
public Registration Registration { get; set; }
public CallForSpeechNumber Number { get; set; }
public Category Category { get; private set; }
public CallForSpeechStatus Status { get; private set; }
public CallForSpeechScoringResult Score { get; private set; }
public Decision PreliminaryDecision { get; private set; }
public Decision FinalDecision { get; private set; }
public class CallForSpeechNumber : ValueObject<CallForSpeechNumber>
{
public string Number { get; }
public CallForSpeechNumber(string number)
{
if (string.IsNullOrWhiteSpace(number))
throw new ArgumentException
("CallForSpeechNumber number cannot be null or empty string");
Number = number;
}
public static CallForSpeechNumber NewNumber() => new CallForSpeechNumber(Guid.NewGuid().ToString());
public static CallForSpeechNumber Of(string number) => new CallForSpeechNumber(number);
public static implicit operator string(CallForSpeechNumber number) => number.Number;
protected override IEnumerable<object> GetAttributesToIncludeInEqualityCheck()
{
yield return Number;
}
}
public enum CallForSpeechStatus
{
New = 0,
EvaluatedByMachine = 1,
PreliminaryAcceptedByJudge = 2,
AcceptedByJudge = 3,
Rejected = 5
}
public class Registration : ValueObject<Registration>
{
public DateTime RegistrationDate { get; }
public Registration(DateTime registrationDate)
{
RegistrationDate = registrationDate;
}
protected Registration()
{
}
protected override IEnumerable<object>
GetAttributesToIncludeInEqualityCheck()
{
yield return RegistrationDate;
}
}
public class CallForSpeechScoringResult : ValueObject<CallForSpeechScoringResult>
{
public CallForSpeechMachineScore Score { get; }
public string RejectExplanation { get; }
public string WarringExplanation { get; }
public CallForSpeechScoringResult(CallForSpeechMachineScore score,
string rejectexlanation)
{
Score = score;
RejectExplanation = rejectexlanation;
}
public CallForSpeechScoringResult(CallForSpeechMachineScore score,
string rejectexlanation, string warringExplanation)
{
Score = score;
RejectExplanation = rejectexlanation;
WarringExplanation = warringExplanation;
}
//Dla EF Core
protected CallForSpeechScoringResult()
{
}
protected override IEnumerable<object>
GetAttributesToIncludeInEqualityCheck()
{
yield return Score;
yield return RejectExplanation;
}
public static CallForSpeechScoringResult Green()
{
return new CallForSpeechScoringResult(CallForSpeechMachineScore.Green,
"", "");
}
public static CallForSpeechScoringResult Red(string[] messages)
{
return new CallForSpeechScoringResult(CallForSpeechMachineScore.Red,
string.Join(Environment.NewLine, messages), "");
}
public static CallForSpeechScoringResult Yellow(string[] messages)
{
return new CallForSpeechScoringResult(CallForSpeechMachineScore.Yellow,
"", string.Join(Environment.NewLine, messages));
}
public bool IsRed()
{
return Score == CallForSpeechMachineScore.Red;
}
public bool IsYellow()
{
return Score == CallForSpeechMachineScore.Yellow;
}
public bool IsGreen()
{
return Score == CallForSpeechMachineScore.Green;
}
}
public enum CallForSpeechMachineScore
{
None = 0,
Red = 1, //Rejected
Yellow = 2, //WithWarrings
Green = 3, //AllOkej
}
public abstract class Entity<T1, T2>
{
public T1 Id { get; protected set; }
public T2 UniqueId { get; set; }
public int Version { get; set; }
}
public class CallForSpeech : Entity<CallForSpeechId, CallForSpeechUniqueId>
{
public Speaker Speaker { get; set; }
public Speech Speech { get; set; }
public Registration Registration { get; set; }
public CallForSpeechNumber Number { get; set; }
public Category Category { get; private set; }
public CallForSpeechStatus Status { get; private set; }
public CallForSpeechScoringResult Score { get; private set; }
public Decision PreliminaryDecision { get; private set; }
public Decision FinalDecision { get; private set; }
public CallForSpeech(CallForSpeechNumber number, Speech speech,
Speaker speaker, Category cat)
: this(number, CallForSpeechStatus.New, speaker, speech, cat,
null, new Registration(AppTime.Now()), null, null,
new CallForSpeechId(0))
{
}
public CallForSpeech(
CallForSpeechNumber number,
CallForSpeechStatus status,
Speaker speaker,
Speech speech,
Category category,
CallForSpeechScoringResult score,
Registration registration,
Decision preliminaryDecision,
Decision finalDecision,
CallForSpeechId callForSpeechId)
{
if (category == null)
throw new ArgumentException("Category cannot be null");
if (number == null)
throw new ArgumentException("Number cannot be null");
if (speech == null)
throw new ArgumentException("speech cannot be null");
if (speaker == null)
throw new ArgumentException("speaker cannot be null");
if (registration == null)
throw new ArgumentException("Registration cannot be null");
Id = callForSpeechId;
Number = number;
Status = status;
Score = score;
Speech = speech;
Speaker = speaker;
Registration = registration;
PreliminaryDecision = preliminaryDecision;
FinalDecision = finalDecision;
Category = category;
Version = 0;
UniqueId = CallForSpeechUniqueId.NewUniqueId();
}
// Dla EF Core jeśli używany
protected CallForSpeech()
{
UniqueId = CallForSpeechUniqueId.NewUniqueId();
Version = 0;
}
public void Evaluate(ScoringRules rules)
{
if (Status != CallForSpeechStatus.New)
{
throw new ApplicationException
("Cannot accept application that isn't new");
}
Score = rules.Evaluate(this);
if (!Score.IsRed())
{
Status = CallForSpeechStatus.EvaluatedByMachine;
}
else
{
Status = CallForSpeechStatus.Rejected;
}
}
public void PreliminaryAccept(Judge decisionBy)
{
if (Status == CallForSpeechStatus.PreliminaryAcceptedByJudge)
{
throw new ApplicationException
("You already PreliminaryAcceptedByJudge this CallForSpeech");
}
if (Status != CallForSpeechStatus.EvaluatedByMachine)
{
throw new ApplicationException
("Cannot accept application that WASNT'T in EvaluatedByMachine");
}
if (Score == null)
{
throw new ApplicationException
("Cannot accept application before scoring");
}
if (!decisionBy.CanAccept(this.Category.Id))
{
throw new ApplicationException
("Judge is from diffrent category. Can't Accept");
}
Status = CallForSpeechStatus.PreliminaryAcceptedByJudge;
PreliminaryDecision = new Decision(AppTime.Now(), decisionBy);
}
public void Accept(Judge decisionBy)
{
if (Status == CallForSpeechStatus.AcceptedByJudge)
{
throw new ApplicationException
("You already Accepted this CallForSpeech");
}
if (Status == CallForSpeechStatus.Rejected)
{
throw new ApplicationException
("Cannot accept application that is already rejected");
}
if (Status != CallForSpeechStatus.PreliminaryAcceptedByJudge)
{
throw new ApplicationException
("Cannot accept application that wasn't PreliminaryAccepted FIRST");
}
if (Score == null)
{
throw new ApplicationException
("Cannot accept application before scoring");
}
if (!decisionBy.CanAccept(this.Category.Id))
{
throw new ApplicationException
("Judge is from diffrent category. Can't Accept");
}
Status = CallForSpeechStatus.AcceptedByJudge;
FinalDecision = new Decision(AppTime.Now(), decisionBy);
}
public void Reject(Judge decisionBy)
{
if (Status == CallForSpeechStatus.Rejected ||
Status == CallForSpeechStatus.AcceptedByJudge)
{
throw new ApplicationException
("Cannot reject application that is already accepted or rejected");
}
if (!decisionBy.CanAccept(this.Category.Id))
{
throw new ApplicationException
("Judge is from diffrent category. Can't Accept");
}
Status = CallForSpeechStatus.Rejected;
FinalDecision = new Decision(AppTime.Now(), decisionBy);
}
public CallForSpeechIds Ids()
{
if (this.Id != null && this.Id.Value != default)
return new CallForSpeechIds()
{
UniqueId = this.UniqueId,
CreatedId = this.Id
};
else
return new CallForSpeechIds()
{
UniqueId = this.UniqueId,
CreatedId = this.Id,
Status = IdsStatus.DudeYouCantReturnCreatedIdWhenYouAreEventSourcing
};
}
}
public void Evaluate(ScoringRules rules)
{
if (Status != CallForSpeechStatus.New)
{
throw new ApplicationException
("Cannot accept application that isn't new");
}
Score = rules.Evaluate(this);
if (!Score.IsRed())
{
Status = CallForSpeechStatus.EvaluatedByMachine;
}
else
{
Status = CallForSpeechStatus.Rejected;
}
}
public void PreliminaryAccept(Judge decisionBy)
{
if (Status == CallForSpeechStatus.PreliminaryAcceptedByJudge)
{
throw new ApplicationException
("You already PreliminaryAcceptedByJudge this CallForSpeech");
}
if (Status != CallForSpeechStatus.EvaluatedByMachine)
{
throw new ApplicationException
("Cannot accept application that WASNT'T in EvaluatedByMachine");
}
if (Score == null)
{
throw new ApplicationException
("Cannot accept application before scoring");
}
if (!decisionBy.CanAccept(this.Category.Id))
{
throw new ApplicationException
("Judge is from diffrent category. Can't Accept");
}
Status = CallForSpeechStatus.PreliminaryAcceptedByJudge;
PreliminaryDecision = new Decision(AppTime.Now(), decisionBy);
}
public void Reject(Judge decisionBy)
{
if (Status == CallForSpeechStatus.Rejected ||
Status == CallForSpeechStatus.AcceptedByJudge)
{
throw new ApplicationException
("Cannot reject application that is already accepted or rejected");
}
if (!decisionBy.CanAccept(this.Category.Id))
{
throw new ApplicationException
("Judge is from diffrent category. Can't Accept");
}
Status = CallForSpeechStatus.Rejected;
FinalDecision = new Decision(AppTime.Now(), decisionBy);
}
public void Accept(Judge decisionBy)
{
if (Status == CallForSpeechStatus.AcceptedByJudge)
{
throw new ApplicationException
("You already Accepted this CallForSpeech");
}
if (Status == CallForSpeechStatus.Rejected)
{
throw new ApplicationException
("Cannot accept application that is already rejected");
}
if (Status != CallForSpeechStatus.PreliminaryAcceptedByJudge)
{
throw new ApplicationException
("Cannot accept application that wasn't PreliminaryAccepted FIRST");
}
if (Score == null)
{
throw new ApplicationException
("Cannot accept application before scoring");
}
if (!decisionBy.CanAccept(this.Category.Id))
{
throw new ApplicationException
("Judge is from diffrent category. Can't Accept");
}
Status = CallForSpeechStatus.AcceptedByJudge;
FinalDecision = new Decision(AppTime.Now(), decisionBy);
}
public enum Reason
{
None,
Error,
NotControledException,
ReturnedNull,
ConcurrencyOlderVersionSendedWhenNewerIsInEventStore,
AggregateOrEventMissingIdInEventStore,
AggregateNotFoundInEventStore,
EventsOutOfOrderInEventStore
}
public enum WhereExecuted
{
IDontKnow = 0,
DataBase = 1,
DomainLogic = 2,
EventStore = 3
}
public class ExecutionStatus
{
public bool Success { get; set; }
public string MessageForClient { get; set; }
public string MessageForDeveloper { get; set; }
public Exception Exception { get; init; }
public WhereExecuted Where { get; init; }
public Reason Reason { get; set; }
internal ExecutionStatus()
{
Reason = Reason.None;
}
public static ExecutionStatus LogicOk()
{
return new ExecutionStatus()
{
Where = WhereExecuted.DomainLogic,
Success = true,
};
}
public static ExecutionStatus EventStoreOk()
{
return new ExecutionStatus()
{
Where = WhereExecuted.EventStore,
Success = true,
};
}
public static ExecutionStatus LogicError(string message)
{
return new ExecutionStatus()
{
Where = WhereExecuted.DomainLogic,
Success = false,
MessageForClient = message,
Reason = Reason.Error
};
}
public static ExecutionStatus EventStoreError(string message)
{
return new ExecutionStatus()
{
Where = WhereExecuted.EventStore,
Success = false,
MessageForClient = message,
Reason = Reason.Error
};
}
public static ExecutionStatus EventStoreConcurrencyError(string message)
{
return new ExecutionStatus()
{
Where = WhereExecuted.EventStore,
Success = false,
MessageForClient = message,
Reason = Reason.ConcurrencyOlderVersionSendedWhenNewerIsInEventStore
};
}
public static ExecutionStatus EventStoreEventsOutOfOrderError(string message)
{
return new ExecutionStatus()
{
Where = WhereExecuted.EventStore,
Success = false,
MessageForClient = message,
Reason = Reason.EventsOutOfOrderInEventStore
};
}
public static ExecutionStatus EventStoreAggregateOrEventMissingIdError(string message)
{
return new ExecutionStatus()
{
Where = WhereExecuted.EventStore,
Success = false,
MessageForClient = message,
Reason = Reason.AggregateNotFoundInEventStore
};
}
public static ExecutionStatus LogicError(Exception ex)
{
return new ExecutionStatus()
{
Where = WhereExecuted.DomainLogic,
Success = false,
Reason = Reason.NotControledException,
Exception = ex,
MessageForClient = ex.Message
};
}
public static ExecutionStatus EventStoreError(Exception ex)
{
return new ExecutionStatus()
{
Where = WhereExecuted.EventStore,
Success = false,
Reason = Reason.NotControledException,
Exception = ex,
MessageForClient = ex.Message
};
}
public static ExecutionStatus DbOk()
{
return new ExecutionStatus()
{
Where = WhereExecuted.DataBase,
Success = true,
};
}
public static ExecutionStatus DbError(string message)
{
return new ExecutionStatus()
{
Where = WhereExecuted.DataBase,
Reason = Reason.Error,
Success = false,
MessageForClient = message
};
}
public static ExecutionStatus DbError(Exception ex)
{
return new ExecutionStatus()
{
Where = WhereExecuted.DataBase,
Success = false,
Exception = ex,
MessageForClient = ex.Message,
Reason = Reason.Error
};
}
}
public class ExecutionStatus<T>
{
public bool Success { get; init; }
public string MessageForClient { get; init; }
public string MessageForDeveloper { get; set; }
public Exception Exception { get; init; }
public WhereExecuted Where { get; init; }
public T Value { get; init; }
public Reason Reason { get; init; }
protected ExecutionStatus()
{
Reason = Reason.None;
}
public ExecutionStatus RemoveGeneric()
{
return new ExecutionStatus()
{
Success = this.Success,
Exception = this.Exception,
MessageForClient = this.MessageForClient,
MessageForDeveloper = this.MessageForDeveloper,
Reason = this.Reason,
Where = this.Where
};
}
public static ExecutionStatus<T> DbOk(T value)
{
return new ExecutionStatus<T>()
{
Success = true,
Value = value,
Where = WhereExecuted.DataBase
};
}
public static ExecutionStatus<T> LogicOk(T value)
{
return new ExecutionStatus<T>()
{
Success = true,
Value = value,
Where = WhereExecuted.DomainLogic
};
}
public static ExecutionStatus<T> EventStoreOk(T value)
{
return new ExecutionStatus<T>()
{
Success = true,
Value = value,
Where = WhereExecuted.EventStore
};
}
public static ExecutionStatus<T> LogicError(string message)
{
return new ExecutionStatus<T>()
{
Success = false,
MessageForClient = message,
Reason = Reason.Error,
Where = WhereExecuted.DomainLogic
};
}
public static ExecutionStatus<T> EventStoreError(string message)
{
return new ExecutionStatus<T>()
{
Success = false,
MessageForClient = message,
Reason = Reason.Error,
Where = WhereExecuted.EventStore
};
}
public static ExecutionStatus<T> LogicError(Exception ex)
{
return new ExecutionStatus<T>()
{
Where = WhereExecuted.DomainLogic,
Success = false,
Reason = Reason.NotControledException,
Exception = ex,
MessageForClient = ex.Message
};
}
public static ExecutionStatus<T> EventStoreError(Exception ex)
{
return new ExecutionStatus<T>()
{
Where = WhereExecuted.EventStore,
Success = false,
Reason = Reason.NotControledException,
Exception = ex,
MessageForClient = ex.Message
};
}
public static ExecutionStatus<T> EventStoreConcurrencyError(string message)
{
return new ExecutionStatus<T>()
{
Where = WhereExecuted.EventStore,
Success = false,
MessageForClient = message,
Reason = Reason.ConcurrencyOlderVersionSendedWhenNewerIsInEventStore
};
}
public static ExecutionStatus EventStoreAggregateOrEventMissingIdError(string message)
{
return new ExecutionStatus()
{
Where = WhereExecuted.EventStore,
Success = false,
MessageForClient = message,
Reason = Reason.AggregateOrEventMissingIdInEventStore
};
}
public static ExecutionStatus<T> EventStoreAggregateNotFoundError(string message)
{
return new ExecutionStatus<T>()
{
Where = WhereExecuted.EventStore,
Success = false,
MessageForClient = message,
Reason = Reason.AggregateNotFoundInEventStore
};
}
public static ExecutionStatus<T> LogicIfDefaultThenError(T value)
{
if (EqualityComparer<T>.Default.Equals(value, default(T)))
{
return new ExecutionStatus<T>()
{
Where = WhereExecuted.DomainLogic,
Success = false,
MessageForClient = "NotFound",
Reason = Reason.ReturnedNull
};
}
return new ExecutionStatus<T>()
{
Where = WhereExecuted.DataBase,
Success = true,
};
}
public static ExecutionStatus<T> DbError(string message)
{
return new ExecutionStatus<T>()
{
Where = WhereExecuted.DataBase,
Success = false,
MessageForClient = message
};
}
public static ExecutionStatus<T> DbError(Exception ex)
{
return new ExecutionStatus<T>()
{
Where = WhereExecuted.DataBase,
Success = false,
Reason = Reason.NotControledException,
Exception = ex,
MessageForDeveloper = ex.Message
};
}
public static ExecutionStatus<T> DbIfDefaultThenError(T value)
{
if (EqualityComparer<T>.Default.Equals(value, default(T)))
{
return new ExecutionStatus<T>()
{
Where = WhereExecuted.DataBase,
Success = false,
MessageForClient = "NotFound",
Reason = Reason.ReturnedNull
};
}
return new ExecutionStatus<T>()
{
Where = WhereExecuted.DataBase,
Success = true,
Value = value
};
}
public static ExecutionStatus<T> From(ExecutionStatus addstatus)
{
return new ExecutionStatus<T>()
{
Where = addstatus.Where,
Exception = addstatus.Exception,
MessageForClient = addstatus.MessageForClient,
MessageForDeveloper = addstatus.MessageForDeveloper,
Success = true,
};
}
}
public static class ExecutionFlow
{
public static IExecutionOptions Options { get; set; }
static ExecutionFlow()
{
Options = new ExecutionOptions();
}
}
public interface IExecutionOptions
{
bool ThrowExceptions { get; set; }
}
public class ExecutionOptions : IExecutionOptions
{
public bool _throwExceptions;
public ExecutionOptions()
{
}
public ExecutionOptions(bool throwExceptions)
{
_throwExceptions = throwExceptions;
}
public bool ThrowExceptions
{
get => _throwExceptions;
set => _throwExceptions = value;
}
}
public class CallForSpeech : Entity<CallForSpeechId, CallForSpeechUniqueId>
{
public Speaker Speaker { get; set; }
public Speech Speech { get; set; }
public Registration Registration { get; set; }
public CallForSpeechNumber Number { get; set; }
public Category Category { get; private set; }
public CallForSpeechStatus Status { get; private set; }
public CallForSpeechScoringResult Score { get; private set; }
public Decision PreliminaryDecision { get; private set; }
public Decision FinalDecision { get; private set; }
public CallForSpeech(CallForSpeechNumber number, Speech speech,
Speaker speaker, Category cat)
: this(number, CallForSpeechStatus.New, speaker, speech, cat,
null, new Registration(AppTime.Now()), null, null,
new CallForSpeechId(0))
{
}
public CallForSpeech(
CallForSpeechNumber number,
CallForSpeechStatus status,
Speaker speaker,
Speech speech,
Category category,
CallForSpeechScoringResult score,
Registration registration,
Decision preliminaryDecision,
Decision finalDecision,
CallForSpeechId callForSpeechId)
{
if (category == null)
throw new ArgumentException("Category cannot be null");
if (number == null)
throw new ArgumentException("Number cannot be null");
if (speech == null)
throw new ArgumentException("speech cannot be null");
if (speaker == null)
throw new ArgumentException("speaker cannot be null");
if (registration == null)
throw new ArgumentException("Registration cannot be null");
Id = callForSpeechId;
Number = number;
Status = status;
Score = score;
Speech = speech;
Speaker = speaker;
Registration = registration;
PreliminaryDecision = preliminaryDecision;
FinalDecision = finalDecision;
Category = category;
Version = 1;
UniqueId = CallForSpeechUniqueId.NewUniqueId();
}
// To satisfy EF Core
protected CallForSpeech()
{
UniqueId = CallForSpeechUniqueId.NewUniqueId();
Version = 1;
}
public void Evaluate(ScoringRules rules)
{
if (Status != CallForSpeechStatus.New)
{
throw new ApplicationException("Cannot accept application that isn't new");
}
Score = rules.Evaluate(this);
if (!Score.IsRed())
{
Status = CallForSpeechStatus.EvaluatedByMachine;
}
else
{
Status = CallForSpeechStatus.Rejected;
}
}
public ExecutionStatus TryEvaluate(ScoringRules rules)
{
if (Status != CallForSpeechStatus.New)
{
return ExecutionStatus.LogicError("Cannot accept application that isn't new");
}
Score = rules.Evaluate(this);
if (!Score.IsRed())
{
Status = CallForSpeechStatus.EvaluatedByMachine;
}
else
{
Status = CallForSpeechStatus.Rejected;
}
return ExecutionStatus.LogicOk();
}
public void PreliminaryAccept(Judge decisionBy)
{
if (Status == CallForSpeechStatus.PreliminaryAcceptedByJudge)
{
throw new ApplicationException("You already PreliminaryAcceptedByJudge this CallForSpeech");
}
if (Status != CallForSpeechStatus.EvaluatedByMachine)
{
throw new ApplicationException("Cannot accept application that WASNT'T in EvaluatedByMachine");
}
if (Score == null)
{
throw new ApplicationException("Cannot accept application before scoring");
}
if (!decisionBy.CanAccept(this.Category.Id))
{
throw new ApplicationException("Judge is from diffrent category. Can't Accept");
}
Status = CallForSpeechStatus.PreliminaryAcceptedByJudge;
PreliminaryDecision = new Decision(AppTime.Now(), decisionBy);
}
public ExecutionStatus TryPreliminaryAccept(Judge decisionBy)
{
if (Status == CallForSpeechStatus.PreliminaryAcceptedByJudge)
{
return ExecutionStatus.
LogicError("You already PreliminaryAcceptedByJudge this CallForSpeech");
}
if (Status != CallForSpeechStatus.EvaluatedByMachine)
{
return ExecutionStatus.LogicError("Cannot accept application that WASNT'T in EvaluatedByMachine");
}
if (Score == null)
{
return ExecutionStatus.LogicError("Cannot accept application before scoring");
}
if (!decisionBy.CanAccept(this.Category.Id))
{
return ExecutionStatus.
LogicError("Judge is from diffrent category. Can't Accept");
}
Status = CallForSpeechStatus.PreliminaryAcceptedByJudge;
PreliminaryDecision = new Decision(AppTime.Now(), decisionBy);
return ExecutionStatus.LogicOk();
}
public void Accept(Judge decisionBy)
{
if (Status == CallForSpeechStatus.AcceptedByJudge)
{
throw new ApplicationException("You already Accepted this CallForSpeech");
}
if (Status == CallForSpeechStatus.Rejected)
{
throw new ApplicationException("Cannot accept application that is already rejected");
}
if (Status != CallForSpeechStatus.PreliminaryAcceptedByJudge)
{
throw new ApplicationException("Cannot accept application that wasn't PreliminaryAccepted FIRST");
}
if (Score == null)
{
throw new ApplicationException("Cannot accept application before scoring");
}
if (!decisionBy.CanAccept(this.Category.Id))
{
throw new ApplicationException("Judge is from diffrent category. Can't Accept");
}
Status = CallForSpeechStatus.AcceptedByJudge;
FinalDecision = new Decision(AppTime.Now(), decisionBy);
}
public ExecutionStatus TryAccept(Judge decisionBy)
{
if (Status == CallForSpeechStatus.AcceptedByJudge)
{
return ExecutionStatus.
LogicError("You already Accepted this CallForSpeech");
}
if (Status == CallForSpeechStatus.Rejected)
{
return ExecutionStatus.
LogicError("Cannot accept application that is already rejected");
}
if (Status != CallForSpeechStatus.PreliminaryAcceptedByJudge)
{
return ExecutionStatus.
LogicError("Cannot accept application that wasn't PreliminaryAccepted FIRST");
}
if (Score == null)
{
return ExecutionStatus.
LogicError("Cannot accept application before scoring");
}
if (!decisionBy.CanAccept(this.Category.Id))
{
return ExecutionStatus.
LogicError("Judge is from diffrent category. Can't Accept");
}
Status = CallForSpeechStatus.AcceptedByJudge;
FinalDecision = new Decision(AppTime.Now(), decisionBy);
return ExecutionStatus.LogicOk();
}
public void Reject(Judge decisionBy)
{
if (Status == CallForSpeechStatus.Rejected ||
Status == CallForSpeechStatus.AcceptedByJudge)
{
throw new ApplicationException("Cannot reject application that is already accepted or rejected");
}
if (!decisionBy.CanAccept(this.Category.Id))
{
throw new ApplicationException("Judge is from diffrent category. Can't Accept");
}
Status = CallForSpeechStatus.Rejected;
FinalDecision = new Decision(AppTime.Now(), decisionBy);
}
public ExecutionStatus TryReject(Judge decisionBy)
{
if (Status == CallForSpeechStatus.Rejected ||
Status == CallForSpeechStatus.AcceptedByJudge)
{
return ExecutionStatus.
LogicError("Cannot reject application that is already accepted or rejected");
}
if (!decisionBy.CanAccept(this.Category.Id))
{
return ExecutionStatus.
LogicError("Judge is from diffrent category. Can't Accept");
}
Status = CallForSpeechStatus.Rejected;
FinalDecision = new Decision(AppTime.Now(), decisionBy);
return ExecutionStatus.LogicOk();
}
public CallForSpeechIds Ids()
{
if (this.Id != null && this.Id.Value != default)
return new CallForSpeechIds()
{
UniqueId = this.UniqueId,
CreatedId = this.Id
};
else
return new CallForSpeechIds()
{
UniqueId = this.UniqueId,
CreatedId = this.Id,
Status = IdsStatus.DudeYouCantReturnCreatedIdWhenYouAreEventSourcing
};
}
}
public ExecutionStatus TryEvaluate(ScoringRules rules)
{
if (Status != CallForSpeechStatus.New)
{
return ExecutionStatus.LogicError("Cannot accept application that isn't new");
}
Score = rules.Evaluate(this);
if (!Score.IsRed())
{
Status = CallForSpeechStatus.EvaluatedByMachine;
}
else
{
Status = CallForSpeechStatus.Rejected;
}
return ExecutionStatus.LogicOk();
}
public ExecutionStatus TryReject(Judge decisionBy)
{
if (Status == CallForSpeechStatus.Rejected ||
Status == CallForSpeechStatus.AcceptedByJudge)
{
return ExecutionStatus.
LogicError("Cannot reject application that is already accepted or rejected");
}
if (!decisionBy.CanAccept(this.Category.Id))
{
return ExecutionStatus.
LogicError("Judge is from diffrent category. Can't Accept");
}
Status = CallForSpeechStatus.Rejected;
FinalDecision = new Decision(AppTime.Now(), decisionBy);
return ExecutionStatus.LogicOk();
}
public interface IScoringRejectRule
{
bool IsSatisfiedBy(CallForSpeech speechCandidate);
string Message { get; }
}
public interface IScoringWarringRule
{
bool IsSatisfiedBy(CallForSpeech speechCandidate);
string Message { get; }
}
public class ScoringRules
{
private readonly IList<IScoringRejectRule> rejectrules;
private readonly IList<IScoringWarringRule> warringrules;
public ScoringRules(IList<IScoringRejectRule> rejectrules,
IList<IScoringWarringRule> warringrules)
{
this.rejectrules = rejectrules;
this.warringrules = warringrules;
}
public CallForSpeechScoringResult Evaluate(CallForSpeech speechCandidate)
{
var brokenRules = this.rejectrules
.Where(r => !r.IsSatisfiedBy(speechCandidate))
.ToList();
if (brokenRules.Any())
return CallForSpeechScoringResult.Red
(brokenRules.Select(r => r.Message).
ToArray());
var warringrules = this.warringrules
.Where(r => !r.IsSatisfiedBy(speechCandidate))
.ToList();
if (warringrules.Any())
return CallForSpeechScoringResult.Yellow
(brokenRules.Select(r => r.Message).
ToArray());
return CallForSpeechScoringResult.Green();
}
}
namespace GeekLemonConference.Application.Common
{
public enum ResponseStatus
{
Success = 0,
NotFoundInDataBase = 1,
BadQuery = 2,
ValidationError = 3,
DataBaseError = 4,
BussinesLogicError = 5,
EventStoreError = 6,
ConcurrencyOlderVersionSendedWhenNewerIsInEventStore = 7,
AggregateOrEventMissingIdInEventStore = 8,
AggregateNotFoundInEventStore = 9
}
}
public enum WhatHTTPCodeShouldBeRetruned
{
Forbid,
NotFound,
BadRequest,
MethodFailure,
Ok
}
public abstract class BaseResponse
{
public ResponseStatus Status { get; set; }
public string StatusInfo
{
get
{
return Status.ToString();
}
}
public WhatHTTPCodeShouldBeRetruned WhatHTTPCodeToBeRetruned
{
get
{
if (this.Status == ResponseStatus.BussinesLogicError)
return WhatHTTPCodeShouldBeRetruned.Forbid;
if (this.Status == ResponseStatus.NotFoundInDataBase)
return WhatHTTPCodeShouldBeRetruned.NotFound;
if (this.Status == ResponseStatus.ValidationError ||
this.Status == ResponseStatus.BadQuery ||
this.Status == ResponseStatus.ConcurrencyOlderVersionSendedWhenNewerIsInEventStore)
return WhatHTTPCodeShouldBeRetruned.BadRequest;
if (!this.Success)
return WhatHTTPCodeShouldBeRetruned.BadRequest;
else
return WhatHTTPCodeShouldBeRetruned.Ok;
}
}
public bool Success { get; set; }
public string Message { get; set; }
public List<string> ValidationErrors { get; set; }
protected BaseResponse()
{
ValidationErrors = new List<string>();
Success = true;
Status = ResponseStatus.Success;
}
protected BaseResponse(ExecutionStatus status)
{
ValidationErrors = new List<string>();
if (!status.Success)
{
Success = false;
if (status.Where == WhereExecuted.DomainLogic)
Status = ResponseStatus.BussinesLogicError;
if (status.Where == WhereExecuted.DataBase)
Status = ResponseStatus.DataBaseError;
if (status.Where == WhereExecuted.DataBase
&& status.Reason == Reason.ReturnedNull)
Status = ResponseStatus.NotFoundInDataBase;
if (status.Reason == Reason.AggregateNotFoundInEventStore)
Status = ResponseStatus.AggregateNotFoundInEventStore;
if (status.Reason == Reason.AggregateOrEventMissingIdInEventStore)
Status = ResponseStatus.AggregateOrEventMissingIdInEventStore;
if (status.Reason == Reason.ConcurrencyOlderVersionSendedWhenNewerIsInEventStore)
Status = ResponseStatus.ConcurrencyOlderVersionSendedWhenNewerIsInEventStore;
Message = status.Message;
}
else
{
Success = true;
Status = ResponseStatus.Success;
}
}
protected BaseResponse(ExecutionStatus status, string message)
{
ValidationErrors = new List<string>();
if (!status.Success)
{
Success = false;
if (status.Where == WhereExecuted.DomainLogic)
Status = ResponseStatus.BussinesLogicError;
if (status.Where == WhereExecuted.DataBase)
Status = ResponseStatus.DataBaseError;
if (status.Where == WhereExecuted.DataBase
&& status.Reason == Reason.ReturnedNull)
Status = ResponseStatus.NotFoundInDataBase;
if (status.Reason == Reason.AggregateNotFoundInEventStore)
Status = ResponseStatus.AggregateNotFoundInEventStore;
if (status.Reason == Reason.AggregateOrEventMissingIdInEventStore)
Status = ResponseStatus.AggregateOrEventMissingIdInEventStore;
if (status.Reason == Reason.ConcurrencyOlderVersionSendedWhenNewerIsInEventStore)
Status = ResponseStatus.ConcurrencyOlderVersionSendedWhenNewerIsInEventStore;
Message = message;
Message += status.Message;
}
else
{
Success = true;
Status = ResponseStatus.Success;
}
}
protected BaseResponse(string message = null)
{
ValidationErrors = new List<string>();
Success = true;
Message = message;
Status = ResponseStatus.Success;
}
protected BaseResponse(string message, bool success)
{
ValidationErrors = new List<string>();
Success = success;
Message = message;
}
protected BaseResponse(ResponseStatus status)
{
ValidationErrors = new List<string>();
Success = status != ResponseStatus.Success;
Status = status;
}
protected BaseResponse(ValidationResult validationResult)
{
ValidationErrors = new List<String>();
Success = validationResult.Errors.Count < 0;
foreach (var item in validationResult.Errors)
{
ValidationErrors.Add(item.ErrorMessage);
}
if (!Success)
Status = ResponseStatus.ValidationError;
else
Status = ResponseStatus.Success;
}
}
public interface IAsyncRepository<T> where T : class
{
Task<ExecutionStatus<IReadOnlyList<T>>> GetAllAsync();
Task<ExecutionStatus> UpdateByUniqueIdAsync(T entity);
Task<ExecutionStatus> UpdateByIdAsync(T entity);
}
public interface IJudgeRepository :
IAsyncRepository<Judge>
{
Task<ExecutionStatus> DeleteAsync(JudgeId entity);
Task<ExecutionStatus> DeleteAsync(JudgeUniqueId id);
Task<ExecutionStatus<JudgeIds>> AddAsync(Judge entity);
Task<ExecutionStatus<Judge>> GetByIdAsync(JudgeId id);
Task<ExecutionStatus<Judge>> GetByIdAsync(JudgeUniqueId id);
}
public interface ICategoryRepository
: IAsyncRepository<Category>
{
Task<ExecutionStatus> DeleteAsync(CategoryId categoryId);
Task<ExecutionStatus> DeleteAsync(CategoryUniqueId categoryId);
Task<ExecutionStatus<CategoryIds>> AddAsync(Category entity);
Task<ExecutionStatus<Category>> GetByIdAsync(CategoryId id);
Task<ExecutionStatus<Category>> GetByIdAsync(CategoryUniqueId id);
}
public interface ICallForSpeechRepository
{
Task<ExecutionStatus<IReadOnlyList<CallForSpeech>>> GetCollectionAsync(
FilterCallForSpeechStyles filtrer);
Task<ExecutionStatus<CallForSpeech>> GetByIdAsync(CallForSpeechId id);
Task<ExecutionStatus<CallForSpeech>> GetByIdAsync(CallForSpeechUniqueId id);
Task<ExecutionStatus> SavePreliminaryAcceptenceAsync(CallForSpeechId id,
JudgeId judge, CallForSpeechStatus status);
Task<ExecutionStatus> SaveAcceptenceAsync(CallForSpeechId id,
JudgeId judge, CallForSpeechStatus status);
Task<ExecutionStatus<CallForSpeechIds>> SubmitAsync(CallForSpeech callForSpeech);
Task<ExecutionStatus> SavePreliminaryAcceptenceAsync(CallForSpeechUniqueId id,
JudgeId judge, CallForSpeechStatus status);
Task<ExecutionStatus> SaveAcceptenceAsync(CallForSpeechUniqueId id,
JudgeId judge, CallForSpeechStatus status);
Task<ExecutionStatus> SaveRejectionAsync(CallForSpeechUniqueId id,
JudgeId judge, CallForSpeechStatus status);
Task<ExecutionStatus> SaveRejectionAsync(CallForSpeechId id,
JudgeId judge, CallForSpeechStatus status);
Task<ExecutionStatus> SaveEvaluatationAsync(CallForSpeechUniqueId id,
CallForSpeechScoringResult score, CallForSpeechStatus status);
Task<ExecutionStatus> SaveEvaluatationAsync(CallForSpeechId id,
CallForSpeechScoringResult score, CallForSpeechStatus status);
}
public enum FilterCallForSpeechStyles
{
All = 100,
New = 0,
EvaluatedByMachine = 1,
PreliminaryAcceptedByJudge = 2,
AcceptedByJudge = 3,
Rejected = 5,
}
public interface IZEsCallForSpeechRepository
: ICallForSpeechRepository
{
}
public interface IZEsCategoryRepository
: ICategoryRepository
{
}
public interface IZEsJudgeRepository
: IJudgeRepository
{
}
public class SpeakerAgeMusteBeAbove17
: IScoringRejectRule
{
public bool IsSatisfiedBy(CallForSpeech cfs)
{
return cfs.Speaker.AgeInYearsAt(AppTime.Now()) > 17.Years();
}
public string Message => "Speaker age must be above 17.";
}
public class SpeakerAgeMusteBeBelow70
: IScoringRejectRule
{
public bool IsSatisfiedBy(CallForSpeech cfs)
{
return cfs.Speaker.AgeInYearsAt(AppTime.Now()) < 70.Years();
}
public string Message => "Speaker age must be below 70.";
}
public class SpeakerMustHaveAtLeastOneSocialMedia
: IScoringRejectRule
{
public bool IsSatisfiedBy(CallForSpeech cfs)
{
return cfs.Speaker.SpeakerWebsites.HaveSocialMedia();
}
public string Message => "Speaker must have at least one social media";
}
public class SpeakerMustHaveBlogOrGitHub : IScoringRejectRule
{
public bool IsSatisfiedBy(CallForSpeech cfs)
{
return cfs.Speaker.SpeakerWebsites.HaveGitHub()
|| cfs.Speaker.SpeakerWebsites.HaveBlog();
}
public string Message => "Speaker must have at blog or github";
}
public interface IScoringRulesFactory
{
public ScoringRules DefaultSet { get; }
}
public class ScoringRulesFactory : IScoringRulesFactory
{
public ScoringRulesFactory()
{
}
public ScoringRules DefaultSet => new ScoringRules(
new List<IScoringRejectRule>
{
new SpeakerAgeMusteBeAbove17(),
new SpeakerAgeMusteBeBelow70(),
new SpeakerMustHaveAtLeastOneSocialMedia(),
new SpeakerMustHaveBlogOrGitHub()
},
new List<IScoringWarringRule>()
{
});
}
public class CategoryBuilder
{
private CategoryId categoryId =
new CategoryId(999);
private CategoryUniqueId categoryUniqueId =
new CategoryUniqueId(Guid.NewGuid());
private string name = "csharp";
private string displayname = "C#";
private string whatWeAreLookingFor = "BBBBB CCCCC AAAA";
public static CategoryBuilder GivenCategory() => new CategoryBuilder();
public CategoryBuilder WithId(int categorId)
{
categoryId = new CategoryId(categorId);
return this;
}
public CategoryBuilder WithUniqueId(Guid guid)
{
categoryUniqueId = new CategoryUniqueId(guid);
return this;
}
public CategoryBuilder WithName(string newname)
{
name = newname;
return this;
}
public CategoryBuilder WithWhatWeAreLookingFor(string newWhatWeAreLookingFor)
{
whatWeAreLookingFor = newWhatWeAreLookingFor;
return this;
}
public CategoryBuilder WithDisplayName(string newdisplayname)
{
displayname = newdisplayname;
return this;
}
public Category Build()
{
var c = new Category(categoryId, name, displayname, whatWeAreLookingFor);
c.InjectUniqueId(categoryUniqueId);
return c;
}
}
public class JudgeBuilder
{
private string login = "guest";
private int id = 1234;
private Category category = CategoryBuilder.GivenCategory().Build();
public static JudgeBuilder GivenJudge() => new JudgeBuilder();
public JudgeBuilder WithLogin(string login)
{
this.login = login;
return this;
}
public JudgeBuilder WithCategory(
Action<CategoryBuilder> categoryBuilderAction)
{
var categoryBuilder = new CategoryBuilder();
categoryBuilderAction(categoryBuilder);
category = categoryBuilder.Build();
return this;
}
public Judge Build()
{
return new Judge(id, new Login(login),
new Password(login),
new Name(login, login), category);
}
public JudgeBuilder WithId(int v)
{
id = v;
return this; ;
}
}
public class SpeakerWebsitesBuilder
{
public static SpeakerWebsitesBuilder GivenSpeakerWebsites()
=> new SpeakerWebsitesBuilder();
private string facebbok = "https://www.facebook.com/cezary.walenciuk";
private string twitter = "https://twitter.com/walenciukc";
private string tiktok = "https://www.tiktok.com/@shanselman?";
private string instagram = "https://www.instagram.com/cezarywalenciuk/";
private string youTube = "https://www.youtube.com/channel/UCaryk7_lKRI1EldZ6saVjBQ";
private string fanPageOnFacebook = "https://www.facebook.com/JakProgramowac?fref=nf";
private string linkedin = "https://www.linkedin.com/in/cezary-walenciuk-35615644/";
private string blog = "https://cezarywalenciuk.pl/";
private string github = "https://github.com/PanNiebieski";
public SpeakerWebsitesBuilder ClearWebsites()
{
facebbok = "";
instagram = "";
twitter = "";
tiktok = "";
youTube = "";
fanPageOnFacebook = "";
linkedin = "";
blog = "";
blog = "";
return this;
}
public SpeakerWebsitesBuilder WithFacebbok(string newfacebook)
{
facebbok = newfacebook;
return this;
}
public SpeakerWebsitesBuilder WithInstagram(string newinstagram)
{
instagram = newinstagram;
return this;
}
public SpeakerWebsitesBuilder WithTwitter(string newtwitter)
{
twitter = newtwitter;
return this;
}
public SpeakerWebsitesBuilder WithTikTok(string newtiktok)
{
tiktok = newtiktok;
return this;
}
public SpeakerWebsitesBuilder WithYoutube(string newyoutube)
{
youTube = newyoutube;
return this;
}
public SpeakerWebsitesBuilder WithFanPageOnFacebook(string newfanPageOnFacebook)
{
fanPageOnFacebook = newfanPageOnFacebook;
return this;
}
public SpeakerWebsitesBuilder WithLinkedIn(string newlinkedin)
{
linkedin = newlinkedin;
return this;
}
public SpeakerWebsitesBuilder WithBlog(string newblog)
{
blog = newblog;
return this;
}
public SpeakerWebsitesBuilder WithGitHub(string newgithub)
{
github = newgithub;
return this;
}
public SpeakerWebsites Build()
{
return new SpeakerWebsites
()
{
Facebook = facebbok,
Blog = blog,
FanPageOnFacebook = fanPageOnFacebook,
GitHub = github,
Instagram = instagram,
LinkedIN = linkedin,
TikTok = tiktok,
Twitter = twitter,
YouTube = youTube
};
}
}
public class SpeakerBuilder
{
private Name name = new Name("Jan", "B");
private Address address =
new Address("PL", "00-002", "Warsaw", "Lemonowa 12");
private DateTime birthDate = AppTime.Now().AddYears(-25);
private SpeakerWebsites speakerWebsites =
SpeakerWebsitesBuilder.GivenSpeakerWebsites().Build();
private Contact contact = new Contact("655-555-555", "C@gmail.com");
private string Bio = "asasa";
public static SpeakerBuilder GivenSpeaker() => new SpeakerBuilder();
public SpeakerBuilder WithAge(int age)
{
this.birthDate = AppTime.Now().AddYears(-1 * age);
return this;
}
public SpeakerBuilder BornOn(DateTime birthDate)
{
this.birthDate = birthDate;
return this;
}
public SpeakerBuilder WithContact(string Phone, string email)
{
this.contact = new Contact(Phone, email);
return this;
}
public SpeakerBuilder WithAddress(string country, string zip, string city, string street)
{
this.address = new Address(country, zip, city, street);
return this;
}
public SpeakerBuilder WithSpeakerWebsites(
Action<SpeakerWebsitesBuilder> speakerBuilderAction)
{
var speakerWebsiteBuilder = new SpeakerWebsitesBuilder();
speakerBuilderAction(speakerWebsiteBuilder);
speakerWebsites = speakerWebsiteBuilder.Build();
return this;
}
public SpeakerBuilder WithSpeakerWebsites(
SpeakerWebsites speakerWebSites)
{
speakerWebsites = speakerWebSites;
return this;
}
public Speaker Build()
{
return new Speaker
(
name,
birthDate,
address,
speakerWebsites,
Bio,
contact
);
}
}
public class CallForSpeechBuilder
{
private static Category category = CategoryBuilder.GivenCategory().Build();
private Judge judge = new Judge(new Login("admin"),
new Password("admin"),
new Name("admin", "admin"),
category);
private Speaker speaker = new SpeakerBuilder().Build();
private Speech speech = new SpeechBuilder().Build();
private CallForSpeechNumber callForSpeechNumber = new CallForSpeechNumber(Guid.NewGuid().ToString());
private bool evaluated = false;
private CallForSpeechStatus targetStatus = CallForSpeechStatus.New;
private ScoringRulesFactory scoringRulesFactory = new ScoringRulesFactory();
public static CallForSpeechBuilder GivenCallForSpeech() => new CallForSpeechBuilder();
public CallForSpeechBuilder Accepted()
{
targetStatus = CallForSpeechStatus.AcceptedByJudge;
return this;
}
public CallForSpeechBuilder Rejected()
{
targetStatus = CallForSpeechStatus.Rejected;
return this;
}
public CallForSpeechBuilder Evaluated()
{
evaluated = true;
targetStatus = CallForSpeechStatus.EvaluatedByMachine;
return this;
}
public CallForSpeechBuilder NotEvaluated()
{
evaluated = false;
targetStatus = CallForSpeechStatus.New;
return this;
}
public CallForSpeechBuilder New()
{
targetStatus = CallForSpeechStatus.New;
evaluated = false;
return this;
}
public CallForSpeechBuilder PreliminaryAcceptedByJudge()
{
targetStatus = CallForSpeechStatus.PreliminaryAcceptedByJudge;
evaluated = true;
return this;
}
public CallForSpeechBuilder WithNumber(string number)
{
callForSpeechNumber = new CallForSpeechNumber(number);
return this;
}
public CallForSpeechBuilder WithSpeaker(Action<SpeakerBuilder> speakerBuilderAction)
{
var speakerBuilder = new SpeakerBuilder();
speakerBuilderAction(speakerBuilder);
speaker = speakerBuilder.Build();
return this;
}
public CallForSpeechBuilder WithSpeech(Action<SpeechBuilder> speechBuilderAction)
{
var speechBuilder = new SpeechBuilder();
speechBuilderAction(speechBuilder);
speech = speechBuilder.Build();
return this;
}
public CallForSpeechBuilder WithJudge(string login, Guid CategoryId)
{
CategoryId categoryId =
new CategoryId(0);
judge = new Judge(new Login(login),
new Password(login),
new Name(login, login),
new Category(
categoryId,
login, login, login));
return this;
}
public CallForSpeechBuilder WithCategory(
Action<CategoryBuilder> categoryBuilderAction)
{
var categoryBuilder = new CategoryBuilder();
categoryBuilderAction(categoryBuilder);
category = categoryBuilder.Build();
return this;
}
public CallForSpeech Build()
{
var cfs = new CallForSpeech
(
callForSpeechNumber,
speech,
speaker,
category
);
if (targetStatus == CallForSpeechStatus.EvaluatedByMachine)
{
cfs.Evaluate(scoringRulesFactory.DefaultSet);
}
if (targetStatus == CallForSpeechStatus.PreliminaryAcceptedByJudge)
{
cfs.Evaluate(scoringRulesFactory.DefaultSet);
cfs.PreliminaryAccept(judge);
}
if (targetStatus == CallForSpeechStatus.AcceptedByJudge)
{
cfs.Evaluate(scoringRulesFactory.DefaultSet);
cfs.PreliminaryAccept(judge);
cfs.Accept(judge);
}
if (targetStatus == CallForSpeechStatus.Rejected)
{
cfs.Reject(judge);
}
return cfs;
}
}
public class AgeInYearsTests
{
[Fact]
public void AgeInYears_PersonBorn1970_AfterBirthdateIn2019_45()
{
var age = AgeInYears.Between
(new DateTime(1970, 6, 26),
new DateTime(2019, 11, 28));
age.Should().Be(49.Years());
}
[Fact]
public void AgeInYears_PersonBorn1970_BeforeBirthdateIn2019_45()
{
var age = AgeInYears.Between(new DateTime(1970, 6, 26),
new DateTime(2019, 5, 28));
age.Should().Be(49.Years());
}
}
public class SpeakerTests
{
[Fact]
public void Speaker_Born1976_IsAt2021_45YearsOld()
{
var customer = GivenSpeaker()
.BornOn(new DateTime(1976, 6, 26))
.Build();
var ageAt2019 = customer.AgeInYearsAt(new DateTime(2021, 1, 1));
ageAt2019.Should().Be(45.Years());
}
[Fact]
public void Speaker_Born1976_IsAt2022_46YearsOld()
{
var customer = GivenSpeaker()
.BornOn(new DateTime(1976, 6, 26))
.Build();
var ageAt2019 = customer.AgeInYearsAt(new DateTime(2022, 1, 1));
ageAt2019.Should().Be(46.Years());
}
[Fact]
public void Speaker_Born1976_IsAt2023_47YearsOld()
{
var customer = GivenSpeaker()
.BornOn(new DateTime(1976, 6, 26))
.Build();
var ageAt2019 = customer.AgeInYearsAt(new DateTime(2023, 1, 1));
ageAt2019.Should().Be(47.Years());
}
[Fact]
public void Speaker_CannotBeCreatedWithout_Name()
{
Action act = () => new Speaker
(
null,
new DateTime(1974, 6, 26),
new Address("Poland", "00-001", "Warsaw", "Lemonowa 81"),
new SpeakerWebsites(),
""
, new Contact("555-555-555", "c@gmail.com")
);
act
.Should()
.Throw<ArgumentException>()
.WithMessage("Name cannot be null");
}
[Fact]
public void Speaker_CannotBeCreatedWithout_Address()
{
Action act = () => new Speaker
(
new Name("Cezary", "W"),
new DateTime(1974, 6, 26),
null,
new SpeakerWebsites(),
""
, new Contact("555-555-555", "c@gmail.com")
);
act
.Should()
.Throw<ArgumentException>()
.WithMessage("Address cannot be null");
}
[Fact]
public void Speaker_CannotBeCreatedWithout_Birthdate()
{
Action act = () => new Speaker
(
new Name("Cezary", "W"),
default,
new Address("Poland", "00-001", "Warsaw", "Lemonowa 81"),
new SpeakerWebsites(),
""
, new Contact("555-555-555", "c@gmail.com")
);
act
.Should()
.Throw<ArgumentException>()
.WithMessage("Birthdate cannot be empty");
}
[Fact]
public void Speaker_CannotBeCreatedWithout_SpeakerWebsities()
{
Action act = () => new Speaker
(
new Name("Cezary", "W"),
new DateTime(1974, 6, 26),
new Address("Poland", "00-001", "Warsaw", "Lemonowa 81"),
null,
""
, new Contact("555-555-555", "c@gmail.com")
);
act
.Should()
.Throw<ArgumentException>()
.WithMessage("SpeakerWebsites cannot be empty");
}
}
private readonly ScoringRulesFactory scoringRulesFactory
= new ScoringRulesFactory();
[Fact]
public void Speaker_Have_Blog_SpeakerMustHaveBlogOrGitHub_Rule_IsSatisfied()
{
var cfs = GivenCallForSpeech()
.WithSpeaker(speaker => speaker.
WithSpeakerWebsites
(web => web.ClearWebsites()
.WithBlog("http://cezary.pl")))
.Build();
var rule = new SpeakerMustHaveBlogOrGitHub();
var ruleCheckResult = rule.IsSatisfiedBy(cfs);
ruleCheckResult.Should().BeTrue();
}
private readonly ScoringRulesFactory scoringRulesFactory
= new ScoringRulesFactory();
[Fact]
public void Speaker_Have_GitHub_SpeakerMustHaveBlogOrGitHub_Rule_IsSatisfied()
{
var cfs = GivenCallForSpeech()
.WithSpeaker(speaker => speaker.
WithSpeakerWebsites
(web => web.ClearWebsites()
.WithGitHub("https://github.com/PanNiebieski")))
.Build();
var rule = new SpeakerMustHaveBlogOrGitHub();
var ruleCheckResult = rule.IsSatisfiedBy(cfs);
ruleCheckResult.Should().BeTrue();
}
[Fact]
public void Speaker_Age_Is_17_SpeakerAgeMusteBeAbove17_Rule_IsNotSatisfied()
{
var cfs = GivenCallForSpeech()
.WithSpeaker(speaker => speaker.WithAge(17))
.Build();
var rule = new SpeakerAgeMusteBeAbove17();
var ruleCheckResult = rule.IsSatisfiedBy(cfs);
ruleCheckResult.Should().BeFalse();
}
[Fact]
public void Speaker_Age_Is_70_SpeakerAgeMusteBeBelow70_Rule_IsNotSatisfied()
{
var cfs = GivenCallForSpeech()
.WithSpeaker(speaker => speaker.WithAge(70))
.Build();
var rule = new SpeakerAgeMusteBeBelow70();
var ruleCheckResult = rule.IsSatisfiedBy(cfs);
ruleCheckResult.Should().BeFalse();
}
[Fact]
public void Speaker_Doesnt_Have_Any_SocialMedia_SpeakerMustHaveAtLeastOneSocialMedia_IsNotSatisfied()
{
var cfs = GivenCallForSpeech()
.WithSpeaker(speaker =>
speaker.
WithSpeakerWebsites(web => web.ClearWebsites()))
.Build();
var rule = new SpeakerMustHaveAtLeastOneSocialMedia();
var ruleCheckResult = rule.IsSatisfiedBy(cfs);
ruleCheckResult.Should().BeFalse();
}
[Theory]
[ClassData(typeof(SpeakerWebsitesTestData))]
public void Speaker_Does_Have_JustOne_SocialMedia_SpeakerMustHaveAtLeastOneSocialMedia_IsSatisfied(SpeakerWebsites web)
{
var cfs = GivenCallForSpeech()
.WithSpeaker(speaker => speaker.WithSpeakerWebsites(web))
.Build();
var rule = new SpeakerMustHaveAtLeastOneSocialMedia();
var ruleCheckResult = rule.IsSatisfiedBy(cfs);
ruleCheckResult.Should().BeTrue();
}
public class SpeakerWebsitesTestData : IEnumerable<object[]>
{
public IEnumerator<object[]> GetEnumerator()
{
yield return new object[] { new SpeakerWebsites() { Instagram = "http://instagram.pl" } };
yield return new object[] { new SpeakerWebsites() { LinkedIN = "http://linkediIn.pl" } };
yield return new object[] { new SpeakerWebsites() { TikTok = "http://TikTok.pl" } };
yield return new object[] { new SpeakerWebsites() { Twitter = "http://TWITTER.PL" } };
yield return new object[] { new SpeakerWebsites() { YouTube = "http://YOUTUBE.PL" } };
yield return new object[] { new SpeakerWebsites() { FanPageOnFacebook = "http://FACEBOOK.PL" } };
yield return new object[] { new SpeakerWebsites() { Facebook = "http://FACEBOOK.PL" } };
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
public static class CallForSpeechAssertExtension
{
public static CallForSpeechAssert Should
(this CallForSpeech cfs)
=> new CallForSpeechAssert(cfs);
}
public class CallForSpeechAssert :
ReferenceTypeAssertions<CallForSpeech, CallForSpeechAssert>
{
public CallForSpeechAssert(CallForSpeech cfs)
: base(cfs)
{
}
public AndConstraint<CallForSpeechAssert> BeInStatus(CallForSpeechStatus expectedStatus)
{
Subject.Status.Should().Be(expectedStatus);
return new AndConstraint<CallForSpeechAssert>(this);
}
public AndConstraint<CallForSpeechAssert> BeAccepted()
{
return BeInStatus(CallForSpeechStatus.AcceptedByJudge);
}
public AndConstraint<CallForSpeechAssert> BePreliminaryAcceptedByJudge()
{
return BeInStatus(CallForSpeechStatus.PreliminaryAcceptedByJudge);
}
public AndConstraint<CallForSpeechAssert> BeRejected()
{
return BeInStatus(CallForSpeechStatus.Rejected);
}
public AndConstraint<CallForSpeechAssert> BeNew()
{
return BeInStatus(CallForSpeechStatus.New);
}
public AndConstraint<CallForSpeechAssert> BeEvaluatedByMachine()
{
return BeInStatus(CallForSpeechStatus.EvaluatedByMachine);
}
public AndConstraint<CallForSpeechAssert> ScoreIsNull()
{
Subject.Score.Should().BeNull();
return new AndConstraint<CallForSpeechAssert>(this);
}
public AndConstraint<CallForSpeechAssert> ScoreIs(CallForSpeechMachineScore expectedScore)
{
Subject.Score?.Score.Should().Be(expectedScore);
return new AndConstraint<CallForSpeechAssert>(this);
}
public AndConstraint<CallForSpeechAssert> HaveRedScore()
{
return ScoreIs(CallForSpeechMachineScore.Red);
}
public AndConstraint<CallForSpeechAssert> HaveGreenScore()
{
return ScoreIs(CallForSpeechMachineScore.Green);
}
public AndConstraint<CallForSpeechAssert> HaveYellowScore()
{
return ScoreIs(CallForSpeechMachineScore.Yellow);
}
protected override string Identifier => "CallForSpeechAssert";
}
private readonly ScoringRulesFactory scoringRulesFactory = new ScoringRulesFactory();
[Fact]
public void NewCallForSpeech_IsCreatedIn_NewStatus_AndNullScore()
{
var cfs = GivenCallForSpeech()
.WithSpeaker(speaker => speaker.WithAge(25))
.Build();
cfs
.Should()
.BeNew()
.And
.ScoreIsNull();
}
private readonly ScoringRulesFactory scoringRulesFactory = new ScoringRulesFactory();
[Fact]
public void ValidCallForSpeech_EvaluationScore_IsGreen()
{
var cfs = GivenCallForSpeech()
.WithSpeaker(speaker => speaker.WithAge(31))
.WithSpeech(speech =>
speech.WithTechnologyOrBussinessStory
(TechnologyOrBussinessStory.OnlyMyPersonalBussinessStory))
.Build();
cfs.Evaluate(scoringRulesFactory.DefaultSet);
cfs
.Should()
.BeEvaluatedByMachine()
.And
.HaveGreenScore();
}
private readonly ScoringRulesFactory scoringRulesFactory = new ScoringRulesFactory();
[Fact]
public void InvalidCallForSpeech_EvaluationScore_IsRed()
{
var cfs = GivenCallForSpeech()
.WithSpeaker(speaker => speaker.WithAge(17)
.WithSpeakerWebsites(web => web.ClearWebsites()))
.WithSpeech(speech =>
speech.WithTechnologyOrBussinessStory
(TechnologyOrBussinessStory.OnlyMyPersonalBussinessStory))
.Build();
cfs.Evaluate(scoringRulesFactory.DefaultSet);
cfs
.Should()
.BeRejected()
.And
.HaveRedScore();
}
private readonly ScoringRulesFactory scoringRulesFactory = new ScoringRulesFactory();
[Fact]
public void CallForSpeech_InStatusNew_EvaluatedGreen_PreliminaryAccept_Then_Jugde_CanAccept()
{
int catid = 8888;
var cfs = GivenCallForSpeech()
.WithSpeaker(speaker => speaker.WithAge(31))
.WithSpeech(speech =>
speech.WithTechnologyOrBussinessStory
(TechnologyOrBussinessStory.OnlyMyPersonalBussinessStory))
.Evaluated()
.WithCategory(cat => cat.WithId(catid))
.Build();
var judge = GivenJudge().
WithCategory(cat => cat.WithId(catid))
.Build();
cfs.PreliminaryAccept(judge);
cfs.Accept(judge);
cfs
.Should()
.BeAccepted()
.And
.HaveGreenScore();
}
[Fact]
public void CallForSpeech_InStatusNew_EvaluatedGreen_PreliminaryAccepted_Then_JugdeFormDiffrentCategory_CannotAccept()
{
int catid2 = int.MaxValue;
var cfs = GivenCallForSpeech()
.WithSpeaker(speaker => speaker.WithAge(31))
.WithSpeech(speech =>
speech.WithTechnologyOrBussinessStory
(TechnologyOrBussinessStory.OnlyMyPersonalBussinessStory))
.Evaluated()
.PreliminaryAcceptedByJudge()
.Build();
var judge = GivenJudge().
WithCategory(cat => cat.WithId(catid2))
.Build();
Action act = () => cfs.Accept(judge);
act
.Should()
.Throw<ApplicationException>()
.WithMessage("Judge is from diffrent category. Can't Accept");
}
[Fact]
public void CallForSpeech_InStatusNew_EvaluatedGreen_CanBeRejected()
{
int catid = 8888;
var cfs = GivenCallForSpeech()
.WithSpeaker(speaker => speaker.WithAge(31))
.WithSpeech(speech =>
speech.WithTechnologyOrBussinessStory
(TechnologyOrBussinessStory.OnlyMyPersonalBussinessStory))
.Evaluated()
.WithCategory(cat => cat.WithId(catid))
.Build();
var judge = GivenJudge().
WithCategory(cat => cat.WithId(catid))
.Build();
cfs.Reject(judge);
cfs
.Should()
.BeRejected()
.And.HaveGreenScore();
}
[Fact]
public void CallForSpeech_InStatusNew_EvaluatedGreen_PreliminaryAccepted_CanBeRejected()
{
int catid = 8888;
var cfs = GivenCallForSpeech()
.WithSpeaker(speaker => speaker.WithAge(31))
.WithSpeech(speech =>
speech.WithTechnologyOrBussinessStory
(TechnologyOrBussinessStory.OnlyMyPersonalBussinessStory))
.Evaluated()
.WithCategory(cat => cat.WithId(catid))
.Build();
var judge = GivenJudge().
WithCategory(cat => cat.WithId(catid))
.Build();
cfs.PreliminaryAccept(judge);
cfs.Reject(judge);
cfs
.Should()
.BeRejected()
.And.HaveGreenScore();
}
[Fact]
public void CallForSpeech_WithoutScore_NOTEvaluatedByMachine_CanBeRejected()
{
int catid = 8888;
var cfs = GivenCallForSpeech()
.WithCategory(cat => cat.WithId(catid))
.NotEvaluated()
.Build();
var judge = GivenJudge()
.WithCategory(cat => cat.WithId(catid))
.Build();
cfs.Reject(judge);
cfs
.Should()
.BeRejected()
.And.ScoreIsNull();
}
[Fact]
public void CallForSpeec_Accepted_CannotBeRejected()
{
int catid = 8888;
var cfs = GivenCallForSpeech()
.WithCategory(cat => cat.WithId(catid))
.Evaluated()
.Build();
var judge = GivenJudge()
.WithCategory(cat => cat.WithId(catid))
.Build();
cfs.PreliminaryAccept(judge);
cfs.Accept(judge);
Action act = () => cfs.Reject(judge);
act
.Should()
.Throw<ApplicationException>()
.WithMessage("Cannot reject application that is already accepted or rejected");
}
[Fact]
public void CallForSpeec_Accepted_CannotBeRejected()
{
int catid = 8888;
var cfs = GivenCallForSpeech()
.WithCategory(cat => cat.WithId(catid))
.Evaluated()
.Build();
var judge = GivenJudge()
.WithCategory(cat => cat.WithId(catid))
.Build();
cfs.PreliminaryAccept(judge);
cfs.Accept(judge);
Action act = () => cfs.Reject(judge);
act
.Should()
.Throw<ApplicationException>()
.WithMessage("Cannot reject application that is already accepted or rejected");
}
[Fact]
public void CallForSpeec_Accepted_CannotBeRejected()
{
int catid = 8888;
var cfs = GivenCallForSpeech()
.WithCategory(cat => cat.WithId(catid))
.Evaluated()
.Build();
var judge = GivenJudge()
.WithCategory(cat => cat.WithId(catid))
.Build();
cfs.PreliminaryAccept(judge);
cfs.Accept(judge);
Action act = () => cfs.Reject(judge);
act
.Should()
.Throw<ApplicationException>()
.WithMessage("Cannot reject application that is already accepted or rejected");
}
[Fact]
public void CallForSpeec_Rejected_CannotBeRejected()
{
int catid = 8888;
var cfs = GivenCallForSpeech()
.WithCategory(cat => cat.WithId(catid))
.Rejected()
.Build();
var judge = GivenJudge()
.WithCategory(cat => cat.WithId(catid))
.Build();
Action act = () => cfs.Reject(judge);
act
.Should()
.Throw<ApplicationException>()
.WithMessage("Cannot reject application that is already accepted or rejected");
}
[Fact]
public void CallForSpeec_PreliminaryAcceptedByJudge_CanbeAccepted()
{
int catid = 8888;
var cfs = GivenCallForSpeech()
.WithCategory(cat => cat.WithId(catid))
.PreliminaryAcceptedByJudge()
.Build();
var judge = GivenJudge()
.WithCategory(cat => cat.WithId(catid))
.Build();
cfs.Accept(judge);
cfs
.Should()
.BeAccepted();
}
[ApiController]
[Route("[controller]")]
public class EmployeeController : Controller
{
private readonly IMapper _mapper;
public Employee Index()
{
EmployeeDto eDTO = new EmployeeDto()
{
EmployeeId = 121,
FirstName = "Damian",
LastName = "Morfeus",
Login = "frankodomanamiga",
OrganizationCompanyName = "LichyDzwig",
OrganizationId = 34,
Role = "Sprzątacz podłogi pietra 34",
RootOrganizationCompanyName = "Dobra Winda",
RootOrganizationId = 12,
Type = "Sprzątacz"
};
return _mapper.Map<Employee>(eDTO);
}
}
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
CreateMap<EmployeeDto, Employee>();
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="8.1.1" />
<PackageReference Include="FluentValidation" Version="9.5.1" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="9.5.1" />
<PackageReference Include="MediatR" Version="9.0.0" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GeekLemonConference.Application.Common\GeekLemonConference.Application.Common.csproj" />
<ProjectReference Include="..\GeekLemonConference.Application.Contracts\GeekLemonConference.Application.Contracts.csproj" />
<ProjectReference Include="..\GeekLemonConference.Application.EventSourcing\GeekLemonConference.Application.EventSourcing.csproj" />
</ItemGroup>
</Project>
public class CallForSpeechInListViewModel
{
public int Id { get; set; }
public SpeechDto Speech { get; set; }
public CategoryDto Category { get; set; }
public string Status { get; set; }
public int Version { get; set; }
public Guid UniqueId { get; set; }
}
}
public class CallForSpeechInListViewModel
{
public int Id { get; set; }
public SpeechDto Speech { get; set; }
public CategoryDto Category { get; set; }
public string Status { get; set; }
public int Version { get; set; }
public Guid UniqueId { get; set; }
}
public class GetAllCallForSpeechesQuery : IRequest<
GetAllCallForSpeechesQueryHandlerResponse>
{
public FilterCallForSpeechStyles Filter { get; set; }
public QueryWitchDataBase queryWitchDataBase { get; set; }
}
public class GetAllCallForSpeechesQueryHandler :
IRequestHandler<GetAllCallForSpeechesQuery, GetAllCallForSpeechesQueryHandlerResponse>
{
private readonly ICallForSpeechRepository _callRepository;
private readonly IZEsCallForSpeechRepository _zEscallRepository;
private readonly IMapper _mapper;
public GetAllCallForSpeechesQueryHandler(ICallForSpeechRepository callRepository,
IZEsCallForSpeechRepository ZEscallRepository,
IMapper mapper)
{
_mapper = mapper;
_zEscallRepository = ZEscallRepository;
_callRepository = callRepository;
}
public async Task<GetAllCallForSpeechesQueryHandlerResponse>
Handle(GetAllCallForSpeechesQuery request, CancellationToken cancellationToken)
{
ExecutionStatus<IReadOnlyList<CallForSpeech>> databaseresult = null;
if (request.queryWitchDataBase == QueryWitchDataBase.WithEventSourcing)
databaseresult = await _zEscallRepository.GetCollectionAsync(request.Filter);
else
databaseresult = await _callRepository.GetCollectionAsync(request.Filter);
if (databaseresult.Success)
{
var allordered = databaseresult.Value.OrderBy(x => x.Id);
var allmaped = _mapper.Map<List<CallForSpeechInListViewModel>>
(databaseresult.Value);
return new GetAllCallForSpeechesQueryHandlerResponse(allmaped);
}
return new GetAllCallForSpeechesQueryHandlerResponse(databaseresult.RemoveGeneric());
}
}
public class GetAllCallForSpeechesQueryHandlerResponse : BaseResponse
{
public List<CallForSpeechInListViewModel> List { get; }
public GetAllCallForSpeechesQueryHandlerResponse(List<CallForSpeechInListViewModel> lisy)
: base()
{
List = lisy;
}
public GetAllCallForSpeechesQueryHandlerResponse() : base()
{ }
public GetAllCallForSpeechesQueryHandlerResponse(ExecutionStatus status)
: base(status)
{
}
public GetAllCallForSpeechesQueryHandlerResponse(ExecutionStatus status, string message)
: base(status, message)
{
}
public GetAllCallForSpeechesQueryHandlerResponse(ValidationResult validationResult)
: base(validationResult)
{ }
public GetAllCallForSpeechesQueryHandlerResponse(string message)
: base(message)
{ }
public GetAllCallForSpeechesQueryHandlerResponse(string message, bool success)
: base(message, success)
{ }
}
public class CallForSpeechViewModel
{
public int Id { get; set; }
public ScoreDto Score { get; set; }
public SpeakerDto Speaker { get; set; }
public SpeechDto Speech { get; set; }
public DecisionDto PreliminaryDecision { get; set; }
public DecisionDto FinalDecision { get; set; }
public CategoryDto Category { get; set; }
public string Status { get; set; }
public int Version { get; set; }
public Guid UniqueId { get; set; }
}
public class GetCallForSpeechQuery : IRequest<GetCallForSpeechQueryHandlerResponse>
{
public CallForSpeechId CallForSpeechId { get; set; }
public CallForSpeechUniqueId CallForSpeechUniqueId { get; set; }
public QueryWitchDataBase queryWitchDataBase { get; set; }
}
public class GetCallForSpeechQueryHandler :
IRequestHandler<GetCallForSpeechQuery, GetCallForSpeechQueryHandlerResponse>
{
private readonly ICallForSpeechRepository _callRepository;
private readonly IMapper _mapper;
private readonly IZEsCallForSpeechRepository _zEscallRepository;
public GetCallForSpeechQueryHandler(ICallForSpeechRepository callRepository,
IZEsCallForSpeechRepository zEscallRepository,
IMapper mapper)
{
_mapper = mapper;
_zEscallRepository = zEscallRepository;
_callRepository = callRepository;
}
public async Task<GetCallForSpeechQueryHandlerResponse>
Handle(GetCallForSpeechQuery request, CancellationToken cancellationToken)
{
ExecutionStatus<CallForSpeech> databaseOperationCfs = null;
if (request.CallForSpeechUniqueId != null)
if (request.queryWitchDataBase == QueryWitchDataBase.WithEventSourcing)
databaseOperationCfs = await _zEscallRepository.GetByIdAsync(request.CallForSpeechUniqueId);
else
databaseOperationCfs = await _callRepository.GetByIdAsync(request.CallForSpeechUniqueId);
else
if (request.queryWitchDataBase == QueryWitchDataBase.WithEventSourcing)
databaseOperationCfs = await _zEscallRepository.GetByIdAsync(request.CallForSpeechId);
else
databaseOperationCfs = await _callRepository.GetByIdAsync(request.CallForSpeechId);
if (!databaseOperationCfs.Success)
return new GetCallForSpeechQueryHandlerResponse(databaseOperationCfs
.RemoveGeneric());
var cfsMaped = _mapper.Map<CallForSpeechViewModel>(databaseOperationCfs.Value);
return new GetCallForSpeechQueryHandlerResponse(cfsMaped);
}
}
public class GetCallForSpeechQueryHandlerResponse : BaseResponse
{
public CallForSpeechViewModel CallForSpeech { get; }
public GetCallForSpeechQueryHandlerResponse(CallForSpeechViewModel callForSpeech)
: base()
{
CallForSpeech = callForSpeech;
}
public GetCallForSpeechQueryHandlerResponse() : base()
{ }
public GetCallForSpeechQueryHandlerResponse(ExecutionStatus status)
: base(status)
{
}
public GetCallForSpeechQueryHandlerResponse(ExecutionStatus status, string message)
: base(status, message)
{
}
public GetCallForSpeechQueryHandlerResponse(ValidationResult validationResult)
: base(validationResult)
{ }
public GetCallForSpeechQueryHandlerResponse(string message)
: base(message)
{ }
public GetCallForSpeechQueryHandlerResponse(string message, bool success)
: base(message, success)
{ }
}
public class CategoryInListViewModel
{
public int Id { get; set; }
public Guid UniqueId { get; set; }
public string Name { get; init; }
public string DisplayName { get; init; }
public string WhatWeAreLookingFor { get; init; }
}
public class GetCategoriesListQuery
: IRequest<GetCategoriesListQueryResponse>
{
public QueryWitchDataBase queryWitchDataBase { get; set; }
}
public class GetCategoriesListQueryHandler :
IRequestHandler<GetCategoriesListQuery, GetCategoriesListQueryResponse>
{
private readonly ICategoryRepository _categoryRepository;
private readonly IZEsCategoryRepository _zEscategoryRepository;
private readonly IMapper _mapper;
public GetCategoriesListQueryHandler(IMapper mapper,
ICategoryRepository categoryRepository,
IZEsCategoryRepository zEscategoryRepository)
{
_mapper = mapper;
_categoryRepository = categoryRepository;
_zEscategoryRepository = zEscategoryRepository;
}
public async Task<GetCategoriesListQueryResponse> Handle
(GetCategoriesListQuery request, CancellationToken cancellationToken)
{
ExecutionStatus<IReadOnlyList<Category>> databaseOperation = null;
if (request.queryWitchDataBase == QueryWitchDataBase.WithEventSourcing)
databaseOperation = await _zEscategoryRepository.GetAllAsync();
else
databaseOperation = await _categoryRepository.GetAllAsync();
if (!databaseOperation.Success)
return new GetCategoriesListQueryResponse(databaseOperation.RemoveGeneric());
var ordered = databaseOperation.Value.OrderBy(a => a.Name);
var mpaed = _mapper.Map<List<CategoryInListViewModel>>(ordered);
return new GetCategoriesListQueryResponse(mpaed);
}
}
public class GetCategoriesListQueryResponse : BaseResponse
{
public List<CategoryInListViewModel> List { get; }
public GetCategoriesListQueryResponse(List<CategoryInListViewModel> list) : base()
{
List = list;
}
public GetCategoriesListQueryResponse() : base()
{ }
public GetCategoriesListQueryResponse(ExecutionStatus status)
: base(status)
{
}
public GetCategoriesListQueryResponse(ExecutionStatus status, string message)
: base(status, message)
{
}
public GetCategoriesListQueryResponse(ValidationResult validationResult)
: base(validationResult)
{ }
public GetCategoriesListQueryResponse(string message)
: base(message)
{ }
public GetCategoriesListQueryResponse(string message, bool success)
: base(message, success)
{ }
}
public class GetCategoryQuery
: IRequest<GetCategoryQueryResponse>
{
public QueryWitchDataBase queryWitchDataBase { get; set; }
public CategoryId CategoryId { get; set; }
public CategoryUniqueId CategoryUniqueId { get; set; }
}
public class GetCategoryQueryHandler : IRequestHandler<GetCategoryQuery, GetCategoryQueryResponse>
{
private readonly ICategoryRepository _categoryRepository;
private readonly IZEsCategoryRepository _zEscategoryRepository;
private readonly IMapper _mapper;
public GetCategoryQueryHandler(IMapper mapper,
IZEsCategoryRepository zEscategoryRepository,
ICategoryRepository categoryRepository)
{
_mapper = mapper;
_zEscategoryRepository = zEscategoryRepository;
_categoryRepository = categoryRepository;
}
public async Task<GetCategoryQueryResponse> Handle(GetCategoryQuery request,
CancellationToken cancellationToken)
{
ExecutionStatus<Category> databaseOperation = null;
if (request.CategoryUniqueId != null)
if (request.queryWitchDataBase == QueryWitchDataBase.WithEventSourcing)
databaseOperation = await _zEscategoryRepository.GetByIdAsync(request.CategoryUniqueId);
else
databaseOperation = await _categoryRepository.GetByIdAsync(request.CategoryUniqueId);
else
if (request.queryWitchDataBase == QueryWitchDataBase.WithEventSourcing)
databaseOperation = await _zEscategoryRepository.GetByIdAsync(request.CategoryId);
else
databaseOperation = await _categoryRepository.GetByIdAsync(request.CategoryId);
if (!databaseOperation.Success)
return new GetCategoryQueryResponse(databaseOperation.RemoveGeneric());
var categorydto = _mapper.Map<CategoryDto>(databaseOperation.Value);
return new GetCategoryQueryResponse(categorydto);
}
}
public class GetCategoryQueryResponse : BaseResponse
{
public CategoryDto Category { get; }
public GetCategoryQueryResponse(CategoryDto cat)
: base()
{
Category = cat;
}
public GetCategoryQueryResponse() : base()
{ }
public GetCategoryQueryResponse(ExecutionStatus status)
: base(status)
{
}
public GetCategoryQueryResponse(ExecutionStatus status, string message)
: base(status, message)
{
}
public GetCategoryQueryResponse(ValidationResult validationResult)
: base(validationResult)
{ }
public GetCategoryQueryResponse(string message)
: base(message)
{ }
public GetCategoryQueryResponse(string message, bool success)
: base(message, success)
{ }
}
public class GetJudgesInListQuery
: IRequest<GetJudgesInListQueryResponse>
{
public QueryWitchDataBase queryWitchDataBase
{ get; set; }
}
public class GetJudgesInListQueryHandler :
IRequestHandler<GetJudgesInListQuery, GetJudgesInListQueryResponse>
{
private readonly IJudgeRepository _judgeRepository;
private readonly IZEsJudgeRepository _zEsjudgeRepository;
private readonly IMapper _mapper;
public GetJudgesInListQueryHandler(IMapper mapper,
IJudgeRepository judgeRepository,
IZEsJudgeRepository zEsjudgeRepository)
{
_mapper = mapper;
_judgeRepository = judgeRepository;
_zEsjudgeRepository = zEsjudgeRepository;
}
public async Task<GetJudgesInListQueryResponse> Handle
(GetJudgesInListQuery request, CancellationToken cancellationToken)
{
ExecutionStatus<IReadOnlyList<Judge>> databaseoperation =
null;
if (request.queryWitchDataBase == QueryWitchDataBase.WithEventSourcing)
databaseoperation = await _zEsjudgeRepository.GetAllAsync();
else
databaseoperation = await _judgeRepository.GetAllAsync();
if (!databaseoperation.Success)
return new GetJudgesInListQueryResponse
(databaseoperation.RemoveGeneric());
var ordered = databaseoperation.Value.OrderBy(a => a.Name.Last);
var maped = _mapper.Map<List<JudgesInListViewModel>>(ordered);
return new GetJudgesInListQueryResponse(maped);
}
}
public class JudgesInListViewModel
{
public int Id { get; set; }
public NameDto Name { get; set; }
public string CategoryName { get; set; }
public string CategoryDisplayName { get; set; }
public int Version { get; set; }
public Guid UniqueId { get; set; }
}
public class GetJudgesInListQueryResponse : BaseResponse
{
public List<JudgesInListViewModel> List { get; }
public GetJudgesInListQueryResponse(List<JudgesInListViewModel> list)
: base()
{
List = list;
}
public GetJudgesInListQueryResponse() : base()
{ }
public GetJudgesInListQueryResponse(ExecutionStatus status)
: base(status)
{
}
public GetJudgesInListQueryResponse(ExecutionStatus status, string message)
: base(status, message)
{
}
public GetJudgesInListQueryResponse(ValidationResult validationResult)
: base(validationResult)
{ }
public GetJudgesInListQueryResponse(string message)
: base(message)
{ }
public GetJudgesInListQueryResponse(string message, bool success)
: base(message, success)
{ }
}
public class JudgeViewModel
{
public int Id { get; set; }
public Guid UniqueId { get; set; }
public string Login { get; set; }
public NameDto Name { get; set; }
public CategoryDto Category { get; set; }
public DateTime Birthdate { get; set; }
public int Version { get; set; }
}
public class GetJudgeQuery :
IRequest<GetJudgeQueryResponse>
{
public JudgeId JudeId { get; set; }
public JudgeUniqueId JudgeUniqueId { get; set; }
public QueryWitchDataBase queryWitchDataBase { get; set; }
}
public class GetJudgeQueryHandler :
IRequestHandler<GetJudgeQuery, GetJudgeQueryResponse>
{
private readonly IJudgeRepository _judgeRepository;
private readonly IMapper _mapper;
private readonly IZEsJudgeRepository _zEsjudgeRepository;
public GetJudgeQueryHandler(IMapper mapper,
IJudgeRepository judgeRepository,
IZEsJudgeRepository zEsjudgeRepository)
{
_mapper = mapper;
_judgeRepository = judgeRepository;
_zEsjudgeRepository = zEsjudgeRepository;
}
public async Task<GetJudgeQueryResponse> Handle
(GetJudgeQuery request, CancellationToken cancellationToken)
{
ExecutionStatus<Judge> databaseoperation;
if (request.JudgeUniqueId != null)
if (request.queryWitchDataBase == QueryWitchDataBase.WithEventSourcing)
databaseoperation = await _zEsjudgeRepository.GetByIdAsync(request.JudgeUniqueId);
else
databaseoperation = await _judgeRepository.GetByIdAsync(request.JudgeUniqueId);
else
if (request.queryWitchDataBase == QueryWitchDataBase.WithEventSourcing)
databaseoperation = await _zEsjudgeRepository.GetByIdAsync(request.JudeId);
else
databaseoperation = await _judgeRepository.GetByIdAsync(request.JudeId);
if (!databaseoperation.Success)
return new GetJudgeQueryResponse(databaseoperation.RemoveGeneric());
var judgeViewModel = _mapper.Map<JudgeViewModel>(databaseoperation.Value);
return new GetJudgeQueryResponse(judgeViewModel);
}
}
public class GetJudgeQueryResponse : BaseResponse
{
public JudgeViewModel Judge { get; }
public GetJudgeQueryResponse(JudgeViewModel judge)
: base()
{
Judge = judge;
}
public GetJudgeQueryResponse() : base()
{ }
public GetJudgeQueryResponse(ExecutionStatus status)
: base(status)
{
}
public GetJudgeQueryResponse(ExecutionStatus status, string message)
: base(status, message)
{
}
public GetJudgeQueryResponse(ValidationResult validationResult)
: base(validationResult)
{ }
public GetJudgeQueryResponse(string message)
: base(message)
{ }
public GetJudgeQueryResponse(string message, bool success)
: base(message, success)
{ }
}
public class CreatedCategoryCommand : IRequest<CreatedCategoryCommandResponse>
{
public string Name { get; set; }
public string DisplayName { get; set; }
public string WhatWeAreLookingFor { get; set; }
internal int Version { get; }
internal CategoryUniqueId UniqueId { get; }
public CreatedCategoryCommand()
{
UniqueId = CategoryUniqueId.NewUniqueId();
Version = 0;
}
}
public class CreatedCategoryCommandHandler
: IRequestHandler<CreatedCategoryCommand, CreatedCategoryCommandResponse>
{
private readonly ICategoryRepository _categoryRepository;
private readonly IMapper _mapper;
public CreatedCategoryCommandHandler(ICategoryRepository categoryRepository,
IMapper mapper)
{
_mapper = mapper;
_categoryRepository = categoryRepository;
}
public async Task<CreatedCategoryCommandResponse> Handle
(CreatedCategoryCommand request, CancellationToken cancellationToken)
{
var validator = new CreatedCategoryCommandValidator();
var validatorResult = await validator.ValidateAsync(request);
if (!validatorResult.IsValid)
return new CreatedCategoryCommandResponse(validatorResult);
var category = _mapper.Map<Category>(request);
category.Version = category.Version + 1;
var databaseResult = await _categoryRepository.AddAsync(category);
if (!databaseResult.Success)
return new CreatedCategoryCommandResponse(databaseResult.RemoveGeneric());
var Idsdto = _mapper.Map<IdsDto>(databaseResult.Value);
return new CreatedCategoryCommandResponse(Idsdto);
}
}
public class CreatedCategoryCommandValidator :
AbstractValidator<CreatedCategoryCommand>
{
public CreatedCategoryCommandValidator()
{
RuleFor(c => c.Name)
.MinimumLength(2).MaximumLength(15)
.WithMessage("{PropertName} Length is beewten 2 and 15");
RuleFor(c => c.DisplayName)
.MinimumLength(2).MaximumLength(15)
.WithMessage("{PropertName} Length is beewten 2 and 15");
}
}
public class CreatedCategoryCommandResponse : BaseResponse
{
public IdsDto CategoryIds { get; set; }
public CreatedCategoryCommandResponse(IdsDto categoryIds)
: base()
{
CategoryIds = categoryIds;
}
public CreatedCategoryCommandResponse() : base()
{ }
public CreatedCategoryCommandResponse(ExecutionStatus status)
: base(status)
{
}
public CreatedCategoryCommandResponse(ExecutionStatus status, string message)
: base(status, message)
{
}
public CreatedCategoryCommandResponse(ValidationResult validationResult)
: base(validationResult)
{ }
public CreatedCategoryCommandResponse(string message)
: base(message)
{ }
public CreatedCategoryCommandResponse(string message, bool success)
: base(message, success)
{ }
}
public class IdsDto
{
public int CreatedId { get; set; }
public Guid UniqueId { get; set; }
public string Status { get; set; }
}
public class UpdateCategoryCommand
: IRequest<UpdateCategoryCommandResponse>
{
public Guid? UniqueId { get; set; }
public int? Id { get; set; }
public string Name { get; set; }
public string DisplayName { get; set; }
public string WhatWeAreLookingFor { get; set; }
}
public class UpdateCategoryCommandValidator :
AbstractValidator<UpdateCategoryCommand>
{
public UpdateCategoryCommandValidator()
{
RuleFor(c => c.Name)
.MinimumLength(2).MaximumLength(15)
.WithMessage("{PropertName} Length is beewten 2 and 15");
RuleFor(c => c.DisplayName)
.MinimumLength(2).MaximumLength(15)
.WithMessage("{PropertName} Length is beewten 2 and 15");
}
}
public class UpdateCategoryCommandHandler : IRequestHandler
<UpdateCategoryCommand, UpdateCategoryCommandResponse>
{
private readonly ICategoryRepository _categoryRepository;
private readonly IMapper _mapper;
public UpdateCategoryCommandHandler(ICategoryRepository categoryRepository,
IMapper mapper)
{
_mapper = mapper;
_categoryRepository = categoryRepository;
}
public async Task<UpdateCategoryCommandResponse> Handle
(UpdateCategoryCommand request, CancellationToken cancellationToken)
{
var validator = new UpdateCategoryCommandValidator();
var validatorResult = await validator.ValidateAsync(request);
if (!validatorResult.IsValid)
return new UpdateCategoryCommandResponse(validatorResult);
var catdtoegory = _mapper.Map<CategoryDto>(request);
var category = _mapper.Map<Category>(catdtoegory);
ExecutionStatus result;
if (request.UniqueId != null)
result = await _categoryRepository.UpdateByUniqueIdAsync(category);
else
result = await _categoryRepository.UpdateByIdAsync(category);
return new UpdateCategoryCommandResponse(result);
}
}
public class UpdateCategoryCommandResponse : BaseResponse
{
public UpdateCategoryCommandResponse() : base()
{ }
public UpdateCategoryCommandResponse(ExecutionStatus status)
: base(status)
{
}
public UpdateCategoryCommandResponse(ExecutionStatus status, string message)
: base(status, message)
{
}
public UpdateCategoryCommandResponse(ValidationResult validationResult)
: base(validationResult)
{ }
public UpdateCategoryCommandResponse(string message)
: base(message)
{ }
public UpdateCategoryCommandResponse(string message, bool success)
: base(message, success)
{ }
}
public class CreateJudgeCommand : IRequest<CreateJudgeCommandResponse>
{
public string Login { get; set; }
public string Password { get; set; }
public NameDto Name { get; set; }
internal int Version { get; set; }
internal JudgeUniqueId UniqueId { get; }
public CreateJudgeCommand()
{
UniqueId = JudgeUniqueId.New();
Version = 0;
}
public int CategoryId { get; set; }
public CategoryDto Category
{
get
{
return new CategoryDto() { Id = CategoryId };
}
}
public DateTime Birthdate { get; set; }
}
public class CreateJudgeCommandHandler
: IRequestHandler<CreateJudgeCommand, CreateJudgeCommandResponse>
{
private readonly IJudgeRepository _judgeRepository;
private readonly IMapper _mapper;
public CreateJudgeCommandHandler(IJudgeRepository judgeRepository,
IMapper mapper)
{
_mapper = mapper;
_judgeRepository = judgeRepository;
}
public async Task<CreateJudgeCommandResponse>
Handle(CreateJudgeCommand request, CancellationToken cancellationToken)
{
var validator = new CreateJudgeCommandValidator();
var validatorResult = await validator.ValidateAsync(request);
if (!validatorResult.IsValid)
return new CreateJudgeCommandResponse(validatorResult);
var judge = _mapper.Map<Judge>(request);
var databaseoperation = await _judgeRepository.AddAsync(judge);
if (!databaseoperation.Success)
return new CreateJudgeCommandResponse
(databaseoperation.RemoveGeneric());
var Idsdto = _mapper.Map<IdsDto>(databaseoperation.Value);
return new CreateJudgeCommandResponse(Idsdto);
}
}
public class CreateJudgeCommandResponse : BaseResponse
{
public IdsDto JudgeIds { get; set; }
public CreateJudgeCommandResponse() : base()
{ }
public CreateJudgeCommandResponse(ExecutionStatus status)
: base(status)
{
}
public CreateJudgeCommandResponse(ExecutionStatus status, string message)
: base(status, message)
{
}
public CreateJudgeCommandResponse(ValidationResult validationResult)
: base(validationResult)
{ }
public CreateJudgeCommandResponse(string message)
: base(message)
{ }
public CreateJudgeCommandResponse(string message, bool success)
: base(message, success)
{ }
public CreateJudgeCommandResponse(IdsDto judgeIds)
{
JudgeIds = judgeIds;
}
}
public class DeleteJudgeCommand
: IRequest<DeleteJudgeCommandResponse>
{
public JudgeUniqueId UniqueId { get; set; }
public JudgeId Id { get; set; }
}
public class DeleteJudgeCommandHandler
: IRequestHandler<DeleteJudgeCommand, DeleteJudgeCommandResponse>
{
private readonly IJudgeRepository _judgeRepository;
private readonly IMapper _mapper;
public DeleteJudgeCommandHandler(IJudgeRepository judgeRepository,
IMapper mapper)
{
_mapper = mapper;
_judgeRepository = judgeRepository;
}
public async Task<DeleteJudgeCommandResponse>
Handle(DeleteJudgeCommand request, CancellationToken cancellationToken)
{
ExecutionStatus databaseOperation;
if (request.UniqueId != null)
databaseOperation = await _judgeRepository.DeleteAsync(
request.UniqueId);
else
databaseOperation = await _judgeRepository.DeleteAsync(
request.Id);
return new DeleteJudgeCommandResponse(databaseOperation);
}
}
public class UpdateJudgeCommand : IRequest<UpdateJudgeCommandResponse>
{
public Guid? UniqueId { get; set; }
public int? Id { get; set; }
public string Login { get; set; }
public string Password { get; set; }
public NameDto Name { get; set; }
public int CategoryId { get; set; }
public CategoryDto Category
{
get
{
return new CategoryDto() { Id = CategoryId };
}
}
public DateTime Birthdate { get; set; }
}
public class UpdateJudgeCommandHandler
: IRequestHandler<UpdateJudgeCommand, UpdateJudgeCommandResponse>
{
private readonly IJudgeRepository _judgeRepository;
private readonly IMapper _mapper;
public UpdateJudgeCommandHandler(IJudgeRepository judgeRepository,
IMapper mapper)
{
_mapper = mapper;
_judgeRepository = judgeRepository;
}
public async Task<UpdateJudgeCommandResponse> Handle
(UpdateJudgeCommand request, CancellationToken cancellationToken)
{
var validator = new UpdateJudgeCommandValidator();
var validatorResult = await validator.ValidateAsync(request);
if (!validatorResult.IsValid)
return new UpdateJudgeCommandResponse(validatorResult);
var judgedto = _mapper.Map<JudgeDto>(request);
var judge = _mapper.Map<Judge>(judgedto);
ExecutionStatus statu;
if (request.UniqueId != null)
statu = await _judgeRepository.UpdateByUniqueIdAsync(judge);
else
statu = await _judgeRepository.UpdateByIdAsync(judge);
if (statu.Success)
return new UpdateJudgeCommandResponse();
else
return new UpdateJudgeCommandResponse(statu);
}
}
public class SubmitCallForSpeechCommand
: IRequest<SubmitCallForSpeechCommandResponse>
{
public int CategoryId { get; set; }
public CategoryDto Category
{
get
{
return new CategoryDto() { Id = CategoryId };
}
}
internal int Version { get; private set; }
internal CallForSpeechUniqueId UniqueId { get; set; }
public SubmitCallForSpeechCommand()
{
UniqueId = CallForSpeechUniqueId.NewUniqueId();
Version = 0;
}
public SpeakerDto Speaker { get; set; }
public SpeechDto Speech { get; set; }
public string Number { get; set; }
public RegistrationDto Registration
{
get
{
return new RegistrationDto()
{
RegistrationDate = AppTime.Now()
};
}
}
}
public class SubmitCallForSpeechCommandValidator :
AbstractValidator<SubmitCallForSpeechCommand>
{
public SubmitCallForSpeechCommandValidator()
{
// Tutaj wstaw walidację
}
}
public class SubmitCallForSpeechCommandHandler :
IRequestHandler<SubmitCallForSpeechCommand, SubmitCallForSpeechCommandResponse>
{
private readonly ICallForSpeechRepository _callRepository;
private readonly IMapper _mapper;
public SubmitCallForSpeechCommandHandler(ICallForSpeechRepository callRepository,
IMapper mapper)
{
_mapper = mapper;
_callRepository = callRepository;
}
public async Task<SubmitCallForSpeechCommandResponse>
Handle(SubmitCallForSpeechCommand request, CancellationToken cancellationToken)
{
var validator = new SubmitCallForSpeechCommandValidator();
var validatorResult = await validator.ValidateAsync(request);
if (!validatorResult.IsValid)
return new SubmitCallForSpeechCommandResponse(validatorResult);
var cfs = _mapper.Map<CallForSpeech>(request);
var id = await _callRepository.SubmitAsync(cfs);
if (!id.Success)
return new SubmitCallForSpeechCommandResponse();
return new SubmitCallForSpeechCommandResponse(id.Value);
}
}
public class SubmitCallForSpeechCommandResponse : BaseResponse
{
public CallForSpeechIds CallForSpeechCommandIds { get; set; }
public SubmitCallForSpeechCommandResponse() : base()
{ }
public SubmitCallForSpeechCommandResponse(ExecutionStatus status)
: base(status)
{
}
public SubmitCallForSpeechCommandResponse(ExecutionStatus status, string message)
: base(status, message)
{
}
public SubmitCallForSpeechCommandResponse(ValidationResult validationResult)
: base(validationResult)
{ }
public SubmitCallForSpeechCommandResponse(string message)
: base(message)
{ }
public SubmitCallForSpeechCommandResponse(string message, bool success)
: base(message, success)
{ }
public SubmitCallForSpeechCommandResponse(CallForSpeechIds callForSpeechid)
{
CallForSpeechCommandIds = callForSpeechid;
}
}
public class EvaluateCallForSpeechCommand
: IRequest<EvaluateCallForSpeechCommandResponse>
{
public Guid CallForSpeechUniqueId { get; set; }
}
public class EvaluateCallForSpeechCommandHandler :
IRequestHandler<EvaluateCallForSpeechCommand,
EvaluateCallForSpeechCommandResponse>
{
private readonly ICallForSpeechRepository _callRepository;
private readonly IScoringRulesFactory _scoringRulesFactory;
private readonly IMapper _mapper;
public EvaluateCallForSpeechCommandHandler(ICallForSpeechRepository callRepository,
IScoringRulesFactory scoringRulesFactory, IMapper mapper)
{
_scoringRulesFactory = scoringRulesFactory;
_callRepository = callRepository;
_mapper = mapper;
}
public async Task<EvaluateCallForSpeechCommandResponse> Handle(EvaluateCallForSpeechCommand request,
CancellationToken cancellationToken)
{
var idc = new CallForSpeechUniqueId(request.CallForSpeechUniqueId);
var databaseOperation = await _callRepository.GetByIdAsync(idc);
if (databaseOperation.Success == false)
{
if (databaseOperation.Reason == Reason.ReturnedNull)
return new EvaluateCallForSpeechCommandResponse(ResponseStatus.BadQuery);
if (databaseOperation.Reason == Reason.Error)
return new EvaluateCallForSpeechCommandResponse(ResponseStatus.DataBaseError);
}
//try
//{
// cfs.Evaluate(_scoringRulesFactory.DefaultSet);
//}
//catch (Exception ex)
//{
// return new EvaluateCallForSpeechCommandResponse();
//}
var cfs = databaseOperation.Value;
var result = cfs.TryEvaluate(_scoringRulesFactory.DefaultSet);
if (!result.Success)
return new EvaluateCallForSpeechCommandResponse(result);
var saveop = await _callRepository.SaveEvaluatationAsync(idc, cfs.Score, cfs.Status);
if (!saveop.Success)
return new EvaluateCallForSpeechCommandResponse(saveop);
var scoredto = _mapper.Map<ScoreDto>(cfs.Score);
return new EvaluateCallForSpeechCommandResponse(scoredto);
}
}
public class RejectCallForSpeechCommand :
IRequest<RejectCallForSpeechCommandResponse>
{
public Guid CallForSpeechUniqueId { get; set; }
public int JudgeId { get; set; }
}
public class RejectCallForSpeechCommandHandler :
IRequestHandler<RejectCallForSpeechCommand, RejectCallForSpeechCommandResponse>
{
private readonly ICallForSpeechRepository _callRepository;
private readonly IJudgeRepository _judegRepository;
private readonly IMapper _mapper;
public RejectCallForSpeechCommandHandler(ICallForSpeechRepository callRepository,
IJudgeRepository judegRepository, IMapper mapper
)
{
_callRepository = callRepository;
_judegRepository = judegRepository;
_mapper = mapper;
}
public async Task<RejectCallForSpeechCommandResponse>
Handle(RejectCallForSpeechCommand request, CancellationToken cancellationToken)
{
var cfsuniqueId = _mapper.Map<CallForSpeechUniqueId>(request.CallForSpeechUniqueId);
var judgeId = _mapper.Map<JudgeId>(request.JudgeId);
var databaseOperationCfs = await _callRepository.GetByIdAsync(cfsuniqueId);
var databaseOperationJudge = await _judegRepository.GetByIdAsync(judgeId);
if (!databaseOperationCfs.Success)
{
if (databaseOperationCfs.Reason == Reason.ReturnedNull)
return new RejectCallForSpeechCommandResponse(ResponseStatus.NotFoundInDataBase);
if (databaseOperationCfs.Reason == Reason.Error)
return new RejectCallForSpeechCommandResponse(ResponseStatus.DataBaseError);
}
if (!databaseOperationJudge.Success)
{
if (databaseOperationJudge.Reason == Reason.ReturnedNull)
return new RejectCallForSpeechCommandResponse(ResponseStatus.NotFoundInDataBase);
if (databaseOperationJudge.Reason == Reason.Error)
return new RejectCallForSpeechCommandResponse(ResponseStatus.DataBaseError);
}
var cfs = databaseOperationCfs.Value;
var judge = databaseOperationJudge.Value;
var result = cfs.TryReject(judge);
if (!result.Success)
return new RejectCallForSpeechCommandResponse(result);
await _callRepository.SaveRejectionAsync(cfsuniqueId, judgeId, cfs.Status);
return new RejectCallForSpeechCommandResponse();
}
}
public class PreliminaryAcceptCallForSpeechCommand
:
IRequest<PreliminaryAcceptCallForSpeechCommandResponse>
{
public Guid CallForSpeechUniqueId { get; set; }
public int JudgeId { get; set; }
}
public class PreliminaryAcceptCallForSpeechCommandHandler :
IRequestHandler<PreliminaryAcceptCallForSpeechCommand, PreliminaryAcceptCallForSpeechCommandResponse>
{
private readonly ICallForSpeechRepository _callRepository;
private readonly IJudgeRepository _judegRepository;
private readonly IMapper _mapper;
public PreliminaryAcceptCallForSpeechCommandHandler(ICallForSpeechRepository callRepository,
IJudgeRepository judegRepository, IMapper mapper
)
{
_callRepository = callRepository;
_judegRepository = judegRepository;
_mapper = mapper;
}
public async Task<PreliminaryAcceptCallForSpeechCommandResponse>
Handle(PreliminaryAcceptCallForSpeechCommand request, CancellationToken cancellationToken)
{
var cfsuniqueId = _mapper.Map<CallForSpeechUniqueId>(request.CallForSpeechUniqueId);
var judgeId = _mapper.Map<JudgeId>(request.JudgeId);
var databaseOperationCfs = await _callRepository.GetByIdAsync(cfsuniqueId);
var databaseOperationJudge = await _judegRepository.GetByIdAsync(judgeId);
if (!databaseOperationCfs.Success)
return new PreliminaryAcceptCallForSpeechCommandResponse(databaseOperationCfs
.RemoveGeneric(), "CallForSpeech Problem");
if (!databaseOperationJudge.Success)
return new PreliminaryAcceptCallForSpeechCommandResponse(databaseOperationJudge
.RemoveGeneric(), "Judge Problem");
var cfs = databaseOperationCfs.Value;
var result = cfs.TryPreliminaryAccept(databaseOperationJudge.Value);
if (!result.Success)
return new PreliminaryAcceptCallForSpeechCommandResponse(result);
await _callRepository.SavePreliminaryAcceptenceAsync(cfsuniqueId, judgeId, cfs.Status);
return new PreliminaryAcceptCallForSpeechCommandResponse();
}
}
public class AcceptCallForSpeechCommand :
IRequest<AcceptCallForSpeechCommandResponse>
{
public Guid CallForSpeechUniqueId { get; set; }
public int JudgeId { get; set; }
}
public class AcceptCallForSpeechComandHandler
: IRequestHandler<AcceptCallForSpeechCommand, AcceptCallForSpeechCommandResponse>
{
private readonly ICallForSpeechRepository _callRepository;
private readonly IJudgeRepository _judegRepository;
private readonly IMapper _mapper;
public AcceptCallForSpeechComandHandler(ICallForSpeechRepository callRepository,
IJudgeRepository judegRepository, IMapper mapper
)
{
_callRepository = callRepository;
_judegRepository = judegRepository;
_mapper = mapper;
}
public async Task<AcceptCallForSpeechCommandResponse>
Handle(AcceptCallForSpeechCommand request, CancellationToken cancellationToken)
{
var cfsuniqueId = _mapper.Map<CallForSpeechUniqueId>(request.CallForSpeechUniqueId);
var judgeId = _mapper.Map<JudgeId>(request.JudgeId);
var databaseOperationCfs = await _callRepository.GetByIdAsync(cfsuniqueId);
var databaseOperationJudge = await _judegRepository.GetByIdAsync(judgeId);
if (!databaseOperationCfs.Success)
{
if (databaseOperationCfs.Reason == Reason.ReturnedNull)
return new AcceptCallForSpeechCommandResponse(ResponseStatus.NotFoundInDataBase);
if (databaseOperationCfs.Reason == Reason.Error)
return new AcceptCallForSpeechCommandResponse(ResponseStatus.DataBaseError);
}
if (!databaseOperationJudge.Success)
{
if (databaseOperationJudge.Reason == Reason.ReturnedNull)
return new AcceptCallForSpeechCommandResponse(ResponseStatus.NotFoundInDataBase);
if (databaseOperationJudge.Reason == Reason.Error)
return new AcceptCallForSpeechCommandResponse(ResponseStatus.DataBaseError);
}
var cfs = databaseOperationCfs.Value;
var judge = databaseOperationJudge.Value;
var result = cfs.TryAccept(judge);
if (!result.Success)
return new AcceptCallForSpeechCommandResponse(result);
var saveop = await _callRepository.SaveAcceptenceAsync(cfsuniqueId, judgeId, cfs.Status);
return new AcceptCallForSpeechCommandResponse(saveop);
}
}
public class AddressDto
{
public string Country { get; set; }
public string ZipCode { get; set; }
public string City { get; set; }
public string Street { get; set; }
}
public class CallForSpeechNumberDto
{
public string Number { get; set; }
}
public class ContactDto
{
public string Phone { get; set; }
public string Email { get; set; }
}
public class DecisionDto
{
public DateTime DecisionDate { get; set; }
}
public class JudgeDto
{
public Guid UniqueId { get; set; }
public int Id { get; set; }
public string Login { get; set; }
public string Password { get; set; }
public NameDto Name { get; set; }
public CategoryDto Category { get; set; }
public int Version { get; set; }
public DateTime Birthdate { get; }
}
public class NameDto
{
public string First { get; set; }
public string Last { get; set; }
}
public class RegistrationDto
{
public DateTime RegistrationDate { get; set; }
}
public class ScoreDto
{
public string Score { get; set; }
public string RejectExplanation { get; set; }
public string WarringExplanation { get; set; }
}
public enum CallForSpeechMachineScoreDto
{
None = 0,
Red = 1, //Rejected
Yellow = 2, //WithWarrings
Green = 3, //AllOkej
}
public class SpeakerDto
{
public DateTime Birthdate { get; set; }
public NameDto Name { get; set; }
public AddressDto Address { get; set; }
public SpeakerWebsitesDto SpeakerWebsites { get; set; }
public string Biography { get; set; }
public ContactDto Contact { get; set; }
}
public class SpeakerWebsitesDto
{
public string Facebook { get; set; }
public string LinkedIN { get; set; }
public string Twitter { get; set; }
public string Instagram { get; set; }
public string TikTok { get; set; }
public string YouTube { get; set; }
public string FanPageOnFacebook { get; set; }
public string GitHub { get; set; }
public string Blog { get; set; }
}
public class SpeechDto
{
public string Title { get; set; }
public string Description { get; set; }
public string[] Tags { get; set; }
public string ForWhichAudience { get; set; }
public string TechnologyOrBussinessStory { get; set; }
}
public class CategoryDto
{
public int Id { get; set; }
public string Name { get; set; }
public string DisplayName { get; set; }
public string WhatWeAreLookingFor { get; set; }
public int Version { get; set; }
public Guid UniqueId { get; set; }
}
public class MappingIds : Profile
{
public MappingIds()
{
CreateMap<int, JudgeId>().ConstructUsing(c => new JudgeId(c));
CreateMap<int, CallForSpeechId>().ConstructUsing(c => new CallForSpeechId(c));
CreateMap<int, CategoryId>().ConstructUsing(c => new CategoryId(c));
CreateMap<JudgeId, int>().ConstructUsing(c => c.Value);
CreateMap<CallForSpeechId, int>().ConstructUsing(c => c.Value);
CreateMap<CategoryId, int>().ConstructUsing(c => c.Value);
CreateMap<JudgeUniqueId, Guid>().ConstructUsing(c => c.Value);
CreateMap<CategoryUniqueId, Guid>().ConstructUsing(c => c.Value);
CreateMap<CallForSpeechUniqueId, Guid>().ConstructUsing(c => c.Value);
CreateMap<Guid, CategoryUniqueId>().ConstructUsing(c =>
new CategoryUniqueId(c));
CreateMap<Guid, JudgeUniqueId>().ConstructUsing(c =>
new JudgeUniqueId(c));
CreateMap<Guid, CallForSpeechUniqueId>().ConstructUsing(c =>
new CallForSpeechUniqueId(c));
CreateMap<String, CategoryUniqueId>().ConstructUsing(c =>
new CategoryUniqueId(Guid.Parse(c)));
CreateMap<String, JudgeUniqueId>().ConstructUsing(c =>
new JudgeUniqueId(Guid.Parse(c)));
CreateMap<String, CallForSpeechUniqueId>().ConstructUsing(c =>
new CallForSpeechUniqueId(Guid.Parse(c)));
}
}
public class MappingToString : Profile
{
public MappingToString()
{
//Judge
CreateMap<string, Login>().ConstructUsing(c => new Login(c));
CreateMap<string, Password>().ConstructUsing(c => new Password(c));
CreateMap<CallForSpeechNumber, string>().ConstructUsing(o => o.Number);
CreateMap<string, CallForSpeechNumber>().ConstructUsing(o => new CallForSpeechNumber(o));
CreateMap<ForWhichAudience, string>().ConvertUsing(c => c.ToString());
CreateMap<TechnologyOrBussinessStory, string>().ConvertUsing(c => c.ToString());
CreateMap<string, ForWhichAudience>()
.ConvertUsing(c => c.ParseEnum<ForWhichAudience>());
CreateMap<string, TechnologyOrBussinessStory>()
.ConvertUsing(c => c.ParseEnum<TechnologyOrBussinessStory>());
}
}
public static class Helper
{
public static T ParseEnum<T>(this string value)
{
return (T)Enum.Parse(typeof(T), value, true);
}
}
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<CreatedCategoryCommand, Category>();
CreateMap<EsUpdateCategoryCommand, Category>();
CreateMap<UpdateCategoryCommand, CategoryDto>();
CreateMap<ESCreateCategoryCommand, Category>();
CreateMap<CreateJudgeCommand, Judge>();
CreateMap<UpdateJudgeCommand, JudgeDto>();
CreateMap<JudgeDto, Judge>();
CreateMap<EsCreateJudgeCommand, Judge>();
CreateMap<EsUpdateJudgeCommand, JudgeDto>();
CreateMap<SubmitCallForSpeechCommand, CallForSpeech>();
CreateMap<EsSubmitCallForSpeechCommand, CallForSpeech>();
CreateMap<Category, CategoryInListViewModel>()
.ForMember(s => s.Id, o => o.MapFrom(k => k.Id.Value));
CreateMap<Judge, JudgesInListViewModel>()
.ForMember(s => s.Id, o => o.MapFrom(k => k.Id.Value));
CreateMap<JudgesInListViewModel, Judge>()
.ForMember(s => s.Id, o => o.MapFrom(k => new JudgeId(k.Id)));
CreateMap<JudgeViewModel, Judge>()
.ForMember(s => s.Id, o => o.MapFrom(k => new JudgeId(k.Id)));
CreateMap<Judge, JudgeViewModel>()
.ForMember(s => s.Id, o => o.MapFrom(k => k.Id.Value));
CreateMap<UpdateJudgeCommand, Judge>();
CreateMap<CallForSpeech, CallForSpeechViewModel>()
.ForMember(s => s.Id, o => o.MapFrom(k => k.Id.Value))
.ForMember(s => s.Status, o => o.MapFrom(k => k.Status.ToString()));
CreateMap<CallForSpeechViewModel, CallForSpeech>()
.ForMember(s => s.Id, o => o.MapFrom(k => new CallForSpeechId(k.Id)))
.ForMember(s => s.Status, o => o.MapFrom(k =>
k.Status.ParseEnum<CallForSpeechStatus>()));
CreateMap<CallForSpeech, CallForSpeechInListViewModel>()
.ForMember(s => s.Id, o => o.MapFrom(k => k.Id.Value))
.ForMember(s => s.Status, o => o.MapFrom(k => k.Status.ToString()));
CreateMap<CallForSpeechInListViewModel, CallForSpeech>()
.ForMember(s => s.Id, o => o.MapFrom(k => new CallForSpeechId(k.Id)))
.ForMember(s => s.Status, o => o.MapFrom(k =>
k.Status.ParseEnum<CallForSpeechStatus>()));
CreateMap<CallForSpeechAggregate, CallForSpeech>();
}
}
public static partial class GeekLemonConferenceInstallers
{
public static IServiceCollection AddGeekLemonConferenceCQRS
(this IServiceCollection services, IConfiguration Configuration)
{
services.AddAutoMapper(Assembly.GetExecutingAssembly());
services.AddMediatR(Assembly.GetExecutingAssembly());
services.AddSingleton<IScoringRulesFactory, ScoringRulesFactory>();
return services;
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="8.1.1" />
<PackageReference Include="Dapper" Version="2.0.78" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="5.0.3" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" />
<PackageReference Include="System.Data.SQLite" Version="1.0.113.7" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GeekLemonConference.Application.Contracts\GeekLemonConference.Application.Contracts.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="SqlQueries.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>SqlQueries.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="SqlQueries.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>SqlQueries.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>
public List<Customer> GetCustomersByState(string state)
{
var dbConnection = new SqlConnection("SomeConnectionString");
string sql = $@"SELECT F_Name AS {nameof(Customer.FirstName)},
L_Name AS {nameof(Customer.LastName)},
Zip_Code AS {nameof(Customer.ZipCode)}
FROM Customers
WHERE State = @State";
var parameters = new DynamicParameters();
parameters.Add("State", state);
return dbConnection.Query<Customer>(sql, parameters).ToList();
}
var cmd = connection.CreateCommand();
cmd.CommandText = "SELECT last_insert_rowid()";
Int64 i = (Int64)cmd.ExecuteScalar();
var cmd = connection.CreateCommand();
cmd.CommandText = @"SELECT seq From sqlite_sequence
Where Name='Categories'";
Int64 i = (Int64)cmd.ExecuteScalar();
public class CallForSpeechRepository : ICallForSpeechRepository
{
private IGeekLemonDBContext _geekLemonContext;
private readonly IMapper _mapper;
public CallForSpeechRepository(IGeekLemonDBContext geekLemonContext,
IMapper mapper)
{
_geekLemonContext = geekLemonContext;
_mapper = mapper;
}
public async Task<ExecutionStatus> SaveAcceptenceAsyncById
(CallForSpeechId Id, JudgeId judge,
CallForSpeechStatus status)
{
using var connection = new SqliteConnection(_geekLemonContext.ConnectionString);
var q = @"UPDATE CallForSpeakes
SET FinalDecision_DecisionBy = @JudgeId,
FinalDecision_Date = @Date,
Status = @Status
WHERE Id = @Id;";
try
{
var result = await connection.ExecuteAsync(q,
new
{
@JudgeId = judge.Value,
@Date = AppTime.Now().ToLongDateString(),
@Id = Id.Value,
@Status = (int)status
});
return ExecutionStatus.DbOk();
}
catch (Exception ex)
{
return ExecutionStatus.DbError(ex);
}
}
public async Task<ExecutionStatus> SaveEvaluatationByIdAsync
(CallForSpeechId Id,
CallForSpeechScoringResult score, CallForSpeechStatus status)
{
using var connection = new SqliteConnection(_geekLemonContext.ConnectionString);
var q = @"UPDATE CallForSpeakes
SET Score_Score = @Score,
Score_RejectExplanation = @RejectExplanation,
Score_WarringExplanation = @WarringExplanation,
Status = @Status
WHERE Id = @Id;";
try
{
var result = await connection.ExecuteAsync(q,
new
{
@Score = (int)score.Score,
@WarringExplanation = score.WarringExplanation,
@RejectExplanation = score.RejectExplanation,
@Id = Id.Value,
@Status = (int)status
});
return ExecutionStatus.DbOk();
}
catch (Exception ex)
{
return ExecutionStatus.DbError(ex);
}
}
public async Task<ExecutionStatus> SaveRejectionByIdAsync
(CallForSpeechId Id, JudgeId judge,
CallForSpeechStatus status)
{
using var connection = new SqliteConnection(_geekLemonContext.ConnectionString);
var q = @"UPDATE CallForSpeakes
SET PreliminaryDecision_DecisionBy = @JudgeId,
PreliminaryDecision_Date = @Date,
Status = @Status
WHERE Id = @Id;";
try
{
return ExecutionStatus.DbOk();
}
catch (Exception ex)
{
return ExecutionStatus.DbError(ex);
}
var result = await connection.ExecuteAsync(q,
new
{
@JudgeId = judge.Value,
@Date = AppTime.Now().ToLongDateString(),
@Id = Id.Value,
@Status = (int)status
});
}
public async Task<ExecutionStatus<int>> SubmitByIdAsync
(CallForSpeech entity)
{
var temp = _mapper.Map<CallForSpeechTemp>(entity);
using var connection = new SqliteConnection(_geekLemonContext.ConnectionString);
var q = SqlQueries.CallForSpeechInsert;
try
{
var result = await connection.QueryAsync<int>(q, temp);
int id = result.FirstOrDefault();
return ExecutionStatus<int>.DbOk(id);
}
catch (Exception ex)
{
return ExecutionStatus<int>.DbError(ex);
}
//var result = await connection.QueryAsync<int>(q,
// new
// {
// @Number = entity.Number.Number,
// @Name = entity.Name,
// @DisplayName = entity.DisplayName,
// @WhatWeAreLookingFor = entity.WhatWeAreLookingFor
// });
}
public async Task<ExecutionStatus<IReadOnlyList<CallForSpeech>>> GetCollectionAsync
(FilterCallForSpeechStyles filtrer)
{
using var connection = new SqliteConnection
(_geekLemonContext.ConnectionString);
IEnumerable<CallForSpeechTemp> r;
var q = @$"SELECT
c.UniqueId ,c.Version,
c.Id,c.Number,c.Status,c.PreliminaryDecision_DecisionBy,
c.PreliminaryDecision_Date,c.FinalDecision_DecisionBy,
c.FinalDecision_Date,c.Speaker_Name_First,c.Speaker_Name_Last,
c.Speaker_Adress_Country,c.Speaker_Adress_ZipCode, c.Speaker_Adress_City,
c.Speaker_Adress_Street,c.Speaker_Websites_Facebook,c.Speaker_Websites_Twitter,
c.Speaker_Websites_Instagram,c.Speaker_Websites_LinkedIn,c.Speaker_Websites_TikTok,
c.Speaker_Websites_Youtube,c.Speaker_Websites_FanPageOnFacebook,c.Speaker_Websites_GitHub,
c.Speaker_Websites_Blog, c.Speaker_BIO,
c.Speaker_Contact_Phone,c.Speaker_Contact_Email, c.Speech_Tags,
c.Speech_ForWhichAudience,c.Speech_TechnologyOrBussinessStory,c.Registration_RegistrationDate,
c.CategoryId,c.Score_Score, c.Score_RejectExplanation,c.Score_WarringExplanation,
c.Speaker_Birthdate,c.Speech_Title,c.Speech_Description,
k.Name AS {nameof(JudgeTemp.Category_Name)},
k.DisplayName AS {nameof(JudgeTemp.Category_DisplayName)}
,k.WhatWeAreLookingFor AS {nameof(JudgeTemp.Category_WhatWeAreLookingFor)}
FROM CallForSpeakes as c
INNER JOIN Categories as k ON c.CategoryId = k.Id";
try
{
if (filtrer == FilterCallForSpeechStyles.All)
{
r = await connection.QueryAsync<CallForSpeechTemp>
(q);
}
else
{
r = await connection.QueryAsync<CallForSpeechTemp>
(q + " WHERE Status = @st;"
, new { st = (int)filtrer });
}
var rmaped = _mapper.Map<IReadOnlyList<CallForSpeech>>(r);
return ExecutionStatus<IReadOnlyList<CallForSpeech>>.DbOk(rmaped.ToList().AsReadOnly());
}
catch (Exception ex)
{
return ExecutionStatus<IReadOnlyList<CallForSpeech>>.DbError(ex);
}
}
public async Task<ExecutionStatus<CallForSpeech>> GetByIdAsync(int id)
{
using var connection = new SqliteConnection
(_geekLemonContext.ConnectionString);
var q =
@$"SELECT c.UniqueId ,c.Version, c.Id,c.Number,c.Status,c.PreliminaryDecision_DecisionBy,
c.PreliminaryDecision_Date,c.FinalDecision_DecisionBy,
c.FinalDecision_Date,c.Speaker_Name_First,c.Speaker_Name_Last,
c.Speaker_Adress_Country,c.Speaker_Adress_ZipCode, c.Speaker_Adress_City,
c.Speaker_Adress_Street,c.Speaker_Websites_Facebook,c.Speaker_Websites_Twitter,
c.Speaker_Websites_Instagram,c.Speaker_Websites_LinkedIn,c.Speaker_Websites_TikTok,
c.Speaker_Websites_Youtube,c.Speaker_Websites_FanPageOnFacebook,c.Speaker_Websites_GitHub,
c.Speaker_Websites_Blog, c.Speaker_BIO,
c.Speaker_Contact_Phone,c.Speaker_Contact_Email, c.Speech_Tags,
c.Speech_ForWhichAudience,c.Speech_TechnologyOrBussinessStory,c.Registration_RegistrationDate,
c.CategoryId,c.Score_Score, c.Score_RejectExplanation,c.Score_WarringExplanation,
c.Speaker_Birthdate,c.Speech_Title,c.Speech_Description,
k.Name AS {nameof(JudgeTemp.Category_Name)},
k.DisplayName AS {nameof(JudgeTemp.Category_DisplayName)}
,k.WhatWeAreLookingFor AS {nameof(JudgeTemp.Category_WhatWeAreLookingFor)}
FROM CallForSpeakes as c
INNER JOIN Categories as k ON c.CategoryId = k.Id
Where c.Id = @Id";
try
{
var r = await connection.
QueryFirstOrDefaultAsync<CallForSpeechTemp>
(q, new
{
@Id = id,
});
var rmaped = _mapper.Map<CallForSpeech>(r);
return ExecutionStatus<CallForSpeech>.DbOk(rmaped);
}
catch (Exception ex)
{
return ExecutionStatus<CallForSpeech>.DbError(ex);
}
}
public async Task<ExecutionStatus> SavePreliminaryAcceptenceByIdAsync
(CallForSpeechId Id, JudgeId judge, CallForSpeechStatus status)
{
using var connection = new SqliteConnection(_geekLemonContext.ConnectionString);
var q = @"UPDATE CallForSpeakes
SET PreliminaryDecision_DecisionBy = @JudgeId,
PreliminaryDecision_Date = @Date,
Status = @Status
WHERE Id = @Id;";
try
{
var result = await connection.ExecuteAsync(q,
new
{
@JudgeId = judge.Value,
@Date = AppTime.Now().ToLongDateString(),
@Id = Id.Value,
@Status = (int)status
});
return ExecutionStatus.DbOk();
}
catch (Exception ex)
{
return ExecutionStatus.DbError(ex);
}
}
public Task<ExecutionStatus> SavePreliminaryAcceptenceAsync(
CallForSpeechUniqueId id, JudgeId judge, CallForSpeechStatus status)
{
throw new NotImplementedException();
}
public Task<ExecutionStatus> SaveAcceptenceAsync
(CallForSpeechUniqueId id, JudgeId judge, CallForSpeechStatus status)
{
throw new NotImplementedException();
}
public Task<ExecutionStatus> SaveRejectionAsync
(CallForSpeechUniqueId id, JudgeId judge, CallForSpeechStatus status)
{
throw new NotImplementedException();
}
public Task<ExecutionStatus> SaveEvaluatationAsync
(CallForSpeechUniqueId id, CallForSpeechScoringResult score, CallForSpeechStatus status)
{
throw new NotImplementedException();
}
public Task<ExecutionStatus> SaveAcceptenceByIdAsync
(CallForSpeechId id, JudgeId judge, CallForSpeechStatus status)
{
throw new NotImplementedException();
}
public Task<ExecutionStatus<CallForSpeech>> GetByUniqueIdAsync
(Guid id)
{
throw new NotImplementedException();
}
public Task<ExecutionStatus<Ids>> SubmitAsync
(CallForSpeech callForSpeech)
{
throw new NotImplementedException();
}
}
public interface IBeforeDoer
{
void ChangeDBContext(IGeekLemonDBContext context);
}
public abstract class BeforeDoer : IBeforeDoer
{
protected IGeekLemonDBContext _geekLemonContext;
public void ChangeDBContext(IGeekLemonDBContext context)
{
_geekLemonContext = context;
}
}
public interface IGeekLemonDBContext
{
string ConnectionString { get; }
}
public class GeekLemonDBContext : IGeekLemonDBContext
{
public GeekLemonDBContext(string connectionString)
{
_connectionString = connectionString;
}
private string _connectionString;
public string ConnectionString
{
get
{
return _connectionString;
}
}
}
public interface IZEsGeekLemonDBContext
{
string ConnectionString { get; }
}
public class ZEsGeekLemonDBContext : IZEsGeekLemonDBContext
{
public ZEsGeekLemonDBContext(string connectionString)
{
_connectionString = connectionString;
}
private string _connectionString;
public string ConnectionString
{
get
{
return _connectionString;
}
}
}
public interface IBeforeDoer
{
void ChangeDBContext(IGeekLemonDBContext context);
}
public interface ICallForSpeechGetByIdDoer : IBeforeDoer
{
Task<ExecutionStatus<CallForSpeech>> Run(CallForSpeechId id);
Task<ExecutionStatus<CallForSpeech>> Run(CallForSpeechUniqueId id);
}
public interface ICallForSpeechGetCollectionDoer : IBeforeDoer
{
Task<ExecutionStatus<IReadOnlyList<CallForSpeech>>> Run(
FilterCallForSpeechStyles filtrer);
}
public interface ICallForSpeechSaveAcceptenceDoer : IBeforeDoer
{
Task<ExecutionStatus> Run(CallForSpeechUniqueId id,
JudgeId judge, CallForSpeechStatus status);
Task<ExecutionStatus> Run(CallForSpeechId id,
JudgeId judge, CallForSpeechStatus status);
}
public interface ICallForSpeechSaveEvaluatationDoer : IBeforeDoer
{
Task<ExecutionStatus> Run(CallForSpeechUniqueId id,
CallForSpeechScoringResult score, CallForSpeechStatus status);
Task<ExecutionStatus> Run(CallForSpeechId id,
CallForSpeechScoringResult score, CallForSpeechStatus status);
}
public interface ICallForSpeechSavePreliminaryAcceptenceDoer : IBeforeDoer
{
Task<ExecutionStatus> Run(CallForSpeechUniqueId id,
JudgeId judge, CallForSpeechStatus status);
Task<ExecutionStatus> Run(CallForSpeechId id,
JudgeId judge, CallForSpeechStatus status);
}
public interface ICallForSpeechSaveRejectionDoer : IBeforeDoer
{
Task<ExecutionStatus> Run(CallForSpeechUniqueId id,
JudgeId judge, CallForSpeechStatus status);
Task<ExecutionStatus> Run(CallForSpeechId id,
JudgeId judge, CallForSpeechStatus status);
}
public interface ICallForSpeechSubmitDoer : IBeforeDoer
{
Task<ExecutionStatus<CallForSpeechIds>>
Run(CallForSpeech callForSpeech);
}
public interface ICategoryAddDoer : IBeforeDoer
{
Task<ExecutionStatus<CategoryIds>> Run(Category entity);
}
public interface ICategoryDeleteDoer : IBeforeDoer
{
Task<ExecutionStatus> Run(CategoryId entity);
Task<ExecutionStatus> Run(CategoryUniqueId id);
}
public interface ICategoryGetAllDoer : IBeforeDoer
{
Task<ExecutionStatus<IReadOnlyList<Category>>> Run();
}
public interface ICategoryGetByIdDoer : IBeforeDoer
{
Task<ExecutionStatus<Category>> Run(CategoryId id);
Task<ExecutionStatus<Category>> Run(CategoryUniqueId id);
}
public interface ICategoryUpdateDoer : IBeforeDoer
{
Task<ExecutionStatus> Run(Category entity, ByWhatId byWhatId);
}
public interface IJudgeAddDoer : IBeforeDoer
{
Task<ExecutionStatus<JudgeIds>> Run(Judge entity);
}
public interface IJudgeDeleteDoer : IBeforeDoer
{
Task<ExecutionStatus> Run(JudgeId entity);
Task<ExecutionStatus> Run(JudgeUniqueId id);
}
public interface IJudgeGetAllDoer : IBeforeDoer
{
Task<ExecutionStatus<IReadOnlyList<Judge>>> Run();
}
public interface IJudgeGetByIdDoer : IBeforeDoer
{
Task<ExecutionStatus<Judge>> Run(JudgeId id);
Task<ExecutionStatus<Judge>> Run(JudgeUniqueId id);
}
public interface IJudgeUpdateDoer : IBeforeDoer
{
Task<ExecutionStatus> Run(Judge entity, ByWhatId byWhatId);
}
public class CategoryRepository : ICategoryRepository
{
private ICategoryAddDoer _categoryAddDoer;
private ICategoryGetAllDoer _categoryGetAllDoer;
private ICategoryDeleteDoer _categoryDeleteDoer;
private ICategoryGetByIdDoer _categoryGetByIdDoer;
private ICategoryUpdateDoer _categoryUpdateDoer;
public CategoryRepository(ICategoryAddDoer categoryAddDoer,
ICategoryGetAllDoer categoryGetAllDoer, ICategoryDeleteDoer categoryDeleteDoer,
ICategoryGetByIdDoer categoryGetByIdDoer, ICategoryUpdateDoer categoryUpdateDoer)
{
_categoryAddDoer = categoryAddDoer;
_categoryGetAllDoer = categoryGetAllDoer;
_categoryDeleteDoer = categoryDeleteDoer;
_categoryGetByIdDoer = categoryGetByIdDoer;
_categoryUpdateDoer = categoryUpdateDoer;
}
public void ChangeContext(IGeekLemonDBContext geekLemonDB)
{
_categoryAddDoer.ChangeDBContext(geekLemonDB);
_categoryGetAllDoer.ChangeDBContext(geekLemonDB);
_categoryDeleteDoer.ChangeDBContext(geekLemonDB);
_categoryGetByIdDoer.ChangeDBContext(geekLemonDB);
_categoryUpdateDoer.ChangeDBContext(geekLemonDB);
}
public Task<ExecutionStatus<CategoryIds>> AddAsync(Category entity)
{
return _categoryAddDoer.Run(entity);
}
public Task<ExecutionStatus> DeleteAsync(CategoryId categoryId)
{
return _categoryDeleteDoer.Run(categoryId);
}
public Task<ExecutionStatus> DeleteAsync(CategoryUniqueId categoryId)
{
return _categoryDeleteDoer.Run(categoryId);
}
public Task<ExecutionStatus<IReadOnlyList<Category>>> GetAllAsync()
{
return _categoryGetAllDoer.Run();
}
public Task<ExecutionStatus<Category>> GetByIdAsync(CategoryId id)
{
return _categoryGetByIdDoer.Run(id);
}
public Task<ExecutionStatus<Category>> GetByIdAsync(CategoryUniqueId id)
{
return _categoryGetByIdDoer.Run(id);
}
public Task<ExecutionStatus> UpdateByUniqueIdAsync(Category entity)
{
return _categoryUpdateDoer.Run(entity, ByWhatId.UniqueId);
}
public Task<ExecutionStatus> UpdateByIdAsync(Category entity)
{
return _categoryUpdateDoer.Run(entity, ByWhatId.CreatedId);
}
}
public class JugdeRepository : IJudgeRepository
{
private IJudgeAddDoer _judgeAddDoer;
private IJudgeUpdateDoer _judgeUpdateDoer;
private IJudgeDeleteDoer _judgeDeleteDoer;
private IJudgeGetAllDoer _judgeGetAllDoer;
private IJudgeGetByIdDoer _judgeGetByIdDoer;
public JugdeRepository(IJudgeAddDoer judgeAddDoer,
IJudgeUpdateDoer judgeUpdateDoer, IJudgeDeleteDoer judgeDeleteDoer,
IJudgeGetAllDoer judgeGetAllDoer, IJudgeGetByIdDoer judgeGetByIdDoer)
{
_judgeAddDoer = judgeAddDoer;
_judgeUpdateDoer = judgeUpdateDoer;
_judgeDeleteDoer = judgeDeleteDoer;
_judgeGetAllDoer = judgeGetAllDoer;
_judgeGetByIdDoer = judgeGetByIdDoer;
}
public void ChangeContext(IGeekLemonDBContext geekLemonDB)
{
_judgeAddDoer.ChangeDBContext(geekLemonDB);
_judgeUpdateDoer.ChangeDBContext(geekLemonDB);
_judgeDeleteDoer.ChangeDBContext(geekLemonDB);
_judgeGetAllDoer.ChangeDBContext(geekLemonDB);
_judgeGetByIdDoer.ChangeDBContext(geekLemonDB);
}
public Task<ExecutionStatus<JudgeIds>> AddAsync(Judge entity)
{
return _judgeAddDoer.Run(entity);
}
public Task<ExecutionStatus> DeleteAsync(JudgeId entity)
{
return _judgeDeleteDoer.Run(entity);
}
public Task<ExecutionStatus> DeleteAsync(JudgeUniqueId id)
{
return _judgeDeleteDoer.Run(id);
}
public Task<ExecutionStatus<IReadOnlyList<Judge>>> GetAllAsync()
{
return _judgeGetAllDoer.Run();
}
public Task<ExecutionStatus<Judge>> GetByIdAsync(JudgeId id)
{
return _judgeGetByIdDoer.Run(id);
}
public Task<ExecutionStatus<Judge>> GetByIdAsync(JudgeUniqueId id)
{
return _judgeGetByIdDoer.Run(id);
}
public Task<ExecutionStatus> UpdateByUniqueIdAsync(Judge entity)
{
return _judgeUpdateDoer.Run(entity, ByWhatId.UniqueId);
}
public Task<ExecutionStatus> UpdateByIdAsync(Judge entity)
{
return _judgeUpdateDoer.Run(entity, ByWhatId.CreatedId);
}
}
public class CallForSpeechRepository : ICallForSpeechRepository
{
private ICallForSpeechGetByIdDoer _callForSpeechGetByIdDoer;
private ICallForSpeechGetCollectionDoer _callForSpeechGetCollectionDoer;
private ICallForSpeechSaveAcceptenceDoer _callForSpeechSaveAcceptenceDoer;
private ICallForSpeechSaveEvaluatationDoer _callForSpeechSaveEvaluatationDoer;
private ICallForSpeechSavePreliminaryAcceptenceDoer _callForSpeechSavePreliminaryAcceptenceDoer;
private ICallForSpeechSaveRejectionDoer _callForSpeechSaveRejectionDoer;
private ICallForSpeechSubmitDoer _callForSpeechSubmitDoer;
public CallForSpeechRepository(ICallForSpeechGetByIdDoer callForSpeechGetByIdDoer,
ICallForSpeechGetCollectionDoer callForSpeechGetCollectionDoer,
ICallForSpeechSaveAcceptenceDoer callForSpeechSaveAcceptenceDoer,
ICallForSpeechSaveEvaluatationDoer callForSpeechSaveEvaluatationDoer,
ICallForSpeechSavePreliminaryAcceptenceDoer callForSpeechSavePreliminaryAcceptenceDoer,
ICallForSpeechSaveRejectionDoer callForSpeechSaveRejectionDoer,
ICallForSpeechSubmitDoer callForSpeechSubmitDoer)
{
_callForSpeechGetByIdDoer = callForSpeechGetByIdDoer;
_callForSpeechGetCollectionDoer = callForSpeechGetCollectionDoer;
_callForSpeechSaveAcceptenceDoer = callForSpeechSaveAcceptenceDoer;
_callForSpeechSaveEvaluatationDoer = callForSpeechSaveEvaluatationDoer;
_callForSpeechSavePreliminaryAcceptenceDoer = callForSpeechSavePreliminaryAcceptenceDoer;
_callForSpeechSaveRejectionDoer = callForSpeechSaveRejectionDoer;
_callForSpeechSubmitDoer = callForSpeechSubmitDoer;
}
public void ChangeContext(IGeekLemonDBContext geekLemonDB)
{
_callForSpeechGetByIdDoer.ChangeDBContext(geekLemonDB);
_callForSpeechGetCollectionDoer.ChangeDBContext(geekLemonDB);
_callForSpeechSaveAcceptenceDoer.ChangeDBContext(geekLemonDB);
_callForSpeechSaveEvaluatationDoer.ChangeDBContext(geekLemonDB);
_callForSpeechSavePreliminaryAcceptenceDoer.ChangeDBContext(geekLemonDB);
_callForSpeechSaveRejectionDoer.ChangeDBContext(geekLemonDB);
_callForSpeechSubmitDoer.ChangeDBContext(geekLemonDB);
}
public Task<ExecutionStatus<CallForSpeech>> GetByIdAsync(CallForSpeechId id)
{
return _callForSpeechGetByIdDoer.Run(id);
}
public Task<ExecutionStatus<CallForSpeech>> GetByIdAsync(CallForSpeechUniqueId id)
{
return _callForSpeechGetByIdDoer.Run(id);
}
public Task<ExecutionStatus<IReadOnlyList<CallForSpeech>>> GetCollectionAsync(FilterCallForSpeechStyles filtrer)
{
return _callForSpeechGetCollectionDoer.Run(filtrer);
}
public Task<ExecutionStatus> SaveAcceptenceAsync(CallForSpeechId id, JudgeId judge, CallForSpeechStatus status)
{
return _callForSpeechSaveAcceptenceDoer.Run(id, judge, status);
}
public Task<ExecutionStatus> SaveAcceptenceAsync(CallForSpeechUniqueId id, JudgeId judge, CallForSpeechStatus status)
{
return _callForSpeechSaveAcceptenceDoer.Run(id, judge, status);
}
public Task<ExecutionStatus> SaveEvaluatationAsync(CallForSpeechId id, CallForSpeechScoringResult score, CallForSpeechStatus status)
{
return _callForSpeechSaveEvaluatationDoer.Run(id, score, status);
}
public Task<ExecutionStatus> SaveEvaluatationAsync(CallForSpeechUniqueId id, CallForSpeechScoringResult score, CallForSpeechStatus status)
{
return _callForSpeechSaveEvaluatationDoer.Run(id, score, status);
}
public Task<ExecutionStatus> SavePreliminaryAcceptenceAsync(CallForSpeechId id, JudgeId judge, CallForSpeechStatus status)
{
return _callForSpeechSavePreliminaryAcceptenceDoer.Run(id, judge, status);
}
public Task<ExecutionStatus> SavePreliminaryAcceptenceAsync(CallForSpeechUniqueId id, JudgeId judge, CallForSpeechStatus status)
{
return _callForSpeechSavePreliminaryAcceptenceDoer.Run(id, judge, status);
}
public Task<ExecutionStatus> SaveRejectionAsync(CallForSpeechId id, JudgeId judge, CallForSpeechStatus status)
{
return _callForSpeechSaveRejectionDoer.Run(id, judge, status);
}
public Task<ExecutionStatus> SaveRejectionAsync(CallForSpeechUniqueId id, JudgeId judge, CallForSpeechStatus status)
{
return _callForSpeechSaveRejectionDoer.Run(id, judge, status);
}
public Task<ExecutionStatus<CallForSpeechIds>> SubmitAsync(CallForSpeech callForSpeech)
{
return _callForSpeechSubmitDoer.Run(callForSpeech);
}
}
public class ZEsCategoryRepository : CategoryRepository, IZEsCategoryRepository
{
public ZEsCategoryRepository(ICategoryAddDoer categoryAddDoer,
ICategoryGetAllDoer categoryGetAllDoer, ICategoryDeleteDoer categoryDeleteDoer,
ICategoryGetByIdDoer categoryGetByIdDoer, ICategoryUpdateDoer categoryUpdateDoer,
IZEsGeekLemonDBContext zEsGeekLemonDBContext)
: base(categoryAddDoer, categoryGetAllDoer, categoryDeleteDoer, categoryGetByIdDoer,
categoryUpdateDoer)
{
GeekLemonDBContext context =
new GeekLemonDBContext(zEsGeekLemonDBContext.ConnectionString);
this.ChangeContext(context);
}
}
public class ZEsJugdeRepository : JugdeRepository, IZEsJudgeRepository
{
public ZEsJugdeRepository(IJudgeAddDoer judgeAddDoer,
IJudgeUpdateDoer judgeUpdateDoer, IJudgeDeleteDoer judgeDeleteDoer,
IJudgeGetAllDoer judgeGetAllDoer, IJudgeGetByIdDoer judgeGetByIdDoer,
IZEsGeekLemonDBContext zEsGeekLemonDBContext)
: base(judgeAddDoer, judgeUpdateDoer, judgeDeleteDoer, judgeGetAllDoer,
judgeGetByIdDoer)
{
GeekLemonDBContext context =
new GeekLemonDBContext(zEsGeekLemonDBContext.ConnectionString);
this.ChangeContext(context);
}
}
public class ZEsCallForSpeechRepository : CallForSpeechRepository,
IZEsCallForSpeechRepository
{
public ZEsCallForSpeechRepository(ICallForSpeechGetByIdDoer callForSpeechGetByIdDoer,
ICallForSpeechGetCollectionDoer callForSpeechGetCollectionDoer,
ICallForSpeechSaveAcceptenceDoer callForSpeechSaveAcceptenceDoer,
ICallForSpeechSaveEvaluatationDoer callForSpeechSaveEvaluatationDoer,
ICallForSpeechSavePreliminaryAcceptenceDoer callForSpeechSavePreliminaryAcceptenceDoer,
ICallForSpeechSaveRejectionDoer callForSpeechSaveRejectionDoer,
ICallForSpeechSubmitDoer callForSpeechSubmitDoer,
IZEsGeekLemonDBContext _zEsGeekLemonDBContext)
: base(callForSpeechGetByIdDoer, callForSpeechGetCollectionDoer,
callForSpeechSaveAcceptenceDoer, callForSpeechSaveEvaluatationDoer,
callForSpeechSavePreliminaryAcceptenceDoer, callForSpeechSaveRejectionDoer,
callForSpeechSubmitDoer)
{
GeekLemonDBContext context =
new GeekLemonDBContext(_zEsGeekLemonDBContext.ConnectionString);
this.ChangeContext(context);
}
}
public class CategoryAddDoer
: BeforeDoer, ICategoryAddDoer
{
private readonly IMapper _mapper;
public CategoryAddDoer
(IGeekLemonDBContext geekLemonContext,
IMapper mapper)
{
_geekLemonContext = geekLemonContext;
_mapper = mapper;
}
public async Task<ExecutionStatus<CategoryIds>> Run(Category entity)
{
using var connection = new SqliteConnection(_geekLemonContext.ConnectionString);
//Nie ma SQL INjection
var q = @"INSERT INTO Categories(Name, DisplayName, WhatWeAreLookingFor
,UniqueId, Version)
VALUES (@Name, @DisplayName, @WhatWeAreLookingFor,@UniqueId, @Version);
SELECT seq From sqlite_sequence Where Name='Categories'";
try
{
var result = await connection.QueryAsync<int>(q,
new
{
@Name = entity.Name,
@DisplayName = entity.DisplayName,
@WhatWeAreLookingFor = entity.WhatWeAreLookingFor,
@UniqueId = entity.UniqueId.Value.ToString(),
@Version = entity.Version,
});
//var cmd = connection.CreateCommand();
//cmd.CommandText = "SELECT last_insert_rowid()";
//Int64 i = (Int64)cmd.ExecuteScalar();
int createdId = result.FirstOrDefault();
CategoryIds ids = new CategoryIds()
{
CreatedId = new CategoryId(createdId),
UniqueId = entity.UniqueId
};
return ExecutionStatus
<CategoryIds>
.DbOk(ids);
}
catch (Exception ex)
{
if (ExecutionFlow.Options.ThrowExceptions)
throw;
return ExecutionStatus
<CategoryIds>
.DbError(ex);
}
}
}
public class CategoryDeleteDoer : BeforeDoer, ICategoryDeleteDoer
{
private readonly IMapper _mapper;
public CategoryDeleteDoer
(IGeekLemonDBContext geekLemonContext,
IMapper mapper)
{
_geekLemonContext = geekLemonContext;
_mapper = mapper;
}
public async Task<ExecutionStatus> Run(CategoryId categoryId)
{
using var connection = new SqliteConnection(_geekLemonContext.ConnectionString);
var q = @"DELETE FROM Categories WHERE Id=@Id;";
try
{
var result = await connection.QueryAsync<int>(q,
new
{
@Id = categoryId.Value
});
}
catch (Exception ex)
{
if (ExecutionFlow.Options.ThrowExceptions)
throw;
return ExecutionStatus.DbError(ex);
}
return ExecutionStatus.DbOk();
}
public async Task<ExecutionStatus> Run(CategoryUniqueId categoryId)
{
using var connection = new SqliteConnection(_geekLemonContext.ConnectionString);
var q = @"DELETE FROM Categories WHERE UniqueId=@UniqueId;";
try
{
var result = await connection.QueryAsync<int>(q,
new
{
@UniqueId = categoryId.Value.ToString()
});
}
catch (Exception ex)
{
if (ExecutionFlow.Options.ThrowExceptions)
throw;
return ExecutionStatus.DbError(ex);
}
return ExecutionStatus.DbOk();
}
}
public class CategoryGetAllDoer : BeforeDoer, ICategoryGetAllDoer
{
private readonly IMapper _mapper;
public CategoryGetAllDoer
(IGeekLemonDBContext geekLemonContext,
IMapper mapper)
{
_geekLemonContext = geekLemonContext;
_mapper = mapper;
}
public async Task<ExecutionStatus<IReadOnlyList<Category>>> Run()
{
using var connection = new SqliteConnection
(_geekLemonContext.ConnectionString);
try
{
var r = await connection.QueryAsync<CategoryTemp>
(@"SELECT Id, DisplayName, Name ,
WhatWeAreLookingFor,UniqueId ,Version FROM Categories;");
var rmaped = _mapper.Map<IEnumerable<Category>>(r);
return ExecutionStatus<IReadOnlyList<Category>>
.DbIfDefaultThenError
(rmaped.ToList().AsReadOnly());
}
catch (Exception ex)
{
return ExecutionStatus<IReadOnlyList<Category>>
.DbError(ex);
}
}
}
public class CategoryGetByIdDoer : BeforeDoer, ICategoryGetByIdDoer
{
private readonly IMapper _mapper;
public CategoryGetByIdDoer
(IGeekLemonDBContext geekLemonContext,
IMapper mapper)
{
_geekLemonContext = geekLemonContext;
_mapper = mapper;
}
public async Task<ExecutionStatus<Category>> Run(CategoryUniqueId categoryId)
{
using var connection = new SqliteConnection
(_geekLemonContext.ConnectionString);
var q = @"SELECT Id, DisplayName, Name,
WhatWeAreLookingFor,UniqueId ,Version FROM Categories
Where UniqueId = @UniqueId";
try
{
var r = await connection.
QueryFirstOrDefaultAsync<CategoryTemp>
(q, new
{
@UniqueId = categoryId.Value.ToString(),
});
var rmaped = _mapper.Map<Category>(r);
return ExecutionStatus<Category>.
DbIfDefaultThenError(rmaped);
}
catch (Exception ex)
{
return ExecutionStatus<Category>.DbError(ex);
}
}
public async Task<ExecutionStatus<Category>> Run(CategoryId categoryId)
{
using var connection = new SqliteConnection
(_geekLemonContext.ConnectionString);
var q = @"SELECT Id, DisplayName, Name,
WhatWeAreLookingFor,UniqueId ,Version FROM Categories
Where Id = @Id";
try
{
var r = await connection.
QueryFirstOrDefaultAsync<CategoryTemp>
(q, new
{
@Id = categoryId.Value,
});
var rmaped = _mapper.Map<Category>(r);
return ExecutionStatus<Category>.DbIfDefaultThenError(rmaped);
}
catch (Exception ex)
{
return ExecutionStatus<Category>.DbError(ex);
}
}
}
public class CategoryUpdateDoer : BeforeDoer, ICategoryUpdateDoer
{
private readonly IMapper _mapper;
public CategoryUpdateDoer
(IGeekLemonDBContext geekLemonContext,
IMapper mapper)
{
_geekLemonContext = geekLemonContext;
_mapper = mapper;
}
public async Task<ExecutionStatus> Run(Category entity, ByWhatId byWhatId)
{
using var connection = new SqliteConnection(_geekLemonContext.ConnectionString);
//Nie ma SQL INjection
var q1 = @"UPDATE Categories
SET Name = @Name, DisplayName = @DisplayName, WhatWeAreLookingFor=@WhatWeAreLookingFor
,Version = @Version
WHERE UniqueId = @UniqueId; ";
var q = @"UPDATE Categories
SET Name = @Name, DisplayName = @DisplayName, WhatWeAreLookingFor=@WhatWeAreLookingFor
,Version = @Version
WHERE Id = @Id; ";
try
{
if (byWhatId == ByWhatId.UniqueId)
q = q1;
var result = await connection.QueryAsync<int>(q,
new
{
@UniqueId = entity.UniqueId.Value.ToString(),
@Id = entity.Id.Value,
@Name = entity.Name,
@Version = entity.Version,
@DisplayName = entity.DisplayName,
@WhatWeAreLookingFor = entity.WhatWeAreLookingFor
});
return ExecutionStatus.DbOk();
}
catch (Exception ex)
{
if (ExecutionFlow.Options.ThrowExceptions)
throw;
return ExecutionStatus.DbError(ex);
}
}
}
public class CallForSpeechTemp
{
public int Id { get; set; }
public string UniqueId { get; set; }
public int Version { get; set; }
public string Number { get; set; }
public int Status { get; set; }
public string PreliminaryDecision_Date { get; set; }
public int? PreliminaryDecision_DecisionBy { get; set; }
public string FinalDecision_Date { get; set; }
public int? FinalDecision_DecisionBy { get; set; }
public string Speaker_Name_First { get; set; }
public string Speaker_Name_Last { get; set; }
public string Speaker_Adress_Country { get; set; }
public string Speaker_Adress_ZipCode { get; set; }
public string Speaker_Adress_City { get; set; }
public string Speaker_Adress_Street { get; set; }
public string Speaker_Websites_Facebook { get; set; }
public string Speaker_Websites_Twitter { get; set; }
public string Speaker_Websites_Instagram { get; set; }
public string Speaker_Websites_LinkedIn { get; set; }
public string Speaker_Websites_TikTok { get; set; }
public string Speaker_Websites_Youtube { get; set; }
public string Speaker_Websites_FanPageOnFacebook { get; set; }
public string Speaker_Websites_GitHub { get; set; }
public string Speaker_Websites_Blog { get; set; }
public string Speaker_BIO { get; set; }
public string Speaker_Contact_Phone { get; set; }
public string Speaker_Contact_Email { get; set; }
public string Speaker_Birthdate { get; set; }
public string Speech_Title { get; set; }
public string Speech_Description { get; set; }
public string Speech_Tags { get; set; }
public int Speech_ForWhichAudience { get; set; }
public int Speech_TechnologyOrBussinessStory { get; set; }
public string Registration_RegistrationDate { get; set; }
public int CategoryId { get; set; }
public int Score_Score { get; set; }
public string Score_RejectExplanation { get; set; }
public string Score_WarringExplanation { get; set; }
public string Category_DisplayName { get; set; }
public string Category_WhatWeAreLookingFor { get; set; }
public string Category_Name { get; set; }
}
public class JudgeTemp
{
public int Id { get; set; }
public string UniqueId { get; set; }
public int Version { get; set; }
public string Login { get; set; }
public string Password { get; set; }
public string BirthDate { get; set; }
public string Name_First { get; set; }
public string Name_Last { get; set; }
public string Email_ForeConference { get; set; }
public string Email_ForSpeakers { get; set; }
public string Phone_ForSpekers { get; set; }
public string Phone_ForConference { get; set; }
public int CategoryId { get; set; }
public string Category_DisplayName { get; set; }
public string Category_WhatWeAreLookingFor { get; set; }
public string Category_Name { get; set; }
}
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<CallForSpeech, CallForSpeechTemp>().
ConvertUsing(new CallForSpeechTempTypeConverter());
CreateMap<CallForSpeechTemp, CallForSpeech>().
ConvertUsing(new CallForSpeechTypeConverter());
CreateMap<Category, CategoryTemp>();
CreateMap<CategoryTemp, Category>();
CreateMap<CategoryId, int>().ConstructUsing(k => k.Value);
CreateMap<int, CategoryId>().ConstructUsing(k => new CategoryId(k));
CreateMap<CategoryUniqueId, string>().ConstructUsing(k => k.Value.ToString());
CreateMap<string, CategoryUniqueId>().
ConstructUsing(k => new CategoryUniqueId(Guid.Parse(k)));
CreateMap<JudgeTemp, Judge>().
ConvertUsing(new JudgeTypeConverter());
CreateMap<Judge, JudgeTemp>().
ConvertUsing(new JudgeTempTypeConverter());
}
}
public class CallForSpeechTempTypeConverter :
ITypeConverter<CallForSpeech, CallForSpeechTemp>
{
public CallForSpeechTemp Convert(CallForSpeech source, CallForSpeechTemp destination, ResolutionContext context)
{
CallForSpeechTemp sc = new CallForSpeechTemp();
sc.CategoryId = source.Category.Id.Value;
sc.Number = source.Number.Number;
sc.Category_DisplayName = source.Category.DisplayName;
sc.Category_Name = source.Category.Name;
sc.Category_WhatWeAreLookingFor = source.Category.WhatWeAreLookingFor;
sc.FinalDecision_Date = source.FinalDecision?.DecisionDate.ToString("yyyy-MM-dd HH:mm:ss.fff",
CultureInfo.InvariantCulture);
sc.FinalDecision_DecisionBy = source.FinalDecision?.DecisionBy?.Value;
sc.PreliminaryDecision_Date = source.PreliminaryDecision?.DecisionDate.ToString("yyyy-MM-dd HH:mm:ss.fff",
CultureInfo.InvariantCulture);
sc.PreliminaryDecision_DecisionBy = source.PreliminaryDecision?.DecisionBy?.Value;
sc.Registration_RegistrationDate = source.Registration.RegistrationDate.ToString("yyyy-MM-dd HH:mm:ss.fff",
CultureInfo.InvariantCulture);
sc.Score_RejectExplanation = source.Score?.RejectExplanation;
sc.Score_WarringExplanation = source.Score?.WarringExplanation;
sc.Score_Score = (int)(source.Score?.Score ?? 0);
if (source.Id != null)
sc.Id = source.Id.Value;
sc.Speaker_Adress_City = source.Speaker.Address.City;
sc.Speaker_Adress_Country = source.Speaker.Address.Country;
sc.Speaker_Adress_Street = source.Speaker.Address.Street;
sc.Speaker_Adress_ZipCode = source.Speaker.Address.ZipCode;
sc.Speaker_BIO = source.Speaker.Biography;
sc.Speaker_Birthdate = source.Speaker.Birthdate.ToString("dd-MM-yyyy");
sc.Speaker_Contact_Email = source.Speaker.Contact.Email;
sc.Speaker_Name_First = source.Speaker.Name.First;
sc.Speaker_Name_Last = source.Speaker.Name.Last;
sc.Speaker_Contact_Phone = source.Speaker.Contact.Phone;
sc.Speaker_Websites_Blog = source.Speaker.SpeakerWebsites.Blog;
sc.Speaker_Websites_Facebook = source.Speaker.SpeakerWebsites.Blog;
sc.Speaker_Websites_FanPageOnFacebook = source.Speaker.SpeakerWebsites.Blog;
sc.Speaker_Websites_GitHub = source.Speaker.SpeakerWebsites.Blog;
sc.Speaker_Websites_Instagram = source.Speaker.SpeakerWebsites.Blog;
sc.Speaker_Websites_LinkedIn = source.Speaker.SpeakerWebsites.Blog;
sc.Speaker_Websites_TikTok = source.Speaker.SpeakerWebsites.Blog;
sc.Speaker_Websites_Twitter = source.Speaker.SpeakerWebsites.Blog;
sc.Speaker_Websites_Youtube = source.Speaker.SpeakerWebsites.Blog;
sc.Speech_Description = source.Speech.Description;
sc.Speech_ForWhichAudience = (int)source.Speech.ForWhichAudience;
sc.Speech_Tags = string.Join(",", source.Speech.Tags);
sc.Speech_TechnologyOrBussinessStory = (int)source.Speech.TechnologyOrBussinessStory;
sc.Speech_Title = source.Speech.Description;
sc.Version = source.Version;
sc.UniqueId = source.UniqueId.Value.ToString();
sc.Status = (int)source.Status;
return sc;
}
}
public class CallForSpeechTypeConverter : ITypeConverter<CallForSpeechTemp, CallForSpeech>
{
public CallForSpeech Convert(CallForSpeechTemp source, CallForSpeech destination, ResolutionContext context)
{
Category c = new Category(new CategoryId(source.CategoryId))
{
DisplayName = source.Category_DisplayName,
Name = source.Category_DisplayName,
WhatWeAreLookingFor = source.Category_WhatWeAreLookingFor,
};
SpeakerWebsites socialMedia = new SpeakerWebsites()
{
Blog = source.Speaker_Websites_Blog,
Facebook = source.Speaker_Websites_Facebook,
FanPageOnFacebook = source.Speaker_Websites_FanPageOnFacebook,
GitHub = source.Speaker_Websites_GitHub,
Instagram = source.Speaker_Websites_Instagram,
LinkedIN = source.Speaker_Websites_LinkedIn,
TikTok = source.Speaker_Websites_TikTok,
Twitter = source.Speaker_Websites_Twitter,
YouTube = source.Speaker_Websites_Youtube
};
Address address = new Address
(
source.Speaker_Adress_Country,
source.Speaker_Adress_ZipCode,
source.Speaker_Adress_Street,
source.Speaker_Adress_City
);
Name name = new Name(
source.Speaker_Name_First,
source.Speaker_Name_Last);
DateTime dateTime;
bool C = DateTime.TryParse(source.Speaker_Birthdate, out dateTime);
Contact cc = new Contact(source.Speaker_Contact_Email,
source.Speaker_Contact_Phone);
Speaker speaker = new Speaker(name, dateTime, address, socialMedia
, source.Speaker_BIO, cc);
CallForSpeechNumber callForSpeechNumber = new CallForSpeechNumber
(source.Number);
Speech speech = new Speech(source.Speech_Title, source.Speech_Description,
source.Speech_Tags.Split(","),
(ForWhichAudience)source.Speech_ForWhichAudience,
(TechnologyOrBussinessStory)source.Speech_TechnologyOrBussinessStory);
CallForSpeechStatus status = (CallForSpeechStatus)source.Status;
CallForSpeechMachineScore callForSpeechMachineScore =
(CallForSpeechMachineScore)source.Score_Score;
CallForSpeechScoringResult res =
new CallForSpeechScoringResult(callForSpeechMachineScore,
source.Score_RejectExplanation, source.Score_WarringExplanation);
DateTime dateTime2 = DateTime.Parse(source.Registration_RegistrationDate);
Registration registration = new Registration(dateTime2);
Decision decisionPreminal = null;
try
{
DateTime dateTime3 = DateTime.Parse(source.PreliminaryDecision_Date);
decisionPreminal =
new Decision(dateTime3, new JudgeId(source.PreliminaryDecision_DecisionBy.Value));
}
catch (Exception)
{
}
Decision decisionFinal = null;
try
{
DateTime dateTime4 = DateTime.Parse(source.FinalDecision_Date);
decisionFinal =
new Decision(dateTime4, new JudgeId(source.FinalDecision_DecisionBy.Value));
}
catch (Exception)
{
}
CallForSpeech sc = new CallForSpeech(callForSpeechNumber, status, speaker, speech, c,
res, registration,
decisionPreminal, decisionFinal, new CallForSpeechId(source.Id));
if (source.UniqueId != "")
sc.UniqueId = new CallForSpeechUniqueId(Guid.Parse(source.UniqueId));
sc.Version = source.Version;
return sc;
}
}
public class JudgeTempTypeConverter : ITypeConverter<Judge, JudgeTemp>
{
private class ValuesFromJugde
{
public string Birthdate { get; set; }
public string EmailForeConference { get; set; }
public string EmailForSpeakers { get; set; }
public string PhoneForSpekers { get; set; }
public string PhoneForConference { get; set; }
}
public JudgeTemp Convert(Judge source, JudgeTemp destination, ResolutionContext context)
{
var birthdate = source.Birthdate.ToString("dd-MM-yyyy");
int id = 0;
if (source.Id != null)
id = source.Id.Value;
string uniqueId = "";
if (source.UniqueId != null)
uniqueId = source.UniqueId.Value.ToString();
JudgeTemp j = new JudgeTemp()
{
Id = id,
BirthDate = birthdate,
CategoryId = source.Category.Id.Value,
Login = source.Login,
Name_First = source.Name.First,
Name_Last = source.Name.Last,
Password = source.Password,
Version = source.Version,
UniqueId = uniqueId,
};
return j;
}
}
public class JudgeTypeConverter : ITypeConverter<JudgeTemp, Judge>
{
public Judge Convert(JudgeTemp source, Judge destination, ResolutionContext context)
{
Category c = new Category(new CategoryId(source.CategoryId))
{
DisplayName = source.Category_DisplayName,
Name = source.Category_Name,
WhatWeAreLookingFor = source.Category_WhatWeAreLookingFor,
};
Login login = new Login(source.Login);
Password password = new Password(source.Password);
Name name = new Name(source.Name_First, source.Name_Last);
Judge j = new Judge(source.Id, login, password, name, c);
j.Birthdate = DateTime.Parse(source.BirthDate);
if (source.UniqueId != "")
j.UniqueId = new JudgeUniqueId(Guid.Parse(source.UniqueId));
j.Version = source.Version;
return j;
}
}
public class JudgeAddDoer : BeforeDoer, IJudgeAddDoer
{
private readonly IMapper _mapper;
public JudgeAddDoer(IGeekLemonDBContext geekLemonContext,
IMapper mapper)
{
_geekLemonContext = geekLemonContext;
_mapper = mapper;
}
public async Task<ExecutionStatus<JudgeIds>> Run(Judge entity)
{
using var connection = new SqliteConnection(_geekLemonContext.ConnectionString);
var q = @"INSERT INTO Judges
(Login, Password, BirthDate, Name_First,
Name_Last,CategoryID,
UniqueId, Version )
VALUES(@Login, @Password, @BirthDate,
@Name_First, @Name_Last, @CategoryId, @UniqueId,@Version);
SELECT seq From sqlite_sequence Where Name='Judges'";
//var v = GetValuesFromJugde(entity);
//var result = await connection.QueryAsync<int>(q,
// new
// {
// @Id = entity.Id,
// @Login = entity.Login,
// @Password = entity.Password,
// @BirthDate = v.Birthdate,
// @Name_First = entity.Name.First,
// @Name_Last = entity.Name.Last,
// @Email_ForeConference = v.EmailForeConference,
// @Email_ForSpeakers = v.EmailForSpeakers,
// @Phone_ForSpekers = v.PhoneForSpekers,
// @Phone_ForConference = v.PhoneForConference,
// @CategoryID = entity.Category.Id.Value
// });
var temp = _mapper.Map<JudgeTemp>(entity);
try
{
var result = await connection.QueryAsync<int>(q, temp);
int createdId = result.FirstOrDefault();
JudgeIds ids = new JudgeIds()
{
CreatedId = new JudgeId(createdId),
UniqueId = entity.UniqueId
};
return ExecutionStatus
<JudgeIds>.
DbIfDefaultThenError(ids);
}
catch (Exception ex)
{
return ExecutionStatus<JudgeIds>
.DbError(ex.Message);
}
}
}
public class JudgeGetAllDoer : BeforeDoer, IJudgeGetAllDoer
{
private readonly IMapper _mapper;
public JudgeGetAllDoer(IGeekLemonDBContext geekLemonContext,
IMapper mapper)
{
_geekLemonContext = geekLemonContext;
_mapper = mapper;
}
public async Task<ExecutionStatus<IReadOnlyList<Judge>>> Run()
{
using var connection = new SqliteConnection
(_geekLemonContext.ConnectionString);
var q = @$"SELECT j.Id, j.Login,j.Password,j.BirthDate,j.Name_First, j.Name_Last,
j.CategoryId, j.UniqueId ,j.Version ,
c.Name AS {nameof(JudgeTemp.Category_Name)},
c.DisplayName AS {nameof(JudgeTemp.Category_DisplayName)}
,c.WhatWeAreLookingFor AS {nameof(JudgeTemp.Category_WhatWeAreLookingFor)}
FROM Judges AS j
INNER JOIN Categories as C ON j.CategoryId = C.Id";
try
{
var r = await connection.QueryAsync<JudgeTemp>
(q);
var rmaped = _mapper.Map<IEnumerable<Judge>>(r);
//var r2 = await connection.QueryAsync<Judge>
//($"SELECT Id,Login AS {nameof(Judge.Login.Value)}," +
//$"Password AS {nameof(Judge.Password.Value)}, " +
//$"BirthDate AS {nameof(Judge.Birthdate)}, " +
//$"Name_First AS {nameof(Judge.Name.First)}, " +
//$"Name_Last, AS {nameof(Judge.Name.Last)}" +
//$"Email_ForeConference AS {nameof(Judg)}" +
//$",Email_ForSpeakers AS {nameof(Judge.Login.Value)}," +
//$"Phone_ForConference AS {nameof(Judge.Login.Value)}," +
//$"Phone_ForSpekers AS {nameof(Judge.Login.Value)}, " +
//$"CategoryId AS {nameof(Judge.Login.Value)} FROM Judges; ");
return ExecutionStatus<IReadOnlyList<Judge>>
.DbIfDefaultThenError(rmaped.ToList().AsReadOnly());
}
catch (Exception ex)
{
return ExecutionStatus<IReadOnlyList<Judge>>.DbError(ex.Message);
}
}
public class CallForSpeechSubmitDoer : BeforeDoer, ICallForSpeechSubmitDoer
{
private readonly IMapper _mapper;
public CallForSpeechSubmitDoer
(IGeekLemonDBContext geekLemonContext,
IMapper mapper)
{
_geekLemonContext = geekLemonContext;
_mapper = mapper;
}
public async Task<ExecutionStatus<CallForSpeechIds>>
Run(CallForSpeech callForSpeech)
{
var temp = _mapper.Map<CallForSpeechTemp>(callForSpeech);
using var connection = new SqliteConnection(_geekLemonContext.ConnectionString);
var q = SqlQueries.CallForSpeechInsert;
try
{
var result = await connection.QueryAsync<int>(q, temp);
int createdId = result.FirstOrDefault();
CallForSpeechIds ids = new CallForSpeechIds()
{
CreatedId = new CallForSpeechId(createdId),
UniqueId = callForSpeech.UniqueId
};
return ExecutionStatus<CallForSpeechIds>.DbOk(ids);
}
catch (Exception ex)
{
if (ExecutionFlow.Options.ThrowExceptions)
throw;
return ExecutionStatus<CallForSpeechIds>.DbError(ex);
}
}
}
public class CallForSpeechSaveRejectionDoer : BeforeDoer, ICallForSpeechSaveRejectionDoer
{
private readonly IMapper _mapper;
public CallForSpeechSaveRejectionDoer
(IGeekLemonDBContext geekLemonContext,
IMapper mapper)
{
_geekLemonContext = geekLemonContext;
_mapper = mapper;
}
public async Task<ExecutionStatus> Run
(CallForSpeechUniqueId id, JudgeId judge, CallForSpeechStatus status)
{
using var connection = new SqliteConnection(_geekLemonContext.ConnectionString);
var q = @"UPDATE CallForSpeakes
SET PreliminaryDecision_DecisionBy = @JudgeId,
PreliminaryDecision_Date = @Date,
Status = @Status
WHERE UniqueId = @UniqueId;";
try
{
var result = await connection.ExecuteAsync(q,
new
{
@JudgeId = judge.Value,
@Date = AppTime.Now().ToLongDateString(),
@UniqueId = id.Value.ToString(),
@Status = (int)status
});
return ExecutionStatus.DbOk();
}
catch (Exception ex)
{
if (ExecutionFlow.Options.ThrowExceptions)
throw;
return ExecutionStatus.DbError(ex);
}
}
public async Task<ExecutionStatus> Run
(CallForSpeechId id, JudgeId judge, CallForSpeechStatus status)
{
using var connection = new SqliteConnection(_geekLemonContext.ConnectionString);
var q = @"UPDATE CallForSpeakes
SET PreliminaryDecision_DecisionBy = @JudgeId,
PreliminaryDecision_Date = @Date,
Status = @Status
WHERE Id = @Id;";
try
{
var result = await connection.ExecuteAsync(q,
new
{
@JudgeId = judge.Value,
@Date = AppTime.Now().ToLongDateString(),
@Id = id.Value,
@Status = (int)status
});
return ExecutionStatus.DbOk();
}
catch (Exception ex)
{
if (ExecutionFlow.Options.ThrowExceptions)
throw;
return ExecutionStatus.DbError(ex);
}
}
}
public class CallForSpeechSaveEvaluatationDoer : BeforeDoer,
ICallForSpeechSaveEvaluatationDoer
{
private readonly IMapper _mapper;
public CallForSpeechSaveEvaluatationDoer
(IGeekLemonDBContext geekLemonContext,
IMapper mapper)
{
_geekLemonContext = geekLemonContext;
_mapper = mapper;
}
public async Task<ExecutionStatus> Run(CallForSpeechUniqueId id,
CallForSpeechScoringResult score, CallForSpeechStatus status)
{
using var connection = new SqliteConnection(_geekLemonContext.ConnectionString);
var q = @"UPDATE CallForSpeakes
SET Score_Score = @Score,
Score_RejectExplanation = @RejectExplanation,
Score_WarringExplanation = @WarringExplanation,
Status = @Status
WHERE UniqueId = @UniqueId;";
try
{
var result = await connection.ExecuteAsync(q,
new
{
@Score = (int)score.Score,
@WarringExplanation = score.WarringExplanation,
@RejectExplanation = score.RejectExplanation,
@UniqueId = id.Value.ToString(),
@Status = (int)status
});
return ExecutionStatus.DbOk();
}
catch (Exception ex)
{
if (ExecutionFlow.Options.ThrowExceptions)
throw;
return ExecutionStatus.DbError(ex);
}
}
public async Task<ExecutionStatus> Run(CallForSpeechId id,
CallForSpeechScoringResult score, CallForSpeechStatus status)
{
using var connection = new SqliteConnection(_geekLemonContext.ConnectionString);
var q = @"UPDATE CallForSpeakes
SET Score_Score = @Score,
Score_RejectExplanation = @RejectExplanation,
Score_WarringExplanation = @WarringExplanation,
Status = @Status
WHERE Id = @Id;";
try
{
var result = await connection.ExecuteAsync(q,
new
{
@Score = (int)score.Score,
@WarringExplanation = score.WarringExplanation,
@RejectExplanation = score.RejectExplanation,
@Id = id.Value,
@Status = (int)status
});
return ExecutionStatus.DbOk();
}
catch (Exception ex)
{
if (ExecutionFlow.Options.ThrowExceptions)
throw;
return ExecutionStatus.DbError(ex);
}
}
}
public static partial class GeekLemonConferenceInstallers
{
public static IServiceCollection
AddGeekLemonPersistenceDapperSQLiteServices
(this IServiceCollection services,
IConfiguration configuration)
{
//If Scoped or Singleton then Two version of repositories will use one version of this
services.AddTransient<ICallForSpeechGetByIdDoer, CallForSpeechGetByIdDoer>();
services.AddTransient<ICallForSpeechGetCollectionDoer, CallForSpeechGetCollectionDoer>();
services.AddTransient<ICallForSpeechSaveAcceptenceDoer, CallForSpeechSaveAcceptenceDoer>();
services.AddTransient<ICallForSpeechSaveEvaluatationDoer, CallForSpeechSaveEvaluatationDoer>();
services.AddTransient<ICallForSpeechSavePreliminaryAcceptenceDoer,
CallForSpeechSavePreliminaryAcceptenceDoer>();
services.AddTransient<ICallForSpeechSaveRejectionDoer, CallForSpeechSaveRejectionDoer>();
services.AddTransient<ICallForSpeechSubmitDoer, CallForSpeechSubmitDoer>();
services.AddTransient<ICategoryAddDoer, CategoryAddDoer>();
services.AddTransient<ICategoryGetAllDoer, CategoryGetAllDoer>();
services.AddTransient<ICategoryDeleteDoer, CategoryDeleteDoer>();
services.AddTransient<ICategoryGetByIdDoer, CategoryGetByIdDoer>();
services.AddTransient<ICategoryUpdateDoer, CategoryUpdateDoer>();
services.AddTransient<IJudgeAddDoer, JudgeAddDoer>();
services.AddTransient<IJudgeUpdateDoer, JudgeUpdateDoer>();
services.AddTransient<IJudgeDeleteDoer, JudgeDeleteDoer>();
services.AddTransient<IJudgeGetAllDoer, JudgeGetAllDoer>();
services.AddTransient<IJudgeGetByIdDoer, JudgeGetByIdDoer>();
services.AddTransient<ICategoryRepository, CategoryRepository>();
services.AddTransient<IJudgeRepository, JugdeRepository>();
services.AddTransient<ICallForSpeechRepository, CallForSpeechRepository>();
services.AddTransient<IZEsCategoryRepository, ZEsCategoryRepository>();
services.AddTransient<IZEsJudgeRepository, ZEsJugdeRepository>();
services.AddTransient<IZEsCallForSpeechRepository, ZEsCallForSpeechRepository>();
SqlMapper.RemoveTypeMap(typeof(DateTimeOffset));
SqlMapper.AddTypeHandler(DateTimeHandler.Default);
services.AddAutoMapper(Assembly.GetExecutingAssembly());
var connection = configuration.
GetConnectionString("GeekLemonConferenceConnectionString");
var zEsConnection = configuration.
GetConnectionString("ZEsGeekLemonConferenceConnectionString");
services.AddTransient<IGeekLemonDBContext, GeekLemonDBContext>
(
(services) =>
{
var c =
new GeekLemonDBContext(connection);
return c;
}
);
services.AddTransient<IZEsGeekLemonDBContext, ZEsGeekLemonDBContext>
(
(services) =>
{
var c =
new ZEsGeekLemonDBContext(zEsConnection);
return c;
}
);
return services;
}
}
public static class CopyDataBase
{
public static string Run()
{
int i = new Random().Next(0, int.MaxValue);
var codeBaseUrl = new Uri(Assembly.GetExecutingAssembly().Location);
var codeBasePath = Uri.UnescapeDataString(codeBaseUrl.AbsolutePath);
var dirPath = Path.GetDirectoryName(codeBasePath);
var pathtodatabasefile = dirPath + "\\DataBaseExample" + "\\GeekLemonTestDataBase.db";
var folder = dirPath + "\\DataBaseExample" + $"\\Temp\\";
System.IO.DirectoryInfo di = new DirectoryInfo(folder);
foreach (FileInfo file in di.GetFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in di.GetDirectories())
{
dir.Delete(true);
}
Directory.CreateDirectory(folder);
var dest = dirPath + "\\DataBaseExample" + $"\\Temp\\TEMPCOPY{i}.db";
File.Copy(pathtodatabasefile, dest);
return dest;
}
}
public class CategoryDataBaseIntegrationTest : IDisposable
{
private GeekLemonDBContext _geekLemonContex;
private IMapper _mapper;
private string _tempdatabasefile;
public CategoryDataBaseIntegrationTest()
{
_tempdatabasefile = CopyDataBase.Run();
if (_geekLemonContex == null)
_geekLemonContex =
new GeekLemonDBContext(
$"Data Source={_tempdatabasefile}");
if (_mapper == null)
{
var mappingConfig = new MapperConfiguration(mc =>
{
mc.AddProfile(new MappingProfile());
});
IMapper mapper = mappingConfig.CreateMapper();
_mapper = mapper;
}
}
public void Dispose()
{
//try
//{
// File.Delete(_tempdatabasefile);
// Directory.Delete(_tempdatabasefile.Replace("\\TEMPCOPY{i}.db", ""));
//}
//catch (Exception
//ex)
//{
//}
}
[Fact]
public async Task CreateCategoryShouldBeSuccessThenGetByIdShouldbeAlsoASuccess()
{
//SetupCategories();
CategoryAddDoer categoryAddDoer =
new CategoryAddDoer(_geekLemonContex, _mapper);
var cat = GivenCategory().WithId(1).WithName("AAA")
.Build();
var status = await categoryAddDoer.Run(cat);
status.Success.Should().BeTrue();
CategoryGetByIdDoer categoryGetByIdDoer =
new CategoryGetByIdDoer(_geekLemonContex, _mapper);
var status2 = await categoryGetByIdDoer.Run(
status.Value.CreatedId as CategoryId);
status2.Success.Should().BeTrue();
status2.Value.Should().Equals(cat);
}
[Fact]
public async Task CreateCategoryShouldBeSuccessThenGetByUniqueIdShouldbeAlsoASuccess()
{
//SetupCategories();
CategoryAddDoer categoryAddDoer =
new CategoryAddDoer(_geekLemonContex, _mapper);
var cat = GivenCategory().WithId(1).WithName("AAA")
.Build();
var status = await categoryAddDoer.Run(cat);
status.Success.Should().BeTrue();
CategoryGetByIdDoer categoryGetByIdDoer =
new CategoryGetByIdDoer(_geekLemonContex, _mapper);
var status2 = await categoryGetByIdDoer.Run(
status.Value.UniqueId as CategoryUniqueId);
status2.Success.Should().BeTrue();
status2.Value.Should().Equals(cat);
}
[Fact]
public async Task CreateCategoryShouldBeSuccessThenGetAllShouldbeAlsoASuccess()
{
//SetupCategories();
CategoryAddDoer categoryAddDoer =
new CategoryAddDoer(_geekLemonContex, _mapper);
var cat = GivenCategory().WithId(1).WithName("AAA")
.Build();
var status = await categoryAddDoer.Run(cat);
status.Success.Should().BeTrue();
CategoryGetAllDoer categoryGetAllDoer =
new CategoryGetAllDoer(_geekLemonContex, _mapper);
var status2 = await categoryGetAllDoer.Run();
status2.Success.Should().BeTrue();
status2.Value.Should().HaveCount(1);
}
[Fact]
public async Task CreateCategoryShouldBeSuccessThenDeleteThenTryGetByIdAndFail()
{
CategoryAddDoer categoryAddDoer =
new CategoryAddDoer(_geekLemonContex, _mapper);
var cat = GivenCategory().WithId(1).WithName("AAA")
.Build();
var status = await categoryAddDoer.Run(cat);
status.Success.Should().BeTrue();
CategoryDeleteDoer categoryDeleteDoer =
new CategoryDeleteDoer(_geekLemonContex, _mapper);
var status2 = await categoryDeleteDoer.Run(
status.Value.CreatedId as CategoryId);
status2.Success.Should().BeTrue();
CategoryGetByIdDoer categoryGetByIdDoer =
new CategoryGetByIdDoer(_geekLemonContex, _mapper);
var status3 = await categoryGetByIdDoer.Run(
status.Value.CreatedId as CategoryId);
status3.Success.Should().BeFalse();
}
[Fact]
public async Task CreateCategoryShouldBeSuccessThenDeleteByUniqueIdThenTryGetByUniqueIdAndFail()
{
CategoryAddDoer categoryAddDoer =
new CategoryAddDoer(_geekLemonContex, _mapper);
var cat = GivenCategory().WithId(1).WithName("AAA")
.Build();
var status = await categoryAddDoer.Run(cat);
status.Success.Should().BeTrue();
CategoryDeleteDoer categoryDeleteDoer =
new CategoryDeleteDoer(_geekLemonContex, _mapper);
var status2 = await categoryDeleteDoer.Run(
status.Value.UniqueId as CategoryUniqueId);
status2.Success.Should().BeTrue();
CategoryGetByIdDoer categoryGetByIdDoer =
new CategoryGetByIdDoer(_geekLemonContex, _mapper);
var status3 = await categoryGetByIdDoer.Run(
status.Value.UniqueId as CategoryUniqueId);
status3.Success.Should().BeFalse();
}
[Fact]
public async Task CreateCategoryThenUpdatedShoudlBeSuccessById()
{
//SetupCategories();
CategoryAddDoer categoryAddDoer =
new CategoryAddDoer(_geekLemonContex, _mapper);
var cat = GivenCategory().WithId(1).WithName("AAA")
.Build();
var status = await categoryAddDoer.Run(cat);
status.Success.Should().BeTrue();
CategoryUpdateDoer categoryUpdateDoer =
new CategoryUpdateDoer(_geekLemonContex, _mapper);
var cat2 = GivenCategory().WithId(1).WithName("2222")
.WithDisplayName("3333")
.WithWhatWeAreLookingFor("4444")
.Build();
var status2 = await categoryUpdateDoer.Run(cat2, ByWhatId.CreatedId);
status2.Success.Should().BeTrue();
CategoryGetByIdDoer categoryGetByIdDoer =
new CategoryGetByIdDoer(_geekLemonContex, _mapper);
var status3 = await categoryGetByIdDoer.Run(
status.Value.UniqueId as CategoryUniqueId);
status3.Success.Should().BeTrue();
status3.Value.Should().NotBeSameAs(cat);
}
[Fact]
public async Task CreateCategoryThenUpdatedShoudlBeSuccessByUniqueId()
{
//SetupCategories();
CategoryAddDoer categoryAddDoer =
new CategoryAddDoer(_geekLemonContex, _mapper);
var cat = GivenCategory().WithId(1).WithName("AAA")
.Build();
var status = await categoryAddDoer.Run(cat);
status.Success.Should().BeTrue();
CategoryGetByIdDoer categoryGetByIdDoer =
new CategoryGetByIdDoer(_geekLemonContex, _mapper);
var status2 = await categoryGetByIdDoer.Run(
status.Value.UniqueId as CategoryUniqueId);
CategoryUpdateDoer categoryUpdateDoer =
new CategoryUpdateDoer(_geekLemonContex, _mapper);
var cat2 = GivenCategory().WithId(1).WithName("2222")
.WithDisplayName("3333")
.WithWhatWeAreLookingFor("4444")
.Build();
var status3 = await categoryUpdateDoer.Run(cat2, ByWhatId.UniqueId);
status3.Success.Should().BeTrue();
var status4 = await categoryGetByIdDoer.Run(
status.Value.UniqueId as CategoryUniqueId);
status3.Success.Should().BeTrue();
status4.Value.Should().NotBeSameAs(cat);
}
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Core" Version="5.2.7" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.0.7" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.0.7" />
<PackageReference Include="Swashbuckle.Core" Version="5.6.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GeekLemon.Infrastructure.Read.SQLite\GeekLemonConference.Persistence.Dapper.SQLite.csproj" />
<ProjectReference Include="..\GeekLemon.Infrastructure.Write.MongoDB\GeekLemonConference.Infrastructure.EventStoreAndBus.csproj" />
<ProjectReference Include="..\GeekLemonConference.Application.CQRS\GeekLemonConference.Application.CQRS.csproj" />
<ProjectReference Include="..\GeekLemonConference.Application.EventSourcing\GeekLemonConference.Application.EventSourcing.csproj" />
<ProjectReference Include="..\GeekLemonConference.Infrastructure.EventStore.MongoDb\GeekLemonConference.Infrastructure.EventStorePlugin.MongoDb.csproj" />
<ProjectReference Include="..\GeekLemonConference.Infrastructure.EventStore.SQLite\GeekLemonConference.Infrastructure.EventStorePlugin.SQLite.csproj" />
</ItemGroup>
</Project>
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddSwaggerGen(c =>
{
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = @"JWT Authorization header using the Bearer scheme. \r\n\r\n
Enter 'Bearer' [space] and then your token in the text input below.
\r\n\r\nExample: 'Bearer 12345abcdef'",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer"
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
},
Scheme = "oauth2",
Name = "Bearer",
In = ParameterLocation.Header,
},
new List<string>()
}
});
c.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "GeekLemonConference API",
});
});
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "GeekLemonConference API");
});
app.UseCors("Open");
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddGeekLemonConferenceCQRS(Configuration);
services.AddGeekLemonPersistenceDapperSQLiteServices(Configuration);
////services.AddDefaultEventStore();
//services.AddEventStoreSqlLite(Configuration);
////services.AddEventStoreMongoDb(Configuration);
//services.AddBusAndRepository(Configuration);
services.AddControllers();
services.AddCors(options =>
{
options.AddPolicy("Open",
builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
});
}
{
"ConnectionStrings": {
"GeekLemonConferenceConnectionString": "DataSource=./DataBase/GeekLemonDB.db",
"ZEsGeekLemonConferenceConnectionString": "DataSource=./DataBase/ZEsGeekLemonDB.db",
"EventStoreSQLiteConnectionString": "DataSource=./DataBase/EventStoreDB.db"
},
"RabbitMqSetting": {
"username": "guest",
"password": "guest",
"hostname": "localhost",
"uri": "amqp://localhost:5672/",
"virtualhost": "/"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
public abstract class BaseGeekLemonController : Controller
{
protected virtual MethodFailureResult MethodFailure([ActionResultObjectValue] object value)
{
return new MethodFailureResult(value);
}
}
[DefaultStatusCode(DefaultStatusCode)]
public class MethodFailureResult : ObjectResult
{
//private const int DefaultStatusCode = 420;
private const int DefaultStatusCode = 500;
/// <summary>
/// Creates a new <see cref="NotFoundObjectResult"/> instance.
/// </summary>
/// <param name="value">The value to format in the entity body.</param>
public MethodFailureResult([ActionResultObjectValue] object value)
: base(value)
{
StatusCode = DefaultStatusCode;
}
}
[Route("api/[controller]")]
[ApiController]
public class CallForSpeechController : BaseGeekLemonController
{
private readonly IMediator _mediator;
public CallForSpeechController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet("all/{filter}", Name = "getallcallforspeeches")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
public async Task<ActionResult<List<CallForSpeechInListViewModel>>> GetAllCallForSpeeches
(int filter)
{
GetAllCallForSpeechesQuery getAllCallForSpeechesQuery = new GetAllCallForSpeechesQuery()
{
Filter = (FilterCallForSpeechStyles)filter,
queryWitchDataBase = QueryWitchDataBase.NormalCQRS
};
var result = await _mediator.Send(getAllCallForSpeechesQuery);
if (result.Status == ResponseStatus.BussinesLogicError)
return Forbid();
if (result.Status == ResponseStatus.NotFoundInDataBase)
return NotFound();
if (result.Status == ResponseStatus.ValidationError)
return BadRequest();
if (result.Status == ResponseStatus.BadQuery)
return BadRequest();
if (!result.Success)
return MethodFailure(result.Message);
return Ok(result.List);
}
[HttpGet("id/{id}", Name = "GetCallForSpeechById")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
[ProducesDefaultResponseType]
public async Task<ActionResult<CallForSpeechViewModel>> GetCallForSpeechById(int id)
{
var result = await _mediator.Send(
(new GetCallForSpeechQuery()
{
CallForSpeechId = new CallForSpeechId(id),
queryWitchDataBase = QueryWitchDataBase.NormalCQRS
}));
if (result.Status == ResponseStatus.BussinesLogicError)
return Forbid();
if (result.Status == ResponseStatus.NotFoundInDataBase)
return NotFound();
if (result.Status == ResponseStatus.ValidationError)
return BadRequest();
if (result.Status == ResponseStatus.BadQuery)
return BadRequest();
if (!result.Success)
return MethodFailure(result.Message);
return Ok(result.CallForSpeech);
}
[HttpGet("uniqueid/{uid}", Name = "GetCallForSpeechByUniqueId")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
[ProducesDefaultResponseType]
public async Task<ActionResult<CallForSpeechViewModel>> GetCallForSpeechByUniqueId(Guid uid)
{
var result = await _mediator.Send(
(new GetCallForSpeechQuery()
{
CallForSpeechUniqueId = new CallForSpeechUniqueId(uid),
queryWitchDataBase = QueryWitchDataBase.NormalCQRS
}));
return Ok(result.CallForSpeech);
}
[HttpPost("submit", Name = "submitcallforspeech")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
public async Task<ActionResult<CallForSpeechIds>> Submit([FromBody] CreateCallForSpeaker request)
{
SubmitCallForSpeechCommand s = new SubmitCallForSpeechCommand()
{
Speaker = request.Speaker,
CategoryId = request.CategoryId,
Speech = request.Speech,
Number = request.Number,
};
var result = await _mediator.Send(s);
if (result.Status == ResponseStatus.BussinesLogicError)
return Forbid();
if (result.Status == ResponseStatus.NotFoundInDataBase)
return NotFound();
if (result.Status == ResponseStatus.ValidationError)
return BadRequest();
if (result.Status == ResponseStatus.BadQuery)
return BadRequest();
if (!result.Success)
return MethodFailure(result.Message);
return Ok(result.CallForSpeechCommandIds);
}
[HttpPost("reject", Name = "rejectcallforspeech")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
public async Task<ActionResult<int>> Reject([FromBody] RejectCallForSpeechCommand rejectCallForSpeechCommand)
{
var result = await _mediator.Send(rejectCallForSpeechCommand);
if (result.Status == ResponseStatus.BussinesLogicError)
return Forbid();
if (result.Status == ResponseStatus.NotFoundInDataBase)
return NotFound();
if (result.Status == ResponseStatus.ValidationError)
return BadRequest();
if (result.Status == ResponseStatus.BadQuery)
return BadRequest();
if (!result.Success)
return MethodFailure(result.Message);
return NoContent();
}
[HttpPost("evaluate", Name = "evaluatecallforspeech")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
public async Task<ActionResult<int>> Evaluate([FromBody] EvaluateCallForSpeechCommand evaluateCallForSpeechCommand)
{
var result = await _mediator.Send(evaluateCallForSpeechCommand);
if (result.Status == ResponseStatus.BussinesLogicError)
return Forbid();
if (result.Status == ResponseStatus.NotFoundInDataBase)
return NotFound();
if (result.Status == ResponseStatus.ValidationError)
return BadRequest();
if (result.Status == ResponseStatus.BadQuery)
return BadRequest();
if (!result.Success)
return MethodFailure(result.Message);
return Ok(result);
}
[HttpPost("accept", Name = "acceptcallforspeech")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
public async Task<ActionResult<int>> Accept([FromBody] AcceptCallForSpeechCommand ccceptCallForSpeechCommand)
{
var result = await _mediator.Send(ccceptCallForSpeechCommand);
if (result.Status == ResponseStatus.BussinesLogicError)
return Forbid();
if (result.Status == ResponseStatus.NotFoundInDataBase)
return NotFound();
if (result.Status == ResponseStatus.ValidationError)
return BadRequest();
if (result.Status == ResponseStatus.BadQuery)
return BadRequest();
if (!result.Success)
return MethodFailure(result.Message);
return NoContent();
}
[HttpPost("preliminaryaccept", Name = "preliminaryacceptcallforspeech")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
public async Task<ActionResult<int>> PreliminaryAccept([FromBody] PreliminaryAcceptCallForSpeechCommand preliminaryCallForSpeechCommand)
{
var result = await _mediator.Send(preliminaryCallForSpeechCommand);
if (result.Status == ResponseStatus.BussinesLogicError)
return Forbid();
if (result.Status == ResponseStatus.NotFoundInDataBase)
return NotFound();
if (result.Status == ResponseStatus.ValidationError)
return BadRequest();
if (result.Status == ResponseStatus.BadQuery)
return BadRequest();
if (!result.Success)
return MethodFailure(result.Message);
return NoContent();
}
}
[Route("api/[controller]")]
[ApiController]
public class CategoryController : BaseGeekLemonController
{
private readonly IMediator _mediator;
public CategoryController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet("all", Name = "getallcategories")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
public async Task<ActionResult<List<CategoryInListViewModel>>> GetAllCategories()
{
var result = await _mediator.Send(new GetCategoriesListQuery());
if (result.Status == ResponseStatus.BussinesLogicError)
return Forbid(result.Message);
if (result.Status == ResponseStatus.NotFoundInDataBase)
return NotFound(result.Message);
if (result.Status == ResponseStatus.ValidationError)
return BadRequest(result.Message);
if (result.Status == ResponseStatus.BadQuery)
return BadRequest(result.Message);
if (!result.Success)
return MethodFailure(result.Message);
return Ok(result.List);
}
[HttpGet("byId/{id}", Name = "GetCategoryById")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
[ProducesDefaultResponseType]
public async Task<ActionResult<CategoryDto>> GetCategoryById(int id)
{
var result = await _mediator.Send
(new GetCategoryQuery()
{ CategoryId = new CategoryId(id) });
if (result.Status == ResponseStatus.BussinesLogicError)
return Forbid(result.Message);
if (result.Status == ResponseStatus.NotFoundInDataBase)
return NotFound(result.Message);
if (result.Status == ResponseStatus.ValidationError)
return BadRequest(result.Message);
if (result.Status == ResponseStatus.BadQuery)
return BadRequest(result.Message);
if (!result.Success)
return MethodFailure(result.Message);
return Ok(result.Category);
}
[HttpGet("byuniqueid/{uid}", Name = "GetCategoryByUniqueId")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
[ProducesDefaultResponseType]
public async Task<ActionResult<CategoryDto>> GetCategoryByUniqueId(Guid uid)
{
var result = await _mediator.Send
(new GetCategoryQuery()
{ CategoryUniqueId = new CategoryUniqueId(uid) });
if (result.Status == ResponseStatus.BussinesLogicError)
return Forbid(result.Message);
if (result.Status == ResponseStatus.NotFoundInDataBase)
return NotFound(result.Message);
if (result.Status == ResponseStatus.ValidationError)
return BadRequest(result.Message);
if (result.Status == ResponseStatus.BadQuery)
return BadRequest(result.Message);
if (!result.Success)
return MethodFailure(result.Message);
return Ok(result.Category);
}
[HttpPut("byId", Name = "updateByIdcategory")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
[ProducesDefaultResponseType]
public async Task<ActionResult> UpdateById([FromBody] UpdateCategoryById u)
{
UpdateCategoryCommand updateCommand = new UpdateCategoryCommand()
{
DisplayName = u.DisplayName,
Id = u.Id,
Name = u.Name,
WhatWeAreLookingFor = u.WhatWeAreLookingFor
};
var result = await _mediator.Send(updateCommand);
return NoContent();
}
[HttpPut("ByUniqueId", Name = "updateByUniqueIdcategory")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
[ProducesDefaultResponseType]
public async Task<ActionResult> UpdateByUniqueId([FromBody] UpdateCategoryByUniqueId u)
{
UpdateCategoryCommand updateCommand = new UpdateCategoryCommand()
{
DisplayName = u.DisplayName,
UniqueId = u.UniqueId,
Name = u.Name,
WhatWeAreLookingFor = u.WhatWeAreLookingFor
};
var result = await _mediator.Send(updateCommand);
return NoContent();
}
[HttpPost(Name = "addcategory")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
public async Task<ActionResult<IdsDto>> Create
([FromBody] CreatedCategoryCommand createCategoryCommand)
{
var result = await _mediator.Send(createCategoryCommand);
if (result.Status == ResponseStatus.BussinesLogicError)
return Forbid(result.Message);
if (result.Status == ResponseStatus.NotFoundInDataBase)
return NotFound(result.Message);
if (result.Status == ResponseStatus.ValidationError)
return BadRequest(result.Message);
if (result.Status == ResponseStatus.BadQuery)
return BadRequest(result.Message);
if (!result.Success)
return MethodFailure(result.Message);
return Ok(result.CategoryIds);
}
}
[Route("api/[controller]")]
[ApiController]
public class JudgeController : BaseGeekLemonController
{
private readonly IMediator _mediator;
public JudgeController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet("all", Name = "getalljudges")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
public async Task<ActionResult<List<JudgesInListViewModel>>> GetAllPosts()
{
var result = await _mediator.Send(new GetJudgesInListQuery());
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.Forbid)
return Forbid(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.NotFound)
return NotFound(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.BadRequest)
return BadRequest(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.MethodFailure)
return MethodFailure(result.Message);
return Ok(result.List);
}
[HttpGet("byid/{id}", Name = "getjudge")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
[ProducesDefaultResponseType]
public async Task<ActionResult<JudgeViewModel>> GetJudgeById(int id)
{
var result = await _mediator.Send
(new GetJudgeQuery() { JudeId = new JudgeId(id) });
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.Forbid)
return Forbid(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.NotFound)
return NotFound(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.BadRequest)
return BadRequest(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.MethodFailure)
return MethodFailure(result.Message);
return Ok(result.Judge);
}
[HttpGet("byuqniqueid/{uid}", Name = "GetJudgeByUniqueId")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
[ProducesDefaultResponseType]
public async Task<ActionResult<JudgeViewModel>> GetJudgeByUniqueId(Guid uid)
{
var result = await _mediator.Send
(new GetJudgeQuery() { JudgeUniqueId = new JudgeUniqueId(uid) });
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.Forbid)
return Forbid(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.NotFound)
return NotFound(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.BadRequest)
return BadRequest(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.MethodFailure)
return MethodFailure(result.Message);
return Ok(result.Judge);
}
[HttpPost(Name = "addjudge")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
public async Task<ActionResult<JudgeIds>> Create([FromBody] CreateJudgeRequest judge)
{
CreateJudgeCommand c = new CreateJudgeCommand()
{
Birthdate = judge.Birthdate,
CategoryId = judge.CategoryId,
Login = judge.Login,
Name = judge.Name,
Password = judge.Password,
};
var result = await _mediator.Send(c);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.Forbid)
return Forbid(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.NotFound)
return NotFound(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.BadRequest)
return BadRequest(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.MethodFailure)
return MethodFailure(result.Message);
return Ok(result.JudgeIds);
}
[HttpPut("ByUniqueId", Name = "UpdateByUniqueId")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
[ProducesDefaultResponseType]
public async Task<ActionResult> UpdateByUniqueId([FromBody] UpdateJudgeByUniqueId u)
{
UpdateJudgeCommand updateJudge = new UpdateJudgeCommand()
{
UniqueId = u.UniqueId,
Name = u.Name,
Login = u.Password,
Password = u.Password,
Birthdate = u.Birthdate,
CategoryId = u.CategoryId,
};
var result = await _mediator.Send(updateJudge);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.Forbid)
return Forbid(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.NotFound)
return NotFound(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.BadRequest)
return BadRequest(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.MethodFailure)
return MethodFailure(result.Message);
return NoContent();
}
[HttpPut("ById", Name = "UpdateById")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
[ProducesDefaultResponseType]
public async Task<ActionResult> UpdateById([FromBody] UpdateJudgeById u)
{
UpdateJudgeCommand updateJudge = new UpdateJudgeCommand()
{
Id = u.Id,
Name = u.Name,
Login = u.Password,
Password = u.Password,
Birthdate = u.Birthdate,
CategoryId = u.CategoryId,
};
var result = await _mediator.Send(updateJudge);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.Forbid)
return Forbid(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.NotFound)
return NotFound(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.BadRequest)
return BadRequest(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.MethodFailure)
return MethodFailure(result.Message);
return NoContent();
}
[HttpDelete("byuniqueId/{id}", Name = "deletejudgedByUniqueId")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
[ProducesDefaultResponseType]
public async Task<ActionResult> DeleteByUniqueId(Guid id)
{
var deletepostCommand = new DeleteJudgeCommand()
{
UniqueId
= new JudgeUniqueId(id)
};
var result = await _mediator.Send(deletepostCommand);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.Forbid)
return Forbid(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.NotFound)
return NotFound(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.BadRequest)
return BadRequest(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.MethodFailure)
return MethodFailure(result.Message);
return NoContent();
}
[HttpDelete("byId/{id}", Name = "deletejudgebyid")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(420)]
[ProducesDefaultResponseType]
public async Task<ActionResult> DeleteById(int id)
{
var deletepostCommand = new DeleteJudgeCommand()
{
Id
= new JudgeId(id)
};
var result = await _mediator.Send(deletepostCommand);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.Forbid)
return Forbid(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.NotFound)
return NotFound(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.BadRequest)
return BadRequest(result.Message);
if (result.WhatHTTPCodeToBeRetruned == WhatHTTPCodeShouldBeRetruned.MethodFailure)
return MethodFailure(result.Message);
return NoContent();
}
}
public interface IMessage
{
}
public interface IEvent : IMessage
{
public int Version { get; set; }
DateTimeOffset TimeStamp { get; set; }
}
public abstract class DomainEvent : IEvent
{
public AggregateKey Key { get; set; }
public int Version { get; set; }
public DateTimeOffset TimeStamp { get; set; }
protected DomainEvent(DateTimeOffset occuredOn, int version)
{
TimeStamp = occuredOn;
Version = version;
}
protected DomainEvent(int version)
{
TimeStamp = AppTime.Now();
Version = version;
}
protected DomainEvent()
{
}
}
public class AggregateKey : ValueObject<AggregateKey>
{
public string Type { get; set; }
public string Id { get; set; }
protected override IEnumerable<object> GetAttributesToIncludeInEqualityCheck()
{
yield return Type;
yield return Id;
}
public static readonly AggregateKey Empty = new AggregateKey();
public override string ToString()
{
return Id;
}
}
public abstract class BaseUniqueId<T>
: ValueObject<T> where T : ValueObject<T>
{
public abstract string ValueInString();
protected abstract string GetName();
public AggregateKey GetAggregateKey()
{
return new AggregateKey
{
Id = ValueInString(),
Type = GetName()
};
}
public BaseUniqueId()
{
}
}
public class CategoryCreateEvent : DomainEvent
{
public CategoryUniqueId UniqueId { get; init; }
public string Name { get; init; }
public string DisplayName { get; init; }
public string WhatWeAreLookingFor { get; init; }
public CategoryCreateEvent(CategoryUniqueId uniqueId,
string Name, string displayName, string whatWeAreLookingFor,
int version)
: base(version)
{
UniqueId = uniqueId;
Key = this.UniqueId.GetAggregateKey();
DisplayName = displayName;
WhatWeAreLookingFor = whatWeAreLookingFor;
}
}
public class CategoryUpdateEvent : DomainEvent
{
public CategoryUniqueId UniqueId { get; init; }
public string Name { get; init; }
public string DisplayName { get; init; }
public string WhatWeAreLookingFor { get; init; }
public CategoryUpdateEvent(CategoryUniqueId uniqueId,
string Name, string displayName, string whatWeAreLookingFor,
int version)
: base(version)
{
UniqueId = uniqueId;
Key = this.UniqueId.GetAggregateKey();
DisplayName = displayName;
WhatWeAreLookingFor = whatWeAreLookingFor;
}
}
public class JudgeCreatedEvent : DomainEvent
{
public Login Login { get; init; }
public Password Password { get; init; }
public Name Name { get; init; }
public Category Category { get; init; }
public DateTime Birthdate { get; init; }
public JudgeUniqueId UniqueId { get; init; }
public JudgeCreatedEvent(DateTime birthdate,
Category category, JudgeUniqueId uniqueId,
Login login, Password password, Name name,
int version) :
base(version)
{
Birthdate = birthdate;
Category = category;
UniqueId = uniqueId;
Login = login;
Name = name;
Password = password;
Key = this.UniqueId.GetAggregateKey();
Version = version;
}
public JudgeCreatedEvent()
{
}
}
public class JudgeDeletedEvent : DomainEvent
{
public JudgeUniqueId UniqueId { get; init; }
public JudgeDeletedEvent(int version) :
base(version)
{
}
public JudgeDeletedEvent()
{
}
}
public class JudgeUpdatedEvent : DomainEvent
{
public Login Login { get; init; }
public Password Password { get; init; }
public Name Name { get; init; }
public Category Category { get; init; }
public DateTime Birthdate { get; init; }
public JudgeUniqueId UniqueId { get; init; }
public JudgeUpdatedEvent(DateTime birthdate,
Category category, JudgeUniqueId uniqueId,
Login login, Password password, Name name,
int version) :
base(version)
{
Birthdate = birthdate;
Category = category;
UniqueId = uniqueId;
Login = login;
Name = name;
Password = password;
Key = this.UniqueId.GetAggregateKey();
Version = version;
}
public JudgeUpdatedEvent()
{
}
}
public class CallForSpeechSubmitedEvent : DomainEvent
{
public Speaker Speaker { get; init; }
public Speech Speech { get; init; }
public Registration Registration { get; init; }
public CallForSpeechNumber Number { get; init; }
public Category Category { get; init; }
public CallForSpeechStatus Status { get; init; }
public CallForSpeechScoringResult Score { get; init; }
public Decision PreliminaryDecision { get; init; }
public Decision FinalDecision { get; init; }
public CallForSpeechUniqueId UniqueId { get; init; }
public CallForSpeechSubmitedEvent(Speaker speaker, Speech speech,
Registration registration, CallForSpeechNumber number, Category category,
CallForSpeechStatus status, CallForSpeechScoringResult score,
Decision preliminaryDecision, Decision finalDecision, CallForSpeechUniqueId uniqueId,
int version)
: base(version)
{
Speaker = speaker;
Speech = speech;
Registration = registration;
Number = number;
Category = category;
Status = status;
Score = score;
PreliminaryDecision = preliminaryDecision;
FinalDecision = finalDecision;
UniqueId = uniqueId;
this.Key = UniqueId.GetAggregateKey();
}
public CallForSpeechSubmitedEvent()
{
}
}
public class CallForSpeechRejectedEvent : DomainEvent
{
public Speaker Speaker { get; init; }
public Speech Speech { get; init; }
public Registration Registration { get; init; }
public CallForSpeechNumber Number { get; init; }
public Category Category { get; init; }
public CallForSpeechStatus Status { get; init; }
public CallForSpeechScoringResult Score { get; init; }
public Decision PreliminaryDecision { get; init; }
public Decision FinalDecision { get; init; }
public CallForSpeechUniqueId UniqueId { get; init; }
public CallForSpeechRejectedEvent(Speaker speaker, Speech speech,
Registration registration, CallForSpeechNumber number, Category category,
CallForSpeechStatus status, CallForSpeechScoringResult score,
Decision preliminaryDecision, Decision finalDecision, CallForSpeechUniqueId uniqueId,
int version)
: base(version)
{
Speaker = speaker;
Speech = speech;
Registration = registration;
Number = number;
Category = category;
Status = status;
Score = score;
PreliminaryDecision = preliminaryDecision;
FinalDecision = finalDecision;
UniqueId = uniqueId;
this.Key = UniqueId.GetAggregateKey();
}
//public CallForSpeechRejectedEvent()
//{
//}
public abstract class AggregateRoot
{
private readonly List<DomainEvent> _changes = new List<DomainEvent>();
public AggregateKey Key { get; protected set; }
public int Version { get; protected set; }
public override string ToString()
{
return Key.Id + Key.Type;
}
public IEnumerable<DomainEvent> GetUncommittedChanges()
{
lock (_changes)
{
return _changes.ToArray();
}
}
public void MarkChangesAsCommitted()
{
lock (_changes)
{
Version = Version + _changes.Count;
_changes.Clear();
}
}
public void LoadFromHistory(IEnumerable<DomainEvent> history)
{
foreach (var e in history)
{
//if (e.Version != Version + 1)
// throw new EventsOutOfOrderException(e.Key);
ApplyChange(e, false);
}
}F
protected void ApplyChange(DomainEvent @event)
{
ApplyChange(@event, true);
}
private void ApplyChange(DomainEvent @event, bool isNew)
{
lock (_changes)
{
this.AsDynamic().Apply(@event);
if (isNew)
{
_changes.Add(@event);
}
else
{
Key = @event.Key;
//Version++;
}
}
}
}
internal static class PrivateReflectionDynamicObjectExtensions
{
public static dynamic AsDynamic(this object o)
{
return PrivateReflectionDynamicObject.WrapObjectIfNeeded(o);
}
}
internal class PrivateReflectionDynamicObject : DynamicObject
{
public object RealObject { get; set; }
private const BindingFlags bindingFlags =
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
internal static object WrapObjectIfNeeded(object o)
{
// Don't wrap primitive types, which don't have many interesting internal APIs
if (o == null || o.GetType().IsPrimitive || o is string)
return o;
return new PrivateReflectionDynamicObject() { RealObject = o };
}
// Called when a method is called
public override bool TryInvokeMember
(InvokeMemberBinder binder, object[] args, out object result)
{
result = InvokeMemberOnType(RealObject.GetType(), RealObject, binder.Name, args);
// Wrap the sub object if necessary. This allows nested anonymous objects to work.
result = WrapObjectIfNeeded(result);
return true;
}
private static object InvokeMemberOnType
(Type type, object target, string name, object[] args)
{
try
{
// Try to incoke the method
return type.InvokeMember(
name,
BindingFlags.InvokeMethod | bindingFlags,
null,
target,
args);
}
catch (MissingMethodException)
{
// If we couldn't find the method, try on the base class
if (type.BaseType != null)
{
return InvokeMemberOnType(type.BaseType, target, name, args);
}
//Don't care if the method don't exist.
return null;
}
}
}
private void ApplyChange(DomainEvent @event, bool isNew)
{
lock (_changes)
{
this.AsDynamic().Apply(@event);
if (isNew)
{
_changes.Add(@event);
}
else
{
Key = @event.Key;
Version++;
}
}
}
public class CategoryAggregate : AggregateRoot
{
public string Name { get; private set; }
public string DisplayName { get; private set; }
public string WhatWeAreLookingFor { get; private set; }
public CategoryUniqueId UniqueId { get; private set; }
private void Apply(CategoryCreateEvent e)
{
Version = e.Version;
Name = e.Name;
DisplayName = e.DisplayName;
UniqueId = e.UniqueId;
WhatWeAreLookingFor = e.WhatWeAreLookingFor;
this.Key = e.UniqueId.GetAggregateKey();
}
private void Apply(CategoryUpdateEvent e)
{
Version = e.Version++;
Name = e.Name;
DisplayName = e.DisplayName;
UniqueId = e.UniqueId;
WhatWeAreLookingFor = e.WhatWeAreLookingFor;
this.Key = e.UniqueId.GetAggregateKey();
}
public CategoryAggregate(Category cc)
{
var c = new CategoryCreateEvent(cc.UniqueId, cc.Name,
cc.DisplayName, cc.WhatWeAreLookingFor,
cc.Version);
ApplyChange(c);
}
public CategoryAggregate()
{
}
public void Update(Category cc)
{
var c = new CategoryUpdateEvent(cc.UniqueId, cc.Name,
cc.DisplayName, cc.WhatWeAreLookingFor,
cc.Version);
ApplyChange(c);
}
}
private void ApplyChange(DomainEvent @event, bool isNew)
{
lock (_changes)
{
this.AsDynamic().Apply(@event);
if (isNew)
{
_changes.Add(@event);
}
else
{
Key = @event.Key;
Version++;
}
}
}
public static class AggregateFactory
{
public static T CreateAggregate<T>()
{
try
{
return (T)Activator.CreateInstance(typeof(T), true);
}
catch (MissingMethodException)
{
throw new MissingParameterLessConstructorException(typeof(T));
}
}
}
public class JudgeAggregate : AggregateRoot
{
public Login Login { get; private set; }
public Password Password { get; private set; }
public Name Name { get; private set; }
public Category Category { get; private set; }
public DateTime Birthdate { get; private set; }
public JudgeUniqueId UniqueId { get; private set; }
private void Apply(JudgeCreatedEvent e)
{
Version = e.Version;
Login = e.Login;
Password = e.Password;
Category = e.Category;
Birthdate = e.Birthdate;
UniqueId = e.UniqueId;
Key = e.Key;
}
private void Apply(JudgeUpdatedEvent e)
{
Version = e.Version++;
Login = e.Login;
Password = e.Password;
Category = e.Category;
Birthdate = e.Birthdate;
UniqueId = e.UniqueId;
Key = e.Key;
}
private void Apply(JudgeDeletedEvent e)
{
Version = e.Version++;
UniqueId = e.UniqueId;
Key = e.Key;
}
public JudgeAggregate()
{
}
public JudgeAggregate(Judge j)
{
var c = new JudgeCreatedEvent(j.Birthdate,
j.Category, j.UniqueId,
j.Login,
j.Password,
j.Name, j.Version);
ApplyChange(c);
}
public void Update(Judge j)
{
var c = new JudgeUpdatedEvent(Birthdate,
Category, UniqueId,
Login,
Password,
Name, Version);
c.Key = c.UniqueId.GetAggregateKey();
ApplyChange(c);
}
public void Delete(JudgeUniqueId id, int version)
{
var eve = new
JudgeDeletedEvent(version)
{ UniqueId = id };
eve.Key = eve.UniqueId.GetAggregateKey();
ApplyChange(eve);
}
}
public class CallForSpeechAggregate : AggregateRoot
{
public Speaker Speaker { get; set; }
public Speech Speech { get; set; }
public Registration Registration { get; set; }
public CallForSpeechNumber Number { get; set; }
public Category Category { get; set; }
public CallForSpeechStatus Status { get; set; }
public CallForSpeechScoringResult Score { get; set; }
public CallForSpeechUniqueId UniqueId { get; set; }
public Decision PreliminaryDecision { get; set; }
public Decision FinalDecision { get; set; }
private void Apply(CallForSpeechSubmitedEvent e)
{
Speaker = e.Speaker;
Speech = e.Speech;
Registration = e.Registration;
Number = e.Number;
Category = e.Category;
Status = e.Status;
PreliminaryDecision = e.PreliminaryDecision;
FinalDecision = e.FinalDecision;
UniqueId = e.UniqueId;
Version = e.Version++;
this.Key = e.UniqueId.GetAggregateKey();
}
private void Apply(CallForSpeechRejectedEvent e)
{
Speaker = e.Speaker;
Speech = e.Speech;
Registration = e.Registration;
Number = e.Number;
Category = e.Category;
Status = e.Status;
PreliminaryDecision = e.PreliminaryDecision;
FinalDecision = e.FinalDecision;
UniqueId = e.UniqueId;
Version = e.Version++;
this.Key = e.UniqueId.GetAggregateKey();
}
private void Apply(CallForSpeechPreliminaryAcceptEvent e)
{
Speaker = e.Speaker;
Speech = e.Speech;
Registration = e.Registration;
Number = e.Number;
Category = e.Category;
Status = e.Status;
PreliminaryDecision = e.PreliminaryDecision;
FinalDecision = e.FinalDecision;
UniqueId = e.UniqueId;
Version = e.Version++;
this.Key = e.UniqueId.GetAggregateKey();
}
private void Apply(CallForSpeechAcceptedEvent e)
{
Speaker = e.Speaker;
Speech = e.Speech;
Registration = e.Registration;
Number = e.Number;
Category = e.Category;
Status = e.Status;
PreliminaryDecision = e.PreliminaryDecision;
FinalDecision = e.FinalDecision;
UniqueId = e.UniqueId;
Version = e.Version++;
this.Key = e.UniqueId.GetAggregateKey();
}
private void Apply(CallForSpeechEvaulatedEvent e)
{
Speaker = e.Speaker;
Speech = e.Speech;
Registration = e.Registration;
Number = e.Number;
Category = e.Category;
Status = e.Status;
PreliminaryDecision = e.PreliminaryDecision;
FinalDecision = e.FinalDecision;
UniqueId = e.UniqueId;
Version = e.Version++;
this.Key = e.UniqueId.GetAggregateKey();
}
public CallForSpeechAggregate(CallForSpeech cc)
{
var c = new CallForSpeechSubmitedEvent
(cc.Speaker, cc.Speech, cc.Registration,
cc.Number, cc.Category, cc.Status, cc.Score,
cc.PreliminaryDecision, cc.FinalDecision,
cc.UniqueId, cc.Version);
this.Key = c.UniqueId.GetAggregateKey();
ApplyChange(c);
}
public void Rejected(CallForSpeech cc)
{
var c = new CallForSpeechRejectedEvent
(cc.Speaker, cc.Speech, cc.Registration,
cc.Number, cc.Category, cc.Status, cc.Score,
cc.PreliminaryDecision, cc.FinalDecision,
cc.UniqueId, cc.Version);
this.Key = c.UniqueId.GetAggregateKey();
ApplyChange(c);
}
public void PreliminaryAccepted(CallForSpeech cc)
{
var c = new CallForSpeechPreliminaryAcceptEvent
(cc.Speaker, cc.Speech, cc.Registration,
cc.Number, cc.Category, cc.Status, cc.Score,
cc.PreliminaryDecision, cc.FinalDecision,
cc.UniqueId, cc.Version);
this.Key = c.UniqueId.GetAggregateKey();
ApplyChange(c);
}
public void Evaulated(CallForSpeech cc)
{
var c = new CallForSpeechEvaulatedEvent
(cc.Speaker, cc.Speech, cc.Registration,
cc.Number, cc.Category, cc.Status, cc.Score,
cc.PreliminaryDecision, cc.FinalDecision,
cc.UniqueId, cc.Version);
this.Key = c.UniqueId.GetAggregateKey();
ApplyChange(c);
}
public void Accepted(CallForSpeech cc)
{
var c = new CallForSpeechAcceptedEvent
(cc.Speaker, cc.Speech, cc.Registration,
cc.Number, cc.Category, cc.Status, cc.Score,
cc.PreliminaryDecision, cc.FinalDecision,
cc.UniqueId, cc.Version);
this.Key = c.UniqueId.GetAggregateKey();
ApplyChange(c);
}
public CallForSpeechAggregate()
{
}
}
public interface ISessionForEventSourcing
{
ExecutionStatus Add<T>(T aggregate)
where T : AggregateRoot;
ExecutionStatus<T> Get<T>
(AggregateKey id, int? expectedVersion = null)
where T : AggregateRoot;
ExecutionStatus Commit();
}
public interface IEventRepository
{
void Save<T>
(T aggregate, int? expectedVersion = null)
where T : AggregateRoot;
T Get<T>
(AggregateKey aggregateId)
where T : AggregateRoot;
}
public interface IEventStore
{
void Save(DomainEvent @event);
List<DomainEvent> Get
(AggregateKey aggregateId, int fromVersion);
}
public interface IEventPublisher
{
void Publish<T>(T @event) where T : DomainEvent;
}
public class AggregateNotFoundException : System.Exception
{
public AggregateNotFoundException(AggregateKey id)
: base
(string.Format
("Aggregate {0} was not found", id))
{
}
}
public class AggregateOrEventMissingIdException : System.Exception
{
public AggregateOrEventMissingIdException(Type aggregateType, Type eventType)
: base(
string.Format
("An event of type {0} was tried to save from {1} but no id where set on either"
, eventType.FullName, aggregateType.FullName))
{
}
}
public class ConcurrencyException : System.Exception
{
public ConcurrencyException(AggregateKey id)
:
base
(string.Format
("A different version than expected was found in aggregate {0}"
, id))
{
}
}
public class EventsOutOfOrderException : System.Exception
{
public EventsOutOfOrderException(AggregateKey id)
:
base
(string.Format
("Eventstore gave event for aggregate {0} out of order"
, id))
{
}
}
public class MissingParameterLessConstructorException : System.Exception
{
public MissingParameterLessConstructorException(Type type)
:
base
(string.Format
("{0} has no constructor without paramerters. This can be either public or private"
, type.FullName))
{
}
}
public class SessionForEventSourcing : ISessionForEventSourcing
{
private readonly IEventRepository _repository;
private readonly Dictionary<AggregateKey,
AggregateDescriptor> _trackedAggregates;
public SessionForEventSourcing(IEventRepository repository)
{
if (repository == null)
throw new ArgumentNullException("repository");
_repository = repository;
_trackedAggregates = new Dictionary<AggregateKey, AggregateDescriptor>();
}
public ExecutionStatus Add<T>(T aggregate) where T : AggregateRoot
{
try
{
if (!IsTracked(aggregate.Key))
_trackedAggregates.Add(aggregate.Key,
new AggregateDescriptor
{
Aggregate = aggregate,
Version = aggregate.Version
});
else if (_trackedAggregates[aggregate.Key].Aggregate != aggregate)
throw new ConcurrencyException(aggregate.Key);
}
catch (Exception ex)
{
if (ExecutionFlow.Options.ThrowExceptions)
throw;
return ExecutionStatus.EventStoreError(ex);
}
return ExecutionStatus.EventStoreOk();
}
public ExecutionStatus<T> Get<T>(AggregateKey id, int? expectedVersion = null) where T : AggregateRoot
{
try
{
//w pamięci sprawdzamy czy nie próbujemy ze złą wersją dodać zdarzenie
if (IsTracked(id))
{
var trackedAggregate = (T)_trackedAggregates[id].Aggregate;
if (expectedVersion != null && trackedAggregate.Version != expectedVersion)
throw new ConcurrencyException(trackedAggregate.Key);
return ExecutionStatus<T>.EventStoreOk(trackedAggregate);
}
//jeśli nie mamy w pamieci to odpytujemy repozytorium
var aggregate = _repository.Get<T>(id);
if (expectedVersion != null && aggregate.Version != expectedVersion)
throw new ConcurrencyException(id);
Add(aggregate); //dodaj do tej warstwy pamięci
return ExecutionStatus<T>.EventStoreOk(aggregate);
}
catch (Exception ex)
{
if (ExecutionFlow.Options.ThrowExceptions)
throw;
return ExecutionStatus<T>.EventStoreError(ex);
}
}
private bool IsTracked(AggregateKey id)
{
return _trackedAggregates.ContainsKey(id);
}
public ExecutionStatus Commit()
{
try
{
foreach (var descriptor in _trackedAggregates.Values)
{
_repository.Save(descriptor.Aggregate, descriptor.Version);
}
_trackedAggregates.Clear();
}
catch (Exception ex)
{
if (ExecutionFlow.Options.ThrowExceptions)
throw;
return ExecutionStatus.EventStoreError(ex);
}
return ExecutionStatus.EventStoreOk();
}
private class AggregateDescriptor
{
public AggregateRoot Aggregate { get; set; }
public int Version { get; set; }
}
}
public class EventRepository : IEventRepository
{
private readonly IEventStore _eventStore;
private readonly IEventPublisher _publisher;
public EventRepository(IEventStore eventStore, IEventPublisher publisher)
{
if (eventStore == null)
throw new ArgumentNullException("eventStore");
if (publisher == null)
throw new ArgumentNullException("publisher");
_eventStore = eventStore;
_publisher = publisher;
}
public void Save<T>(T aggregate, int? expectedVersion = null) where T : AggregateRoot
{
if (expectedVersion != null && _eventStore.Get(
aggregate.Key, expectedVersion.Value).Any())
throw new ConcurrencyException(aggregate.Key);
var i = 0;
foreach (var @event in aggregate.GetUncommittedChanges())
{
if (@event.Key == AggregateKey.Empty)
@event.Key = aggregate.Key;
if (@event.Key == AggregateKey.Empty)
throw new AggregateOrEventMissingIdException(
aggregate.GetType(), @event.GetType());
i++;
@event.Version = aggregate.Version + i;
@event.TimeStamp = DateTimeOffset.UtcNow;
_eventStore.Save(@event);
_publisher.Publish(@event);
}
aggregate.MarkChangesAsCommitted();
}
public T Get<T>(AggregateKey aggregateId) where T : AggregateRoot
{
return LoadAggregate<T>(aggregateId);
}
private T LoadAggregate<T>(AggregateKey id) where T : AggregateRoot
{
var aggregate = GeekLemonConference.Application.EventSourcing.AggregateFactory.CreateAggregate<T>();
//#ToFix
var events = _eventStore.Get(id, -1);
if (!events.Any())
throw new AggregateNotFoundException(id);
aggregate.LoadFromHistory(events);
return aggregate;
}
}
public class Constants
{
public const string QUEUE_JUDGE_CREATED = "judge_created";
public const string QUEUE_JUDGE_UPDATED = "judge_updated";
public const string QUEUE_JUDGE_DELETED = "judge_deleted";
public const string QUEUE_CATEGORY_CREATED = "category_created";
public const string QUEUE_CATEGORY_UPDATED = "category_updated";
public const string QUEUE_CALLFORSPEECH_SUBMITC = "callforspeech_submit";
public const string QUEUE_CALLFORSPEECH_REJECTC = "callforspeech_reject";
public const string QUEUE_CALLFORSPEECH_PRELIMINARY_ACCEPT = "callforspeech_preminal_accept";
public const string QUEUE_CALLFORSPEECH_EVALUATE = "callforspeech_evaluate";
public const string QUEUE_CALLFORSPEECH_ACCEPT = "callforspeech_accept";
}
public static class DomainEventHelper
{
public static string WhatRabbitMQQueue(this DomainEvent @event)
{
string g = @event switch
{
JudgeUpdatedEvent => Constants.QUEUE_JUDGE_UPDATED,
JudgeCreatedEvent => Constants.QUEUE_JUDGE_CREATED,
JudgeDeletedEvent => Constants.QUEUE_JUDGE_DELETED,
CategoryCreateEvent => Constants.QUEUE_CATEGORY_CREATED,
CategoryUpdateEvent => Constants.QUEUE_CATEGORY_UPDATED,
CallForSpeechAcceptedEvent => Constants.QUEUE_CALLFORSPEECH_ACCEPT,
CallForSpeechEvaulatedEvent => Constants.QUEUE_CALLFORSPEECH_EVALUATE,
CallForSpeechPreliminaryAcceptEvent
=> Constants.QUEUE_CALLFORSPEECH_PRELIMINARY_ACCEPT,
CallForSpeechRejectedEvent => Constants.QUEUE_CALLFORSPEECH_REJECTC,
CallForSpeechSubmitedEvent => Constants.QUEUE_CALLFORSPEECH_SUBMITC,
_ => throw new NotImplementedException(),
};
return g;
}
}
public class GeekLemonEventPublisher : IEventPublisher
{
private readonly ConnectionFactory connectionFactory;
public GeekLemonEventPublisher(IHostingEnvironment env)
{
connectionFactory = new ConnectionFactory();
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)
.AddEnvironmentVariables();
builder.Build().GetSection("RabbitMqSetting").Bind(connectionFactory);
}
public void Publish<T>(T @event) where T : DomainEvent
{
using (IConnection conn = connectionFactory.CreateConnection())
{
using (IModel channel = conn.CreateModel())
{
var queue = @event.WhatRabbitMQQueue();
channel.QueueDeclare(
queue: queue,
durable: false,
exclusive: false,
autoDelete: false,
arguments: null
);
var body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(@event));
channel.BasicPublish(
exchange: "",
routingKey: queue,
basicProperties: null,
body: body
);
}
}
}
}
public class InMemoryEventStore : IEventStore
{
private readonly Dictionary<AggregateKey, List<DomainEvent>>
customerInMemDictionary =
new Dictionary<AggregateKey, List<DomainEvent>>();
public List<DomainEvent> Get(AggregateKey aggregateId, int fromVersion)
{
List<DomainEvent> geekLemonEvents;
customerInMemDictionary.TryGetValue(aggregateId, out geekLemonEvents);
if (geekLemonEvents != null)
{
return geekLemonEvents.Where(x => x.Version > fromVersion).ToList();
}
return new List<DomainEvent>();
}
public void Save(DomainEvent @event)
{
List<DomainEvent> geekLemonEvents;
customerInMemDictionary.TryGetValue(@event.Key, out geekLemonEvents);
if (geekLemonEvents == null)
{
geekLemonEvents = new List<DomainEvent>();
customerInMemDictionary.Add(@event.Key, geekLemonEvents);
}
geekLemonEvents.Add(@event);
}
}
public static partial class GeekLemonConferenceInstallers
{
public static IServiceCollection
AddDefaultEventStore(this IServiceCollection services)
{
services.AddScoped<IEventStore, InMemoryEventStore>();
return services;
}
public static IServiceCollection AddBusAndRepository
(this IServiceCollection services,
IConfiguration configuration)
{
services.AddOptions();
//AddOption<RabbitMqConfiguration>(services, configuration);
services.AddScoped<ISessionForEventSourcing, SessionForEventSourcing>();
services.AddSingleton<IEventPublisher, GeekLemonEventPublisher>();
services.AddScoped<IEventRepository, EventRepository>();
//services.AddScoped<IEventRepository, CacheRepository>((services) =>
//{
// var iEventStore = services.GetRequiredService<IEventStore>();
// var iEventPublisher = services.GetRequiredService<IEventPublisher>();
// var eventRepository = new EventRepository(iEventStore, iEventPublisher);
// return new CacheRepository(eventRepository, iEventStore);
//});
return services;
}
private static void AddOption<T>(IServiceCollection services, IConfiguration configuration) where T : class
{
services.Configure<T>(configuration.GetSection(typeof(T).Name));
}
}
public class CacheRepository : IEventRepository
{
private readonly IEventRepository _repository;
private readonly IEventStore _eventStore;
private readonly MemoryCache _cache;
private readonly Func<CacheItemPolicy> _policyFactory;
private static readonly ConcurrentDictionary<string, object> _locks =
new ConcurrentDictionary<string, object>();
public CacheRepository(IEventRepository repository, IEventStore eventStore)
{
if (repository == null)
throw new ArgumentNullException("repository");
if (eventStore == null)
throw new ArgumentNullException("eventStore");
_repository = repository;
_eventStore = eventStore;
_cache = MemoryCache.Default;
_policyFactory = () => new CacheItemPolicy
{
SlidingExpiration = new TimeSpan(0, 0, 15, 0),
RemovedCallback = x =>
{
object o;
_locks.TryRemove(x.CacheItem.Key, out o);
}
};
}
public void Save<T>(T aggregate, int? expectedVersion = null)
where T : AggregateRoot
{
var idstring = aggregate.Key.ToString();
try
{
lock (_locks.GetOrAdd(idstring, _ => new object()))
{
if (aggregate.Key != AggregateKey.Empty && !IsTracked(aggregate.Key))
_cache.Add(idstring, aggregate, _policyFactory.Invoke());
_repository.Save(aggregate, expectedVersion);
}
}
catch (Exception)
{
_cache.Remove(idstring);
throw;
}
}
public T Get<T>(AggregateKey aggregateId) where T : AggregateRoot
{
var idstring = aggregateId.ToString();
try
{
lock (_locks.GetOrAdd(idstring, _ => new object()))
{
T aggregate;
if (IsTracked(aggregateId))
{
aggregate = (T)_cache.Get(idstring);
var events = _eventStore.Get(aggregateId, aggregate.Version);
if (events.Any() && events.First().Version != aggregate.Version + 1)
{
_cache.Remove(idstring);
}
else
{
aggregate.LoadFromHistory(events);
return aggregate;
}
}
//jeśli nie ma go w Cache to poszukać w repozytorium prawdziwym
aggregate = _repository.Get<T>(aggregateId);
_cache.Add(
aggregateId.ToString(),
aggregate,
_policyFactory.Invoke());
return aggregate;
}
}
catch (Exception)
{
_cache.Remove(idstring);
throw;
}
}
private bool IsTracked(AggregateKey id)
{
return _cache.Contains(id.ToString());
}
}
public class EventData
{
public const string IdFieldName = "_id";
public const string StreamIdFieldName = "_streamId";
public const string VersionFieldName = "_version";
[BsonElement(IdFieldName)]
[BsonId(IdGenerator = typeof(GuidGenerator))]
public Guid Id { get; set; }
[BsonElement(StreamIdFieldName)]
public string StreamId { get; set; }
[BsonElement(VersionFieldName)]
public int Version { get; set; }
[BsonElement("_payload")]
public DomainEvent PayLoad { get; set; }
[BsonElement("_timestamp")]
public DateTimeOffset TimeStamp { get; set; }
[BsonElement("_clrTypeFullname")]
public string AssemblyQualifiedName { get; set; }
}
public interface IMongoDbContext
{
IMongoDatabase Database { get; }
IClientSessionHandle Session { get; }
IClientSessionHandle StartSession
();
}
public class MongoDbContext : IMongoDbContext
{
public IMongoDatabase Database { get; }
public IClientSessionHandle Session { get; private set; }
private MongoClient _client;
public MongoDbContext()
{
string connectionString = "mongodb://localhost:27017/dbtest?readPreference=primary";
var mongoUrl = new MongoUrl(connectionString);
_client = new MongoClient(mongoUrl);
Database = _client.GetDatabase("GeekLemon");
ClassMapping();
}
private static void ClassMapping()
{
if (!BsonClassMap.IsClassMapRegistered
(typeof(CategoryUpdateEvent)))
{ BsonClassMap.RegisterClassMap<CategoryUpdateEvent>(); }
if (!BsonClassMap.IsClassMapRegistered
(typeof(CategoryCreateEvent)))
{ BsonClassMap.RegisterClassMap<CategoryCreateEvent>(); }
if (!BsonClassMap.IsClassMapRegistered
(typeof(JudgeCreatedEvent)))
{ BsonClassMap.RegisterClassMap<JudgeCreatedEvent>(); }
if (!BsonClassMap.IsClassMapRegistered
(typeof(JudgeUpdatedEvent)))
{ BsonClassMap.RegisterClassMap<JudgeUpdatedEvent>(); }
if (!BsonClassMap.IsClassMapRegistered
(typeof(JudgeDeletedEvent)))
{ BsonClassMap.RegisterClassMap<JudgeDeletedEvent>(); }
if (!BsonClassMap.IsClassMapRegistered
(typeof(CallForSpeechAcceptedEvent)))
{ BsonClassMap.RegisterClassMap<CallForSpeechAcceptedEvent>(); }
if (!BsonClassMap.IsClassMapRegistered
(typeof(CallForSpeechPreliminaryAcceptEvent)))
{ BsonClassMap.RegisterClassMap<CallForSpeechPreliminaryAcceptEvent>(); }
if (!BsonClassMap.IsClassMapRegistered
(typeof(CallForSpeechRejectedEvent)))
{ BsonClassMap.RegisterClassMap<CallForSpeechRejectedEvent>(); }
if (!BsonClassMap.IsClassMapRegistered
(typeof(CallForSpeechEvaulatedEvent)))
{ BsonClassMap.RegisterClassMap<CallForSpeechEvaulatedEvent>(); }
if (!BsonClassMap.IsClassMapRegistered
(typeof(CallForSpeechSubmitedEvent)))
{ BsonClassMap.RegisterClassMap<CallForSpeechSubmitedEvent>(); }
}
public IClientSessionHandle StartSession()
{
var session = _client.StartSession();
Session = session;
return session;
}
}
public class MongoDbEventStore : IEventStore
{
private IMongoCollection<EventData> _events;
private const string EventsCollection = "eventstore";
private readonly IMongoDbContext _mongoDbContext;
public MongoDbEventStore(IEventPublisher publisher, IMongoDbContext mongoDbContext)
{
_mongoDbContext = mongoDbContext;
_events = _mongoDbContext.Database.GetCollection<EventData>(EventsCollection);
}
public List<DomainEvent> Get
(Application.EventSourcing.AggregateKey aggregateId, int fromVersion)
{
try
{
var filterBuilder = Builders<EventData>.Filter;
var filter = filterBuilder.Eq(EventData.StreamIdFieldName, aggregateId) &
filterBuilder.Gte(EventData.VersionFieldName, fromVersion);
var result = _events.Find(filter);
var r = result.ToList().Select(x => x.PayLoad).ToList();
return r;
}
catch (Exception)
{
throw;
}
}
public void Save(DomainEvent @event)
{
using var session = _mongoDbContext.StartSession();
try
{
//You can do atomic mass add
//but i have community version
var eventData = new EventData
{
Id = Guid.NewGuid(),
StreamId = @event.Key.Id,
TimeStamp = @event.TimeStamp,
AssemblyQualifiedName = @event.GetType().AssemblyQualifiedName,
PayLoad = @event,
Version = @event.Version
};
_events.InsertOne(eventData);
}
catch (Exception exp)
{
//session.AbortTransaction();
throw;
}
}
}
public static partial class GeekLemonConferenceInstallers
{
public static IServiceCollection
AddEventStoreMongoDb
(this IServiceCollection services,
IConfiguration configuration)
{
services.AddScoped<IMongoDbContext, MongoDbContext>();
services.AddScoped<IEventStore, MongoDbEventStore>();
return services;
}
}
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "EventStore" (
"Id" INTEGER NOT NULL UNIQUE,
"Key" TEXT NOT NULL,
"AssemblyQualifiedName" TEXT NOT NULL,
"Value" TEXT NOT NULL,
"Version" INTEGER,
PRIMARY KEY("Id" AUTOINCREMENT)
);
COMMIT;
public interface IEventStoreSQLiteContext
{
string ConnectionString { get; }
}
public class EventStoreSQLiteContext : IEventStoreSQLiteContext
{
public EventStoreSQLiteContext(string connectionString)
{
_connectionString = connectionString;
}
private string _connectionString;
public string ConnectionString
{
get
{
return _connectionString;
}
}
}
public class SqlLiteEventStore : IEventStore
{
private IEventStoreSQLiteContext _geekLemonContext;
public SqlLiteEventStore(IEventStoreSQLiteContext context)
{
_geekLemonContext = context;
}
public List<DomainEvent> Get(AggregateKey aggregateId, int fromVersion)
{
using var connection = new SqliteConnection
(_geekLemonContext.ConnectionString);
try
{
var r = connection.Query<EventTemp>
(@"SELECT Id,Key, Value, AssemblyQualifiedName, Version FROM EventSTORE
WHERE Key = @aggregateId and Version > @Version;", new
{
@aggregateId = aggregateId.Id,
@Version = fromVersion
});
List<DomainEvent> de = new List<DomainEvent>();
foreach (var item in r)
{
Assembly asm = typeof(DomainEvent).Assembly;
Type type = TypeRecon.ReconstructType(item.AssemblyQualifiedName, true, asm);
var domain = JsonConvert.
DeserializeObject(item.Value, type);
de.Add(domain as DomainEvent);
}
return de;
}
catch (Exception ex)
{
throw;
}
}
public void Save(DomainEvent @event)
{
using var connection = new SqliteConnection
(_geekLemonContext.ConnectionString);
try
{
var q = @"INSERT INTO EventSTORE(Key, Value,
AssemblyQualifiedName
,Version)
VALUES (@Key, @Value, @AssemblyQualifiedName,@Version);";
var result = connection.Execute(q, new
{
@Key = @event.Key.Id,
@Value = JsonConvert.SerializeObject(@event),
@AssemblyQualifiedName = @event.GetType().AssemblyQualifiedName,
@Version = @event.Version,
}
);
}
catch (Exception ex)
{
throw;
}
}
}
public class EventTemp
{
public string Key { get; set; }
public string Value { get; set; }
public string AssemblyQualifiedName { get; set; }
}
public static class TypeRecon
{
public static Type ReconstructType(string assemblyQualifiedName,
bool throwOnError = true, params Assembly[] referencedAssemblies)
{
foreach (Assembly asm in referencedAssemblies)
{
var fullNameWithoutAssemblyName = assemblyQualifiedName.Replace($", {asm.FullName}", "");
var type = asm.GetType(fullNameWithoutAssemblyName, throwOnError: false);
if (type != null) return type;
}
if (assemblyQualifiedName.Contains("[["))
{
Type type = ConstructGenericType(assemblyQualifiedName, throwOnError);
if (type != null)
return type;
}
else
{
Type type = Type.GetType(assemblyQualifiedName, false);
if (type != null)
return type;
}
if (throwOnError)
throw new Exception
($"The type \"{assemblyQualifiedName}\" cannot be found in referenced assemblies.");
else
return null;
}
private static Type ConstructGenericType(string assemblyQualifiedName, bool throwOnError = true)
{
Regex regex = new Regex
(@"^(?<name>\w+(\.\w+)*)`(?<count>\d)\[(?<subtypes>\[.*\])\](, (?<assembly>\w+(\.\w+)*)[\w\s,=\.]+)$?",
RegexOptions.Singleline | RegexOptions.ExplicitCapture);
Match match = regex.Match(assemblyQualifiedName);
if (!match.Success)
if (!throwOnError) return null;
else throw new Exception($"Unable to parse the type's assembly qualified name: {assemblyQualifiedName}");
string typeName = match.Groups["name"].Value;
int n = int.Parse(match.Groups["count"].Value);
string asmName = match.Groups["assembly"].Value;
string subtypes = match.Groups["subtypes"].Value;
typeName = typeName + $"`{n}";
Type genericType = ReconstructType(typeName, throwOnError);
if (genericType == null) return null;
List<string> typeNames = new List<string>();
int ofs = 0;
while (ofs < subtypes.Length && subtypes[ofs] == '[')
{
int end = ofs, level = 0;
do
{
switch (subtypes[end++])
{
case '[': level++; break;
case ']': level--; break;
}
} while (level > 0 && end < subtypes.Length);
if (level == 0)
{
typeNames.Add(subtypes.Substring(ofs + 1, end - ofs - 2));
if (end < subtypes.Length && subtypes[end] == ',')
end++;
}
ofs = end;
n--; // just for checking the count
}
if (n != 0)
// This shouldn't ever happen!
throw new Exception("Generic type argument count mismatch! Type name: " + assemblyQualifiedName);
Type[] types = new Type[typeNames.Count];
for (int i = 0; i < types.Length; i++)
{
try
{
types[i] = ReconstructType(typeNames[i], throwOnError);
if (types[i] == null) // if throwOnError, should not reach this point if couldn't create the type
return null;
}
catch (Exception ex)
{
throw new Exception($"Unable to reconstruct generic type. Failed on creating the type argument {(i + 1)}: {typeNames[i]}. Error message: {ex.Message}");
}
}
Type resultType = genericType.MakeGenericType(types);
return resultType;
}
}
public static partial class GeekLemonConferenceInstallers
{
public static IServiceCollection
AddEventStoreSqlLite
(this IServiceCollection services,
IConfiguration configuration)
{
var connection = configuration.
GetConnectionString("EventStoreSQLiteConnectionString");
services.AddScoped<IEventStoreSQLiteContext, EventStoreSQLiteContext>
(
(services) =>
{
var c =
new EventStoreSQLiteContext(connection);
return c;
}
);
services.AddScoped<IEventStore, SqlLiteEventStore>();
return services;
}
}
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddSwaggerGen(c => .........
services.AddGeekLemonConferenceCQRS(Configuration);
services.AddGeekLemonPersistenceDapperSQLiteServices(Configuration);
//services.AddDefaultEventStore();
//services.AddEventStoreSqlLite(Configuration);
services.AddEventStoreMongoDb(Configuration);
services.AddBusAndRepository(Configuration);
services.AddControllers();
services.AddCors(options =>
{
options.AddPolicy("Open",
builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
});
}
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddSwaggerGen(c => .........
services.AddGeekLemonConferenceCQRS(Configuration);
services.AddGeekLemonPersistenceDapperSQLiteServices(Configuration);
//services.AddDefaultEventStore();
services.AddEventStoreSqlLite(Configuration);
//services.AddEventStoreMongoDb(Configuration);
services.AddBusAndRepository(Configuration);
services.AddControllers();
services.AddCors(options =>
{
options.AddPolicy("Open",
builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
});
}
public class ESCreateCategoryCommand :
IRequest<ESCreateCategoryCommandResponse>
{
public string Name { get; set; }
public string DisplayName { get; set; }
public string WhatWeAreLookingFor { get; set; }
internal int Version { get; private set; }
internal CategoryUniqueId UniqueId { get; private set; }
public ESCreateCategoryCommand()
{
UniqueId = CategoryUniqueId.NewUniqueId();
Version = 0;
}
}
public class ESCreateCategoryCommandHandler
: IRequestHandler<ESCreateCategoryCommand, ESCreateCategoryCommandResponse>
{
private readonly ISessionForEventSourcing _sessionForEventSourcing;
private readonly IMapper _mapper;
public ESCreateCategoryCommandHandler(
ISessionForEventSourcing sessionForEventSourcing, IMapper mapper)
{
_mapper = mapper;
_sessionForEventSourcing = sessionForEventSourcing;
}
public async Task<ESCreateCategoryCommandResponse> Handle
(ESCreateCategoryCommand request, CancellationToken cancellationToken)
{
var validator = new ESCreateCategoryCommandValidator();
var validatorResult = await validator.ValidateAsync(request);
if (!validatorResult.IsValid)
return new ESCreateCategoryCommandResponse(validatorResult);
var category = _mapper.Map<Category>(request);
var item = new CategoryAggregate(category);
_sessionForEventSourcing.Add<CategoryAggregate>(item);
_sessionForEventSourcing.Commit();
var ids = _mapper.Map<IdsDto>(category.Ids());
return new ESCreateCategoryCommandResponse(ids);
}
}
public class ESCreateCategoryCommandResponse : BaseResponse
{
public IdsDto CategoryIds { get; set; }
public ESCreateCategoryCommandResponse(IdsDto Ids)
: base()
{
CategoryIds = Ids;
}
public ESCreateCategoryCommandResponse() : base()
{ }
public ESCreateCategoryCommandResponse(ExecutionStatus status)
: base(status)
{
}
public ESCreateCategoryCommandResponse(ExecutionStatus status, string message)
: base(status, message)
{
}
public ESCreateCategoryCommandResponse(ValidationResult validationResult)
: base(validationResult)
{ }
public ESCreateCategoryCommandResponse(string message)
: base(message)
{ }
public ESCreateCategoryCommandResponse(string message, bool success)
: base(message, success)
{ }
}
public class EsUpdateCategoryCommand
: IRequest<EsUpdateCategoryCommandResponse>
{
public Guid UniqueId { get; set; }
public string Name { get; set; }
public string DisplayName { get; set; }
public string WhatWeAreLookingFor { get; set; }
public int Version { get; set; }
}
public class EsUpdateCategoryCommandHandler : IRequestHandler
<EsUpdateCategoryCommand, EsUpdateCategoryCommandResponse>
{
private readonly ISessionForEventSourcing _sessionForEventSourcing;
private readonly IMapper _mapper;
public EsUpdateCategoryCommandHandler(
ISessionForEventSourcing sessionForEventSourcing, IMapper mapper)
{
_mapper = mapper;
_sessionForEventSourcing = sessionForEventSourcing;
}
public async Task<EsUpdateCategoryCommandResponse> Handle
(EsUpdateCategoryCommand request, CancellationToken cancellationToken)
{
var validator = new EsUpdateCategoryCommandValidator();
var validatorResult = await validator.ValidateAsync(request);
if (!validatorResult.IsValid)
return new EsUpdateCategoryCommandResponse(validatorResult);
var category = _mapper.Map<Category>(request);
var eventstoreResult = Get<CategoryAggregate>
(category.UniqueId.GetAggregateKey());
if (!eventstoreResult.Success)
return new EsUpdateCategoryCommandResponse
(eventstoreResult.RemoveGeneric());
if ((eventstoreResult.Value.Version - 1) > category.Version )
return new EsUpdateCategoryCommandResponse
(ExecutionStatus.EventStoreConcurrencyError
(@$"You sended old version.
Yours {category.Version}. Should be :{eventstoreResult.Value.Version - 1}"));
eventstoreResult.Value.Update(category);
var status = _sessionForEventSourcing.Commit();
return new EsUpdateCategoryCommandResponse(status);
}
private ExecutionStatus<T> Get<T>
(AggregateKey id, int? expectedVersion = null) where T : AggregateRoot
{
var a = _sessionForEventSourcing.Get<T>(id, expectedVersion);
return a;
}
}
public class EsCreateJudgeCommand : IRequest<EsCreateJudgeCommandResponse>
{
public string Login { get; set; }
public string Password { get; set; }
public NameDto Name { get; set; }
public DateTime Birthdate { get; set; }
public int CategoryId { get; set; }
public CategoryDto Category
{
get
{
return new CategoryDto() { Id = CategoryId };
}
}
internal JudgeUniqueId UniqueId { get; }
public EsCreateJudgeCommand()
{
UniqueId = JudgeUniqueId.New();
Version = 0;
}
}
public class EsCreateJudgeCommandHandler
: IRequestHandler<EsCreateJudgeCommand, EsCreateJudgeCommandResponse>
{
private readonly ISessionForEventSourcing _sessionForEventSourcing;
private readonly IMapper _mapper;
public EsCreateJudgeCommandHandler(
ISessionForEventSourcing sessionForEventSourcing, IMapper mapper)
{
_mapper = mapper;
_sessionForEventSourcing = sessionForEventSourcing;
}
public async Task<EsCreateJudgeCommandResponse> Handle
(EsCreateJudgeCommand request, CancellationToken cancellationToken)
{
var validator = new EsCreateJudgeCommandValidator();
var validatorResult = await validator.ValidateAsync(request);
if (!validatorResult.IsValid)
return new EsCreateJudgeCommandResponse(validatorResult);
var judge = _mapper.Map<Judge>(request);
var item = new JudgeAggregate(judge);
_sessionForEventSourcing.Add<JudgeAggregate>(item);
_sessionForEventSourcing.Commit();
var ids = _mapper.Map<IdsDto>(judge.Ids());
return new EsCreateJudgeCommandResponse(ids);
}
}
public class EsUpdateJudgeCommand
: IRequest<EsUpdateJudgeCommandResponse>
{
public Guid UniqueId { get; set; }
public string Login { get; set; }
public string Password { get; set; }
public NameDto Name { get; set; }
public int CategoryId { get; set; }
public int Version { get; set; }
public CategoryDto Category
{
get
{
return new CategoryDto() { Id = CategoryId };
}
}
public DateTime Birthdate { get; set; }
}
public class EsUpdateJudgeCommandHandler :
IRequestHandler<EsUpdateJudgeCommand, EsUpdateJudgeCommandResponse>
{
private readonly ISessionForEventSourcing _sessionForEventSourcing;
private readonly IMapper _mapper;
public EsUpdateJudgeCommandHandler(
ISessionForEventSourcing sessionForEventSourcing, IMapper mapper)
{
_mapper = mapper;
_sessionForEventSourcing = sessionForEventSourcing;
}
public async Task<EsUpdateJudgeCommandResponse> Handle
(EsUpdateJudgeCommand request, CancellationToken cancellationToken)
{
var validator = new EsUpdateJudgeCommandValidator();
var validatorResult = await validator.ValidateAsync(request);
if (!validatorResult.IsValid)
return new EsUpdateJudgeCommandResponse(validatorResult);
var judgedto = _mapper.Map<JudgeDto>(request);
var judge = _mapper.Map<Judge>(judgedto);
var eventstoreResult = Get<JudgeAggregate>(judge.UniqueId.GetAggregateKey());
if (!eventstoreResult.Success)
return await Task.FromResult(new
EsUpdateJudgeCommandResponse(eventstoreResult.RemoveGeneric()));
if ((eventstoreResult.Value.Version - 1) > judge.Version)
return new EsUpdateJudgeCommandResponse
(ExecutionStatus.EventStoreConcurrencyError
(@$"You sended old version. Your version {judge.Version}.
Should be :{eventstoreResult.Value.Version - 1}"));
eventstoreResult.Value.Update(judge);
_sessionForEventSourcing.Commit();
return new EsUpdateJudgeCommandResponse();
}
private ExecutionStatus<T> Get<T>
(AggregateKey id, int? expectedVersion = null) where T : AggregateRoot
{
return _sessionForEventSourcing.Get<T>(id, expectedVersion);
}
}
public class EsSubmitCallForSpeechCommand
: IRequest<EsSubmitCallForSpeechCommandResponse>
{
public int CategoryId { get; set; }
public CategoryDto Category
{
get
{
return new CategoryDto() { Id = CategoryId };
}
}
public int Version { get; }
public CallForSpeechUniqueId UniqueId { get; }
public EsSubmitCallForSpeechCommand()
{
UniqueId = CallForSpeechUniqueId.NewUniqueId();
Version = 0;
}
public SpeakerDto Speaker { get; set; }
public SpeechDto Speech { get; set; }
public string Number { get; set; }
public RegistrationDto Registration
{
get
{
return new RegistrationDto()
{
RegistrationDate = AppTime.Now()
};
}
}
}
public class EsSubmitCallForSpeechCommandHandler
: IRequestHandler<EsSubmitCallForSpeechCommand, EsSubmitCallForSpeechCommandResponse>
{
private readonly ISessionForEventSourcing _sessionForEventSourcing;
private readonly IMapper _mapper;
public EsSubmitCallForSpeechCommandHandler(
ISessionForEventSourcing sessionForEventSourcing, IMapper mapper)
{
_mapper = mapper;
_sessionForEventSourcing = sessionForEventSourcing;
}
public async Task<EsSubmitCallForSpeechCommandResponse> Handle
(EsSubmitCallForSpeechCommand request, CancellationToken cancellationToken)
{
var validator = new EsSubmitCallForSpeechCommandValidation();
var validatorResult = await validator.ValidateAsync(request);
if (!validatorResult.IsValid)
return new EsSubmitCallForSpeechCommandResponse(validatorResult);
var csf = _mapper.Map<CallForSpeech>(request);
var item = new CallForSpeechAggregate(csf);
_sessionForEventSourcing.Add<CallForSpeechAggregate>(item);
_sessionForEventSourcing.Commit();
var ids = _mapper.Map<IdsDto>(csf.Ids());
return new EsSubmitCallForSpeechCommandResponse(ids);
}
}
public class EsEvaluateCallForSpeechCommand
: IRequest<EsEvaluateCallForSpeechCommandResponse>
{
public Guid CallForSpeechIdUnique { get; set; }
public int Version { get; set; }
}
public class EsEvaluateCallForSpeechCommandHandler
: IRequestHandler<EsEvaluateCallForSpeechCommand, EsEvaluateCallForSpeechCommandResponse>
{
private readonly ISessionForEventSourcing _sessionForEventSourcing;
private readonly IMapper _mapper;
private readonly IScoringRulesFactory _scoringRulesFactory;
public EsEvaluateCallForSpeechCommandHandler(
ISessionForEventSourcing sessionForEventSourcing, IMapper mapper,
IScoringRulesFactory scoringRulesFactory)
{
_mapper = mapper;
_sessionForEventSourcing = sessionForEventSourcing;
_scoringRulesFactory = scoringRulesFactory;
}
public async Task<EsEvaluateCallForSpeechCommandResponse>
Handle(EsEvaluateCallForSpeechCommand request, CancellationToken cancellationToken)
{
var cfsuniqueId = _mapper.Map<CallForSpeechUniqueId>
(request.CallForSpeechIdUnique);
var eventstoreResult = Get<CallForSpeechAggregate>
(cfsuniqueId.GetAggregateKey());
if (!eventstoreResult.Success)
return await Task.FromResult(new EsEvaluateCallForSpeechCommandResponse());
var aggregateCallForSpeaker = eventstoreResult.Value;
if (aggregateCallForSpeaker.Version > request.Version)
return new EsEvaluateCallForSpeechCommandResponse
(ExecutionStatus.EventStoreConcurrencyError(@$"You sended old version.
Yours {request.Version}.
Should be :{aggregateCallForSpeaker.Version}"));
var csf = _mapper.Map<CallForSpeech>(aggregateCallForSpeaker);
var domainLogicResult = csf.TryEvaluate(_scoringRulesFactory.DefaultSet);
if (!domainLogicResult.Success)
return new EsEvaluateCallForSpeechCommandResponse(domainLogicResult);
aggregateCallForSpeaker.Evaulated(csf);
_sessionForEventSourcing.Commit();
var scoredto = _mapper.Map<ScoreDto>(csf.ScoreResult);
return new EsEvaluateCallForSpeechCommandResponse(scoredto);
}
private ExecutionStatus<T> Get<T>
(AggregateKey id, int? expectedVersion = null) where T : AggregateRoot
{
var a = _sessionForEventSourcing.Get<T>(id, expectedVersion);
return a;
}
}
public class EsPreliminaryAcceptCallForSpeechCommand
:
IRequest<EsPreliminaryAcceptCallForSpeechCommandResponse>
{
public Guid CallForSpeechUniqueId { get; set; }
public int JudgeId { get; set; }
public int Version { get; set; }
}
public class EsPreliminaryAcceptCallForSpeechCommandHandler
: IRequestHandler<EsPreliminaryAcceptCallForSpeechCommand, EsPreliminaryAcceptCallForSpeechCommandResponse>
{
private readonly ISessionForEventSourcing _sessionForEventSourcing;
private readonly IMapper _mapper;
private readonly IZEsJudgeRepository _zEsJudgeRepository;
public EsPreliminaryAcceptCallForSpeechCommandHandler(
ISessionForEventSourcing sessionForEventSourcing, IMapper mapper,
IZEsJudgeRepository zEsJudgeRepository)
{
_mapper = mapper;
_sessionForEventSourcing = sessionForEventSourcing;
_zEsJudgeRepository = zEsJudgeRepository;
}
public async Task<EsPreliminaryAcceptCallForSpeechCommandResponse>
Handle(EsPreliminaryAcceptCallForSpeechCommand request, CancellationToken cancellationToken)
{
var cfsuniqueId = _mapper.Map<CallForSpeechUniqueId>(request.CallForSpeechUniqueId);
var judgeId = _mapper.Map<JudgeId>(request.JudgeId);
var databaseOperationJudge = await _zEsJudgeRepository.GetByIdAsync(judgeId);
if (!databaseOperationJudge.Success)
return new EsPreliminaryAcceptCallForSpeechCommandResponse
(databaseOperationJudge.RemoveGeneric(),
"Judge Problem");
var judge = databaseOperationJudge.Value;
var eventstoreResult = Get<CallForSpeechAggregate>
(cfsuniqueId.GetAggregateKey());
if (!eventstoreResult.Success)
return new EsPreliminaryAcceptCallForSpeechCommandResponse
(eventstoreResult.RemoveGeneric());
var aggregateCallForSpeaker = eventstoreResult.Value;
if ((eventstoreResult.Value.Version - 1) > (request.Version))
return new EsPreliminaryAcceptCallForSpeechCommandResponse
(ExecutionStatus.EventStoreConcurrencyError(@$"You sended old version.
Yours {request.Version}. Should be :{aggregateCallForSpeaker.Version - 1}"));
var csf = _mapper.Map<CallForSpeech>(aggregateCallForSpeaker);
var domainLogicResult = csf.TryPreliminaryAccept(judge);
if (!domainLogicResult.Success)
return new EsPreliminaryAcceptCallForSpeechCommandResponse(domainLogicResult);
aggregateCallForSpeaker.PreliminaryAccepted(csf);
_sessionForEventSourcing.Commit();
return new EsPreliminaryAcceptCallForSpeechCommandResponse();
}
private ExecutionStatus<T> Get<T>(AggregateKey id, int? expectedVersion = null) where T : AggregateRoot
{
var a = _sessionForEventSourcing.Get<T>(id, expectedVersion);
return a;
}
}
public class Constants
{
public const string QUEUE_JUDGE_CREATED = "judge_created";
public const string QUEUE_JUDGE_UPDATED = "judge_updated";
public const string QUEUE_JUDGE_DELETED = "judge_deleted";
public const string QUEUE_CATEGORY_CREATED = "category_created";
public const string QUEUE_CATEGORY_UPDATED = "category_updated";
public const string QUEUE_CALLFORSPEECH_SUBMITC = "callforspeech_submit";
public const string QUEUE_CALLFORSPEECH_REJECTC = "callforspeech_reject";
public const string QUEUE_CALLFORSPEECH_PRELIMINARY_ACCEPT = "callforspeech_preminal_accept";
public const string QUEUE_CALLFORSPEECH_EVALUATE = "callforspeech_evaluate";
public const string QUEUE_CALLFORSPEECH_ACCEPT = "callforspeech_accept";
}
public interface ISettings
{
TimeSpan Frequency { get; set; }
TimeSpan Timeout { get; set; }
}
public class Settings : ISettings
{
public TimeSpan Frequency { get; set; }
public TimeSpan Timeout { get; set; }
}
{
"ConnectionStrings": {
"GeekLemonConferenceConnectionString": "NotUsed",
"ZEsGeekLemonConferenceConnectionString":
"DataSource=C:/Users/PanNiebieski/source/repos/GeekLemonConference/GeekLemonConference.Api/DataBase/ZEsGeekLemonDB.db"
},
"RabbitMqSetting": {
"username": "guest",
"password": "guest",
"hostname": "localhost",
"uri": "amqp://localhost:5672/",
"virtualhost": "/"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<CategoryCreateEvent, Category>();
CreateMap<CategoryUpdateEvent, Category>();
CreateMap<JudgeCreatedEvent, Judge>();
CreateMap<JudgeUpdatedEvent, Judge>();
CreateMap<JudgeDeletedEvent, Judge>();
CreateMap<CallForSpeechAcceptedEvent, CallForSpeech>();
CreateMap<CallForSpeechEvaulatedEvent, CallForSpeech>();
CreateMap<CallForSpeechPreliminaryAcceptEvent, CallForSpeech>();
CreateMap<CallForSpeechRejectedEvent, CallForSpeech>();
CreateMap<CallForSpeechSubmitedEvent, CallForSpeech>();
}
}
public class BackgroundEventHandlersServerService : BackgroundService
{
private readonly ILogger Logger;
private readonly ISettings Settings;
private readonly ISubscribeBase[] _subscribes;
private string _ContentRootPath;
public BackgroundEventHandlersServerService(ILogger logger, ISettings settings,
IHostingEnvironment env,
ISubscribeBase[] subscribes)
{
Settings = settings;
Logger = logger;
_subscribes = subscribes;
_ContentRootPath = env.ContentRootPath;
}
protected async override Task ExecuteAsync(CancellationToken stoppingToken)
{
ConnectionFactory connectionFactory = new ConnectionFactory();
var builder = new ConfigurationBuilder()
.SetBasePath(_ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)
.AddEnvironmentVariables();
builder.Build().GetSection("RabbitMqSetting").Bind(connectionFactory);
using IConnection conn = connectionFactory.CreateConnection();
using IModel channel = conn.CreateModel();
Console.WriteLine("CreateConnection CreateModel");
try
{
Console.ForegroundColor = ConsoleColor.DarkCyan;
foreach (var item in _subscribes)
{
channel.QueueDeclare(
queue: item.QUEUE_Name,
durable: false,
exclusive: false,
autoDelete: false,
arguments: null
);
Console.WriteLine($"QueueDeclare {item.QUEUE_Name}");
}
foreach (var item in _subscribes)
{
item.StartSubing(channel);
Console.WriteLine($"StartSubing {item.QUEUE_Name}");
}
Console.ForegroundColor = ConsoleColor.Gray;
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"Exception {ex}");
Console.ForegroundColor = ConsoleColor.Gray;
LogError(ex.Message);
}
int i = 0;
while (!stoppingToken.IsCancellationRequested)
{
i++;
Console.ForegroundColor = (ConsoleColor)i;
Console.WriteLine($"Still Working and Still Waiting");
Console.ForegroundColor = ConsoleColor.Gray;
if (i == 15)
{
Console.Clear();
i = 0;
}
await Task.Delay(Settings.Frequency, stoppingToken);
}
}
public async override Task StopAsync(CancellationToken cancellationToken)
{
foreach (var item in _subscribes)
{
try
{
item.Dispose();
}
catch (Exception)
{
}
}
await base.StopAsync(cancellationToken);
}
private void LogError(string error)
{
Logger.Error(error);
}
}
public interface ISubscribeBase
{
string QUEUE_Name { get; }
DomainEvent DeserializeObject(string json);
Task HandleBasicDeliver(string consumerTag,
ulong deliveryTag, bool redelivered, string exchange,
string routingKey,
IBasicProperties properties, ReadOnlyMemory<byte> body);
void StartSubing(IModel channel);
void Dispose();
Task<ExecutionStatus> HandleEvent(DomainEvent @event);
}
public abstract class SubscribeBase : ISubscribeBase
{
private MessageReceiverBase Consumer { get; set; }
private IModel _channel;
public abstract string QUEUE_Name { get; }
public abstract DomainEvent DeserializeObject(string json);
public abstract Task<ExecutionStatus> HandleEvent(DomainEvent @event);
public void StartSubing(IModel channel)
{
_channel = channel;
Consumer = new MessageReceiverBase(channel, this);
channel.BasicConsume(this.QUEUE_Name,
false, Consumer);
}
public async Task HandleBasicDeliver(string consumerTag, ulong deliveryTag,
bool redelivered, string exchange, string routingKey, IBasicProperties
properties, ReadOnlyMemory<byte> body)
{
var json = Encoding.UTF8.GetString(body.Span);
var obj = DeserializeObject(json);
var status = await HandleEvent(obj);
if (status.Success)
{
try
{
_channel.BasicAck(deliveryTag, false);
}
catch (Exception ex)
{
throw;
}
}
}
public void Dispose()
{
Consumer.Dispose();
}
}
public class MessageReceiverBase : DefaultBasicConsumer
{
private readonly IModel _channel;
private ISubscribeBase _messageReceiverBasez;
public MessageReceiverBase(IModel channel, ISubscribeBase messageReceiverBasez)
{
_messageReceiverBasez = messageReceiverBasez;
_channel = channel;
}
public override void HandleBasicDeliver(string consumerTag,
ulong deliveryTag, bool redelivered, string exchange,
string routingKey,
IBasicProperties properties, ReadOnlyMemory<byte> body)
{
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.WriteLine($"Consuming Message");
Console.WriteLine(string.Concat("Message received from the exchange ", exchange));
Console.WriteLine(string.Concat("Consumer tag: ", consumerTag));
Console.WriteLine(string.Concat("Delivery tag: ", deliveryTag));
Console.WriteLine(string.Concat("Routing tag: ", routingKey));
var json = Encoding.UTF8.GetString(body.Span);
Console.WriteLine(string.Concat("Message: ", json));
Console.ForegroundColor = ConsoleColor.Gray;
_messageReceiverBasez.HandleBasicDeliver
(consumerTag, deliveryTag, redelivered, exchange, routingKey, properties, body);
}
public void Dispose()
{_channel.Dispose();}
}
public class SubscribeCreatedCategory : SubscribeBase
{
private IZEsCategoryRepository _zEsCategoryRepository;
private IMapper _mapper;
public SubscribeCreatedCategory(IZEsCategoryRepository ZEsCategoryRepository,
IMapper mapper)
{
_zEsCategoryRepository = ZEsCategoryRepository;
_mapper = mapper;
}
public override string QUEUE_Name => Constants.QUEUE_CATEGORY_CREATED;
public override DomainEvent DeserializeObject(string json)
{
return JsonConvert.DeserializeObject<CategoryCreateEvent>(json);
}
public async override Task<ExecutionStatus> HandleEvent(DomainEvent @event)
{
CategoryCreateEvent categoryCreateEvent = @event as CategoryCreateEvent;
var category = _mapper.Map<Category>(categoryCreateEvent);
var execution = await _zEsCategoryRepository.AddAsync(category);
return execution.RemoveGeneric();
}
}
public class SubscribeUpdateCategory : SubscribeBase
{
private IZEsCategoryRepository _zEsCategoryRepository;
private IMapper _mapper;
public SubscribeUpdateCategory(IZEsCategoryRepository ZEsCategoryRepository,
IMapper mapper)
{
_zEsCategoryRepository = ZEsCategoryRepository;
_mapper = mapper;
}
public override string QUEUE_Name => Constants.QUEUE_CATEGORY_UPDATED;
public override DomainEvent DeserializeObject(string json)
{
return JsonConvert.DeserializeObject<CategoryUpdateEvent>(json);
}
public override async Task<ExecutionStatus> HandleEvent(DomainEvent @event)
{
CategoryUpdateEvent categoryCreateEvent = @event as CategoryUpdateEvent;
var category = _mapper.Map<Category>(categoryCreateEvent);
var execution = await
_zEsCategoryRepository.UpdateByUniqueIdAsync(category);
return execution;
}
}
public class SubscribeDeleteJudge : SubscribeBase
{
private IZEsJudgeRepository _zEsJudgeRepository;
private IMapper _mapper;
public SubscribeDeleteJudge(IZEsJudgeRepository zEsJudgeRepository,
IMapper mapper) :
base()
{
_zEsJudgeRepository = zEsJudgeRepository;
_mapper = mapper;
}
public override string QUEUE_Name => Constants.QUEUE_JUDGE_DELETED;
public override DomainEvent DeserializeObject(string json)
{
return JsonConvert.DeserializeObject<JudgeDeletedEvent>(json);
}
public override async Task<ExecutionStatus> HandleEvent(DomainEvent @event)
{
JudgeDeletedEvent judgeDeletedEvent = @event as JudgeDeletedEvent;
var execution = await
_zEsJudgeRepository.DeleteAsync(judgeDeletedEvent.UniqueId);
return execution;
}
}
public class SubscribeSubmitCallForSpeech : SubscribeBase
{
private IZEsCallForSpeechRepository _ZEsCallForSpeechRepository;
private IMapper _mapper;
public SubscribeSubmitCallForSpeech
(IZEsCallForSpeechRepository zEsCallForSpeechRepository,
IMapper mapper) :
base()
{
_ZEsCallForSpeechRepository = zEsCallForSpeechRepository;
_mapper = mapper;
}
public override string QUEUE_Name => Constants.QUEUE_CALLFORSPEECH_SUBMITC;
public override DomainEvent DeserializeObject(string json)
{
return JsonConvert.DeserializeObject<CallForSpeechSubmitedEvent>(json);
}
public async override Task<ExecutionStatus> HandleEvent(DomainEvent @event)
{
CallForSpeechSubmitedEvent CallForSpeechSubmitedEvent
= @event as CallForSpeechSubmitedEvent;
var cfs = _mapper.Map<CallForSpeech>(CallForSpeechSubmitedEvent);
var execution = await
_ZEsCallForSpeechRepository.SubmitAsync(cfs);
return execution.RemoveGeneric();
}
}
public class SubscribeEvaluateCallForSpeech : SubscribeBase
{
private IZEsCallForSpeechRepository _ZEsCallForSpeechRepository;
private IMapper _mapper;
public SubscribeEvaluateCallForSpeech(
IZEsCallForSpeechRepository zEsCallForSpeechRepository,
IMapper mapper) :
base()
{
_ZEsCallForSpeechRepository = zEsCallForSpeechRepository;
_mapper = mapper;
}
public override string QUEUE_Name => Constants.QUEUE_CALLFORSPEECH_EVALUATE;
public override DomainEvent DeserializeObject(string json)
{
return JsonConvert.DeserializeObject<CallForSpeechEvaulatedEvent>(json);
}
public async override Task<ExecutionStatus> HandleEvent(DomainEvent @event)
{
CallForSpeechEvaulatedEvent callForSpeechRejectedEvent =
@event as CallForSpeechEvaulatedEvent;
var cfs = _mapper.Map<CallForSpeech>(callForSpeechRejectedEvent);
var execution = await
_ZEsCallForSpeechRepository
.SaveEvaluatationAsync
(cfs.UniqueId, cfs.ScoreResult, cfs.Status);
return execution;
}
}
public abstract class SubscribeBase : ISubscribeBase
{
................................
public async Task HandleBasicDeliver(string consumerTag, ulong deliveryTag,
bool redelivered, string exchange, string routingKey, IBasicProperties
properties, ReadOnlyMemory<byte> body)
{
var json = Encoding.UTF8.GetString(body.Span);
var obj = DeserializeObject(json);
var status = await HandleEvent(obj);
if (status.Success)
{
try
{
_channel.BasicAck(deliveryTag, false);
}
catch (Exception ex)
{
throw;
}
}
}
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddAutoMapper(Assembly.GetExecutingAssembly());
services.AddGeekLemonPersistenceDapperSQLiteServices(Configuration);
var seriFileLogger = new LoggerConfiguration()
.WriteTo.File(@"D:\Temp\").CreateLogger();
services.AddSingleton<Serilog.ILogger>(seriFileLogger);
services.AddSingleton<ISettings>(new Settings()
{
Timeout = TimeSpan.FromSeconds(5),
Frequency = TimeSpan.FromSeconds(5),
});
services.AddTransient<ISubscribeBase, SubscribeCreateJudge>();
services.AddTransient<ISubscribeBase, SubscribeUpdateJudge>();
services.AddTransient<ISubscribeBase, SubscribeDeleteJudge>();
services.AddTransient<ISubscribeBase, SubscribeCreatedCategory>();
services.AddTransient<ISubscribeBase, SubscribeUpdateCategory>();
services.AddTransient<ISubscribeBase, SubscribeSubmitCallForSpeech>();
services.AddTransient<ISubscribeBase, SubscribeRejectCallForSpeech>();
services.AddTransient<ISubscribeBase, SubscribePreminalAcceptCallForSpeech>();
services.AddTransient<ISubscribeBase, SubscribeEvaluateCallForSpeech>();
services.AddTransient<ISubscribeBase, SubscribeAcceptCallForSpeech>();
services.AddTransient<ISubscribeBase[]>
(p => p.GetServices<ISubscribeBase>().ToArray());
services.AddHostedService<BackgroundEventHandlersServerService>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.
Response.WriteAsync
("GeekLemonConference.Infrastructure.BackgroundEventHandlersServer Working");
});
});
}