Habr├й рдкрд░ рдФрд░ рди рдХреЗрд╡рд▓ рд▓реЗрдЦреЛрдВ рдХрд╛ рдПрдХ рд╕рднреНрдп рд░рд╛рд╢рд┐ рдбреЛрдореЗрди рдбреНрд░рд┐рд╡реЗрди рдбрд┐рдЬрд╝рд╛рдЗрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ - рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рдФрд░ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП .Net рдХреЗ рд╕рд╛рдеред рд▓реЗрдХрд┐рди рд╕рд╛рде рд╣реА, рдЗрд╕ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХрд╛ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣рд┐рд╕реНрд╕рд╛ рдореВрд▓реНрдп рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдХреНрд╕рд░ рдЦрд░рд╛рдм рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ .Net рдХреЛрд░ рдореЗрдВ рдореВрд▓реНрдп рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реВрдВрдЧрд╛ред
рдПрдХ рдмрд┐рд▓реНрд▓реА рдХреЗ рдиреАрдЪреЗ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХреЛрдб рд╣реЛрддреЗ рд╣реИрдВред
рд╕рд┐рджреНрдзрд╛рдВрдд рдХреА рдмрд┐рдЯ
рдбреЛрдореЗрди рдбреНрд░рд┐рд╡реЗрди рдбрд┐рдЬрд╝рд╛рдЗрди рдХреА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХрд╛ рдореВрд▓
рдбреЛрдореЗрди рд╣реИ - рд╡рд╣ рд╡рд┐рд╖рдп рдХреНрд╖реЗрддреНрд░ рдЬрд┐рд╕ рдкрд░ рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣рд╛рдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рд╕рдВрдкреВрд░реНрдг рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рд╣реИ, рдЬреЛ рдЖрдорддреМрд░ рдкрд░ рд╡рд┐рднрд┐рдиреНрди рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рддрд╛ рд╣реИред рдбреЗрдЯрд╛ рджреЛ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ:
- рдЗрдХрд╛рдИ рд╡рд╕реНрддреБ
- рдорд╛рди рдСрдмреНрдЬреЗрдХреНрдЯ (рдЗрд╕рдХреЗ рдмрд╛рдж - VO)
рдПрдВрдЯрд┐рдЯреА рдСрдмреНрдЬреЗрдХреНрдЯ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдореЗрдВ рдПрдХ рдЗрдХрд╛рдИ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╣рдореЗрд╢рд╛ рдПрдХ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рдПрдВрдЯрд┐рдЯреА рдХреЛ рджреВрд╕рд░реЗ рдПрдВрдЯрд┐рдЯреА рдХреЗ рд╕рд╛рде рдкрд╛рдпрд╛ рдпрд╛ рддреБрд▓рдирд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрджрд┐ рджреЛ рдПрдВрдЯрд┐рдЯреА рдореЗрдВ рдПрдХ рд╕рдорд╛рди рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдПрдХ рд╣реА рдПрдВрдЯрд┐рдЯреА рд╣реИред рд▓рдЧрднрдЧ рд╣рдореЗрд╢рд╛ рдмрджрд▓рддреЗ рд░рд╣рддреЗ рд╣реИрдВред
рд╡реИрд▓реНрдпреВ рдСрдмреНрдЬреЗрдХреНрдЯ рдПрдХ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдкреНрд░рдХрд╛рд░ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдореВрд▓реНрдп рдирд┐рд░реНрдорд╛рдг рдХреЗ рджреМрд░рд╛рди рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдкреВрд░реЗ рдЬреАрд╡рди рдореЗрдВ рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИред рдЗрд╕рдХреА рдкрд╣рдЪрд╛рди рдирд╣реАрдВ рд╣реИред рдпрджрд┐ рджреЛ VO рд╕рдВрд░рдЪрдирд╛рддреНрдордХ рд░реВрдк рд╕реЗ рд╕рдорд╛рди рд╣реИрдВ, рддреЛ рд╡реЗ рд╕рдорддреБрд▓реНрдп рд╣реИрдВред
рдЗрдХрд╛рдИ рдореЗрдВ рдЕрдиреНрдп рдЗрдХрд╛рдИ рдФрд░ VO рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рд╡реАрдУ рдореЗрдВ рдЕрдиреНрдп рд╡реАрдУ рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдПрдВрдЯрд┐рдЯреА рдирд╣реАрдВред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдбреЛрдореЗрди рддрд░реНрдХ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЗрдХрд╛рдИ рдФрд░ рд╡реАрдУ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП - рдпрд╣ рдЗрд╕рдХреА рд╕реНрдерд┐рд░рддрд╛ рдХреА рдЧрд╛рд░рдВрдЯреА рджреЗрддрд╛ рд╣реИред рдмреБрдирд┐рдпрд╛рджреА рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдЬреИрд╕реЗ рдХрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ, рдЗрдВрдЯ, рдЖрджрд┐ред рдЕрдХреНрд╕рд░ рд╡реЗ VO рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдХреЗрд╡рд▓ рдбреЛрдореЗрди рдХреА рд╕реНрдерд┐рддрд┐ рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдЬреЛ DDD рдХреЗ рдврд╛рдВрдЪреЗ рдореЗрдВ рд▓рдЧрднрдЧ рдПрдХ рдЖрдкрджрд╛ рд╣реИред
рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИред рд╡рд┐рднрд┐рдиреНрди рдирд┐рдпрдорд╛рд╡рд▓реА рдореЗрдВ, рд╕рднреА рдХреЛ рдмреАрдорд╛рд░ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╡реНрдпрдХреНрддрд┐ рд╡рд░реНрдЧ рдХреЛ рдЕрдХреНрд╕рд░ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } }
рд╕рд░рд▓ рдФрд░ рд╕реНрдкрд╖реНрдЯ - рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛, рдирд╛рдо рдФрд░ рдЙрдореНрд░, рдЖрдк рдХрд╣рд╛рдВ рдЧрд▓рддреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ?
рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рдХрдИ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВ - рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡реНрдпрд╛рдкрд╛рд░рд┐рдХ рддрд░реНрдХ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ, рдПрдХ рдирд╛рдо рдЕрдирд┐рд╡рд╛рд░реНрдп рд╣реИ, рдпрд╣ рд╢реВрдиреНрдп рд▓рдВрдмрд╛рдИ рдпрд╛ 100 рд╕реЗ рдЕрдзрд┐рдХ рд╡рд░реНрдг рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рд╡рд┐рд╢реЗрд╖ рд╡рд░реНрдг, рд╡рд┐рд░рд╛рдо рдЪрд┐рд╣реНрди рдЖрджрд┐ рдирд╣реАрдВ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред рдФрд░ рдЖрдпреБ 10 рд╡рд░реНрд╖ рд╕реЗ рдХрдо рдпрд╛ 120 рд╡рд░реНрд╖ рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреА рд╣реИред
рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ, 5 рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рдкреВрд░реНрдгрд╛рдВрдХ рд╣реИ, рдЗрд╕реА рддрд░рд╣ рдПрдХ рдЦрд╛рд▓реА рд╕реНрдЯреНрд░рд┐рдВрдЧред рд▓реЗрдХрд┐рди рдбреЛрдореЗрди рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЧрд▓рдд рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реИред
рдЕрднреНрдпрд╛рд╕ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ
рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ VO рдХреЛ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдЗрд╕рдореЗрдВ рдПрдХ рдорд╛рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдХреЗ рд▓рд┐рдП рдорд╛рдиреНрдп рд╣реИред
рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рджреМрд░рд╛рди рд░реАрдбрдСрдирд▓реА рдкреНрд░реЙрдкрд░реНрдЯреА рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рдХреЗ рдЗрдореНрдпреВрдирд┐рдЯреА рд╣рд╛рд╕рд┐рд▓ рдХреА рдЬрд╛рддреА рд╣реИред
рдореВрд▓реНрдп рдХрд╛ рд╕рддреНрдпрд╛рдкрди рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ (рдЧрд╛рд░реНрдб рдХреНрд▓реЙрдЬ) рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред рд╕рддреНрдпрд╛рдкрди рдХреЛ рд╕реНрд╡рдпрдВ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд░реВрдк рд╕реЗ рдЙрдкрд▓рдмреНрдз рдХрд░рдирд╛ рд╡рд╛рдВрдЫрдиреАрдп рд╣реИ - рддрд╛рдХрд┐ рдЕрдиреНрдп рдкрд░рддреЗрдВ рдХреНрд▓рд╛рдЗрдВрдЯ (рдЙрд╕реА рдмреНрд░рд╛рдЙрдЬрд╝рд░) рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдбреЗрдЯрд╛ рдХреЛ рдорд╛рдиреНрдп рдХрд░ рд╕рдХреЗрдВред
рдЖрдЗрдП рдирд╛рдо рдФрд░ рдЖрдпреБ рдХреЗ рд▓рд┐рдП рдПрдХ VO рдмрдирд╛рдПрдВред рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рд╣рдо рдХрд╛рд░реНрдп рдХреЛ рдереЛрдбрд╝рд╛ рдЬрдЯрд┐рд▓ рдХрд░рддреЗ рд╣реИрдВ - FirstName рдФрд░ LastName рдХреЗ рд╕рдВрдпреЛрдЬрди рдореЗрдВ рдПрдХ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдирд╛рдо рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдЗрд╕реЗ рд╡реНрдпрдХреНрддрд┐ рдкрд░ рд▓рд╛рдЧреВ рдХрд░реЗрдВред
рдирд╛рдо public class Name { private static readonly Regex ValidationRegex = new Regex( @"^[\p{L}\p{M}\p{N}]{1,100}\z", RegexOptions.Singleline | RegexOptions.Compiled); public Name(String value) { if (!IsValid(value)) { throw new ArgumentException("Name is not valid"); } Value = value; } public String Value { get; } public static Boolean IsValid(String value) { return !String.IsNullOrWhiteSpace(value) && ValidationRegex.IsMatch(value); } public override Boolean Equals(Object obj) { return obj is Name other && StringComparer.Ordinal.Equals(Value, other.Value); } public override Int32 GetHashCode() { return StringComparer.Ordinal.GetHashCode(Value); } }
PersonalName public class PersonalName { protected PersonalName() { } public PersonalName(Name firstName, Name lastName) { if (firstName == null) { throw new ArgumentNullException(nameof(firstName)); } if (lastName == null) { throw new ArgumentNullException(nameof(lastName)); } FirstName = firstName; LastName = lastName; } public Name FirstName { get; } public Name LastName { get; } public String FullName => $"{FirstName} {LastName}"; public override Boolean Equals(Object obj) { return obj is PersonalName personalName && EqualityComparer<Name>.Default.Equals(FirstName, personalName.FirstName) && EqualityComparer<Name>.Default.Equals(LastName, personalName.LastName); } public override Int32 GetHashCode() { return HashCode.Combine(FirstName, LastName); } public override String ToString() { return FullName; } }
рдЖрдпреБ public class Age { public Age(Int32 value) { if (!IsValid(value)) { throw new ArgumentException("Age is not valid"); } Value = value; } public Int32 Value { get; } public static Boolean IsValid(Int32 value) { return 10 <= value && value <= 120; } public override Boolean Equals(Object obj) { return obj is Age other && Value == other.Value; } public override Int32 GetHashCode() { return Value.GetHashCode(); } }
рдФрд░ рдЕрдВрдд рдореЗрдВ рд╡реНрдпрдХреНрддрд┐:
public class Person { public Person(PersonalName personalName, Age age) { if (personalName == null) { throw new ArgumentNullException(nameof(personalName)); } if (age == null) { throw new ArgumentNullException(nameof(age)); } Id = Guid.NewGuid(); PersonalName= personalName; Age = age; } public Guid Id { get; private set; } public PersonalName PersonalName{ get; set; } public Age Age { get; set; } }
рдЗрд╕рд▓рд┐рдП, рд╣рдо рдПрдХ рдкреВрд░реНрдг рдирд╛рдо рдпрд╛ рдЖрдпреБ рдХреЗ рдмрд┐рдирд╛ рд╡реНрдпрдХреНрддрд┐ рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддреЗред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо "рдЧрд▓рдд" рдирд╛рдо рдпрд╛ "рдЧрд▓рдд" рдЙрдореНрд░ рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддреЗред рдПрдХ рдЕрдЪреНрдЫрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ Name.IsValid ("рдЬреЙрди") рдФрд░ Age.IsValid (35) рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдирд┐рдпрдВрддреНрд░рдХ рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдбреЗрдЯрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдЧрд╛ рдФрд░ рдЧрд▓рдд рдбреЗрдЯрд╛ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЧреНрд░рд╛рд╣рдХ рдХреЛ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╕реВрдЪрд┐рдд рдХрд░реЗрдЧрд╛ред
рдпрджрд┐ рд╣рдо рдХреЗрд╡рд▓ рдПрдВрдЯрд┐рдЯреА рдФрд░ VO рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореЙрдбрд▓ рдореЗрдВ рд╣рд░ рдЬрдЧрд╣ рдПрдХ рдирд┐рдпрдо рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рд╕реЗ рдЦреБрдж рдХреА рд░рдХреНрд╖рд╛ рдХрд░реЗрдВрдЧреЗ - рдЧрд▓рдд рдбреЗрдЯрд╛ рдмрд╕ рдореЙрдбрд▓ рдореЗрдВ рдирд╣реАрдВ рдорд┐рд▓реЗрдЧрд╛ред
рд╣рда
рдЕрдм рд╣рдореЗрдВ рдЕрдкрдиреЗ рдбреЗрдЯрд╛ рдХреЛ рдбреЗрдЯрд╛ рд╡реЗрдпрд░рд╣рд╛рдЙрд╕ рдореЗрдВ рд╕рд╣реЗрдЬрдиреЗ рдФрд░ рдЕрдиреБрд░реЛрдз рдкрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рдо ORM рдХреЗ рд░реВрдк рдореЗрдВ рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдФрд░ рдбреЗрдЯрд╛ рд╡реЗрдпрд░рд╣рд╛рдЙрд╕ MS SQL рд╕рд░реНрд╡рд░ рд╣реИред
рдбреАрдбреАрдбреА рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ: рджреГрдврд╝рддрд╛ рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдВрдЪреЗ рдХреА рдкрд░рдд рдХреА рдПрдХ рдЙрдк-рдкреНрд░рдЬрд╛рддрд┐ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдбреЗрдЯрд╛ рдкрд╣реБрдВрдЪ рдХреЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдЫреБрдкрд╛рддрд╛ рд╣реИред
рдбреЛрдореЗрди рдХреЛ рдкрд░реНрд╕рд┐рд╕реНрдЯреЗрдВрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдЬрд╛рдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдХреЗрд╡рд▓ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЗ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред
рдФрд░ рджреГрдврд╝рддрд╛ рдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рдореИрдк рдХрд░рдирд╛, рд╕рд╛рде рд╣реА рдПрдХ UnitOfWork рдСрдмреНрдЬреЗрдХреНрдЯред
рдЗрд╕рдореЗрдВ рджреЛ рд░рд╛рдп рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рд░рд┐рдкреЛрдЬрд┐рдЯрд░реА рдФрд░ рдпреВрдирд┐рдЯ рдСрдл рд╡рд░реНрдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИред
рдПрдХ рдУрд░ - рдирд╣реАрдВ, рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛрд░ рдореЗрдВ рдпрд╣ рд╕рдм рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рд╛рдЧреВ рд╣реИред рдЕрдЧрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ DAL -> рдмрд┐рдЬрдиреЗрд╕ рд▓реЙрдЬрд┐рдХ -> рдкреНрд░реЗрдЬреЗрдВрдЯреЗрд╢рди рдХрд╛ рдПрдХ рдмрд╣реБ-рд╕реНрддрд░реАрдп рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рд╣реИ, рдЬреЛ рдбреЗрдЯрд╛ рд╕реНрдЯреЛрд░реЗрдЬ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ, рддреЛ рд╕реАрдзреЗ EF Core рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреНрдпреЛрдВ рди рдХрд░реЗрдВред
рд▓реЗрдХрд┐рди DDD рдореЗрдВ рдбреЛрдореЗрди рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣рдг рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП ORM рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ - рдпреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рд╕рднреА рд╕реВрдХреНрд╖реНрдорддрд╛рдПрдВ рд╣реИрдВ рдЬреЛ рджреГрдврд╝рддрд╛ рдореЗрдВ рд╕рдВрд▓рдЧреНрди рд╣реИрдВ рдФрд░ рдХрд┐рд╕реА рдФрд░ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд░реБрдЪрд┐ рдирд╣реАрдВ рд╣реИрдВред рдпрджрд┐ рд╣рдо рдЕрдиреНрдп рдкрд░рддреЛрдВ рдХреЛ DbContext рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рддреБрд░рдВрдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рд╡рд░рдгреЛрдВ рдХрд╛ рдЦреБрд▓рд╛рд╕рд╛ рдХрд░рддреЗ рд╣реИрдВ, рдХрд╕рдХрд░ рдЪрдпрдирд┐рдд ORM рд╕реЗ рдмрд╛рдВрдзрддреЗ рд╣реИрдВ рдФрд░ DAL рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ - рд╕рднреА рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдХреЗ рдЖрдзрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдореЛрдЯреЗ рддреМрд░ рдкрд░, рдбреЛрдореЗрди рдХреЛ рдУрдЖрд░рдПрдо рдореЗрдВ рдмрджрд▓рд╛рд╡ рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдПрдХ рдкрд░рдд рдХреЗ рд░реВрдк рдореЗрдВ рджреГрдврд╝рддрд╛ рдХреЗ рдиреБрдХрд╕рд╛рди рдХреЛ рдзреНрдпрд╛рди рдирд╣реАрдВ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдПред
рддреЛ, рдбреЛрдореЗрди рдореЗрдВ рд╡реНрдпрдХреНрддрд┐ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдЗрдВрдЯрд░рдлрд╝реЗрд╕,
public interface IPersons { Task Add(Person person); Task<IReadOnlyList<Person>> GetList(); }
рдФрд░ рджреГрдврд╝рддрд╛ рдореЗрдВ рдЗрд╕рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:
public class EfPersons : IPersons { private readonly PersonsDemoContext _context; public EfPersons(UnitOfWork unitOfWork) { if (unitOfWork == null) { throw new ArgumentNullException(nameof(unitOfWork)); } _context = unitOfWork.Context; } public async Task Add(Person person) { if (person == null) { throw new ArgumentNullException(nameof(person)); } await _context.Persons.AddAsync(person); } public async Task<IReadOnlyList<Person>> GetList() { return await _context.Persons.ToListAsync(); } }
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХреБрдЫ рднреА рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИред рдЖрдЙрдЯ рдСрдл рдж рдмреЙрдХреНрд╕ рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛрд░ рдХреЗрд╡рд▓ рдмреБрдирд┐рдпрд╛рджреА рдкреНрд░рдХрд╛рд░ (рд╕реНрдЯреНрд░рд┐рдВрдЧ, рдЗрдВрдЯ, рдбреЗрдЯрд╛рдЗрдо, рдЖрджрд┐) рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдирд╛рдо рдФрд░ рдЖрдпреБ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рд╣реИред рдЖрдЗрдП рд╣рдорд╛рд░реА рдореВрд▓реНрдп рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдИрдПрдл рдХреЛрд░ рд╕рд┐рдЦрд╛рдПрдВред
рд╡рд┐рдиреНрдпрд╛рд╕
рдзрд╛рд░рд╛рдкреНрд░рд╡рд╛рд╣ рдПрдкреАрдЖрдИ рдбреАрдбреАрдбреА рдореЗрдВ рдПрдВрдЯрд┐рдЯреА рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЙрдкрдпреБрдХреНрдд рд╣реИред рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдбреЛрдореЗрди рдХреЛ рдорд╛рдирдЪрд┐рддреНрд░рдг рдХреА рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдЬрд╛рдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рдореВрд▓ рд╡рд┐рдиреНрдпрд╛рд╕ рдХреЗ рд╕рд╛рде рджреГрдврд╝рддрд╛ рдореЗрдВ рдПрдХ рд╡рд░реНрдЧ рдмрдирд╛рдПрдБ
internal class PersonConfiguration : IEntityTypeConfiguration<Person> { public void Configure(EntityTypeBuilder<Person> builder) { builder.ToTable("Persons"); builder.HasKey(p => p.Id); builder.Property(p => p.Id).ValueGeneratedNever(); } }
рдФрд░ рдЗрд╕реЗ DbContext рдореЗрдВ рдкреНрд▓рдЧ рдХрд░реЗрдВ:
protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.ApplyConfiguration(new PersonConfiguration()); }
рдорд╛рдирдЪрд┐рддреНрд░рдг
рд╡рд╣ рдЕрдиреБрднрд╛рдЧ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдпрд╣ рд╕рд╛рдордЧреНрд░реА рд▓рд┐рдЦреА рдЧрдИ рдереАред
рдлрд┐рд▓рд╣рд╛рд▓, рдЧреИрд░-рдорд╛рдирдХ рдХрдХреНрд╖рд╛рдУрдВ рдХреЛ рдЖрдзрд╛рд░ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдореИрдк рдХрд░рдиреЗ рдХреЗ рджреЛ рдФрд░ рдХрдо рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХреЗ рд╣реИрдВ - рдореВрд▓реНрдп рд░реВрдкрд╛рдВрддрд░рдг рдФрд░ рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рдкреНрд░рдХрд╛рд░ред
рдореВрд▓реНрдп рд░реВрдкрд╛рдВрддрд░рдг
рдпрд╣ рд╕реБрд╡рд┐рдзрд╛ рдЗрдХрд╛рдИ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛрд░ 2.1 рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреА рдФрд░ рдЖрдкрдХреЛ рджреЛ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдмреАрдЪ рд░реВрдкрд╛рдВрддрд░рдг рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред
рдЖрдЗрдП рдЖрдпреБ рдХреЗ рд▓рд┐рдП рдХрдирд╡рд░реНрдЯрд░ рд▓рд┐рдЦреЗрдВ (рдЗрд╕ рдЦрдВрдб рдореЗрдВ рд╕рднреА рдХреЛрдб рдкрд░реНрд╕рдирдСрдлрд┐рдЧреНрд░реЗрд╢рди рдореЗрдВ рд╣реИ):
var ageConverter = new ValueConverter<Age, Int32>( v => v.Value, v => new Age(v)); builder .Property(p => p.Age) .HasConversion(ageConverter) .HasColumnName("Age") .HasColumnType("int") .IsRequired();
рд╕рд░рд▓ рдФрд░ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡рд╛рдХреНрдп рд░рдЪрдирд╛, рд▓реЗрдХрд┐рди рджреЛрд╖реЛрдВ рдХреЗ рдмрд┐рдирд╛ рдирд╣реАрдВ:
- рдЕрд╢рдХреНрдд рдХрдиреНрд╡рд░реНрдЯ рдХрд░рдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрде;
- рдПрдХ рдПрдХрд▓ рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдХрдИ рд╕реНрддрдВрднреЛрдВ рдореЗрдВ рдмрджрд▓рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд;
- EF Core рдЗрд╕ рдкреНрд░реЙрдкрд░реНрдЯреА рдХреЗ рд╕рд╛рде LINQ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдХреЛ SQL рдХреНрд╡реЗрд░реА рдореЗрдВ рдирд╣реАрдВ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИред
рдореИрдВ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдЕрдВрддрд┐рдо рдмрд┐рдВрджреБ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реВрдВрдЧрд╛ред рджреА рдЧрдИ рдЙрдореНрд░ рдореЗрдВ рд╡реНрдпрдХреНрддрд┐ рдХреА рд╕реВрдЪреА рджреЗрдиреЗ рд╡рд╛рд▓реЗ рднрдВрдбрд╛рд░ рдореЗрдВ рдПрдХ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ:
public async Task<IReadOnlyList<Person>> GetOlderThan(Age age) { if (age == null) { throw new ArgumentNullException(nameof(age)); } return await _context.Persons .Where(p => p.Age.Value > age.Value) .ToListAsync(); }
рдЖрдпреБ рдХреЗ рд▓рд┐рдП рдПрдХ рд╢рд░реНрдд рд╣реИ, рд▓реЗрдХрд┐рди EF Core рдЗрд╕реЗ SQL рдХреНрд╡реЗрд░реА рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдФрд░, рдЬрд╣рд╛рдБ рддрдХ рдкрд╣реБрдБрдЪрддреЗ рд╣реБрдП (), рдпрд╣ рдкреВрд░реА рдореЗрдЬ рдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдореЛрд░реА рдореЗрдВ рд▓реЛрдб рдХрд░ рджреЗрдЧрд╛ рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА, LINQ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдпрд╣ рд╢рд░реНрдд рдХреЛ рдкреВрд░рд╛ рдХрд░реЗрдЧрд╛ред p.ge.Value> age.Value ред
рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдореВрд▓реНрдп рд░реВрдкрд╛рдВрддрд░рдг рдПрдХ рд╕рд░рд▓ рдФрд░ рддреНрд╡рд░рд┐рдд рдорд╛рдирдЪрд┐рддреНрд░рдг рд╡рд┐рдХрд▓реНрдк рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдИрдПрдл рдХреЛрд░ рдХреА рдЗрд╕ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдпрд╛рдж рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЕрдиреНрдпрдерд╛, рдХрд┐рд╕реА рдмрд┐рдВрджреБ рдкрд░, рдмрдбрд╝реА рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЛ рдХреНрд╡реЗрд░реА рдХрд░рддреЗ рд╕рдордп, рд╕реНрдореГрддрд┐ рдмрд╛рд╣рд░ рдирд┐рдХрд▓ рд╕рдХрддреА рд╣реИред
рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рдкреНрд░рдХрд╛рд░
рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рд╡рд╛рд▓реЗ рдкреНрд░рдХрд╛рд░ рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛрд░ 2.0 рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдП рдФрд░ рдирд┐рдпрдорд┐рдд рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ рд╕реЗ рдЬрдЯрд┐рд▓ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ред
рдЖрдЗрдП рдЖрдпреБ рдХреЛ рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдмрдирд╛рдПрдВ:
builder.OwnsOne(p => p.Age, a => { a.Property(u => u.Value).HasColumnName("Age"); a.Property(u => u.Value).HasColumnType("int"); a.Property(u => u.Value).IsRequired(); });
рдмреБрд░рд╛ рдирд╣реАрдВ рд╣реИред рдФрд░ рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдореВрд▓реНрдп рд░реВрдкрд╛рдВрддрд░рдгреЛрдВ рдХреЗ рдХреБрдЫ рдиреБрдХрд╕рд╛рди рдирд╣реАрдВ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреН рдЕрдВрдХ 2 рдФрд░ 3ред
2. рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдПрдХ рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдХрдИ рд╕реНрддрдВрднреЛрдВ рдореЗрдВ рдмрджрд▓рдирд╛
рд╕рдВрднрд╡ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд
рдЖрдкрдХреЛ PersonalName рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдЪрд╛рд╣рд┐рдП, рд╣рд╛рд▓рд╛рдБрдХрд┐ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рднрд░рд╛ рд╣реБрдЖ рд╣реИ:
builder.OwnsOne(b => b.PersonalName, pn => { pn.OwnsOne(p => p.FirstName, fn => { fn.Property(x => x.Value).HasColumnName("FirstName"); fn.Property(x => x.Value).HasColumnType("nvarchar(100)"); fn.Property(x => x.Value).IsRequired(); }); pn.OwnsOne(p => p.LastName, ln => { ln.Property(x => x.Value).HasColumnName("LastName"); ln.Property(x => x.Value).HasColumnType("nvarchar(100)"); ln.Property(x => x.Value).IsRequired(); }); });
3. EF Core рдЗрд╕ рдкреНрд░реЙрдкрд░реНрдЯреА рдХреЗ рд╕рд╛рде рдПрдХ LINQ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдХреЛ SQL рдХреНрд╡реЗрд░реА рдореЗрдВ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИред
рд╕реВрдЪреА рд▓реЛрдб рдХрд░рддреЗ рд╕рдордп LastName рдФрд░ FirstName рджреНрд╡рд╛рд░рд╛ рдЫрдБрдЯрд╛рдИ рдЬреЛрдбрд╝реЗрдВ:
public async Task<IReadOnlyList<Person>> GetList() { return await _context.Persons .OrderBy(p => p.PersonalName.LastName.Value) .ThenBy(p => p.PersonalName.FirstName.Value) .ToListAsync(); }
рдЗрд╕ рддрд░рд╣ рдХреА рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ SQL рдХреНрд╡реЗрд░реА рдореЗрдВ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рд╕реЙрд░реНрдЯрд┐рдВрдЧ SQL рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рдХреА рдЬрд╛рддреА рд╣реИ, рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдирд╣реАрдВред
рдмреЗрд╢рдХ, рдЗрд╕рдХреЗ рдиреБрдХрд╕рд╛рди рднреА рд╣реИрдВред
- рдЕрд╢рдХреНрдд рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛рдПрдВ рджреВрд░ рдирд╣реАрдВ рд╣реБрдИ рд╣реИрдВ;
- рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рд╡рд╛рд▓реЗ рдкреНрд░рдХрд╛рд░ рдлрд╝реАрд▓реНрдб рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдирд╣реАрдВ рдкрдврд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЙрдирдХреЗ рдкрд╛рд╕ рдПрдХ рд╕рдВрд░рдХреНрд╖рд┐рдд рдпрд╛ рдирд┐рдЬреА рд╕реЗрдЯрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
- рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рд╡рд╛рд▓реЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдирд┐рдпрдорд┐рдд рдЗрдХрд╛рдИ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ:
- рдЙрдирдХреЗ рдкрд╛рд╕ рдПрдХ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реИ (рдПрдХ рдЫрд╛рдпрд╛ рд╕рдВрдкрддреНрддрд┐ рдХреА рддрд░рд╣, рдпрд╛рдиреА рдпрд╣ рдбреЛрдореЗрди рд╡рд░реНрдЧ рдореЗрдВ рдкреНрд░рдХрдЯ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ);
- EF Core, рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рд╡рд╛рд▓реЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдореЗрдВ рд╕рднреА рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рддрд╛ рд╣реИ, рдмрд┐рд▓реНрдХреБрд▓ рдирд┐рдпрдорд┐рдд рдЗрдХрд╛рдИ рдХреЗ рд▓рд┐рдПред
рдПрдХ рддрд░рдл, рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореВрд▓реНрдп рд╡рд╕реНрддреБрдПрдВ рдХреНрдпрд╛ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред рдЙрдирдХреЗ рдкрд╛рд╕ рдХреЛрдИ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред VO рдХреЛ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдЯреНрд░реИрдХ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП - рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╢реБрд░реВ рдореЗрдВ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рд╣реИрдВ, рдореВрд▓ рдПрдВрдЯрд┐рдЯреА рдХреЗ рдЧреБрдгреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди VO рдХреЗ рдЧреБрдгреЛрдВ рдХреЛ рдирд╣реАрдВред
рджреВрд╕рд░реА рдУрд░, рдпреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рд╡рд░рдг рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЫреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рд╕реЗ, рдордд рднреВрд▓рдирд╛ред рдЯреНрд░реИрдХрд┐рдВрдЧ рдкрд░рд┐рд╡рд░реНрддрди рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдпрд╣ рдПрдХрд▓ рдЗрдХрд╛рдИ рдХреЗ рдЪрдпрди (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдИрдбреА) рдпрд╛ рдЫреЛрдЯреА рд╕реВрдЪрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИ, рддреЛ "рднрд╛рд░реА" рдЗрдХрд╛рдИ (рдХрдИ рд╡реАрдУ-рдЧреБрдг) рдХреА рдмрдбрд╝реА рд╕реВрдЪрд┐рдпреЛрдВ рдХреЗ рдирдореВрдиреЗ рдХреЗ рд╕рд╛рде, рдЯреНрд░реИрдХрд┐рдВрдЧ рдХреА рд╡рдЬрд╣ рд╕реЗ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдЧрд┐рд░рд╛рд╡рдЯ рдмрд╣реБрдд рд╣реА рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реЛрдЧреАред
рдкреНрд░рджрд░реНрд╢рди
рд╣рдордиреЗ рдкрддрд╛ рд▓рдЧрд╛рдпрд╛ рдХрд┐ рдХрд┐рд╕реА рдбреЛрдореЗрди рдФрд░ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рд╡реИрд▓реНрдпреВ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПред рдпрд╣ рд╕рдм рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред рдЖрдЗрдП рджреЛ рд╕рд╛рдзрд╛рд░рдг рдкреГрд╖реНрда рдмрдирд╛рдПрдВ - рд╕реВрдЪреА рд╡реНрдпрдХреНрддрд┐ рдФрд░ рд╡реНрдпрдХреНрддрд┐ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдлреЙрд░реНрдо рдХреЗ рд╕рд╛рдеред
рдПрдХреНрд╢рди рддрд░реАрдХреЛрдВ рдХреЗ рдмрд┐рдирд╛ рдирд┐рдпрдВрддреНрд░рдХ рдХреЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
public class HomeController : Controller { private readonly IPersons _persons; private readonly UnitOfWork _unitOfWork; public HomeController(IPersons persons, UnitOfWork unitOfWork) { if (persons == null) { throw new ArgumentNullException(nameof(persons)); } if (unitOfWork == null) { throw new ArgumentNullException(nameof(unitOfWork)); } _persons = persons; _unitOfWork = unitOfWork; }
рд╡реНрдпрдХреНрддрд┐ рд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд░рд┐рдпрд╛ рдЬреЛрдбрд╝реЗрдВ:
[HttpGet] public async Task<IActionResult> Index() { var persons = await _persons.GetList(); var result = new PersonsListModel { Persons = persons .Select(CreateModel) .ToArray() }; return View(result); }
рд░рд╛рдп @model PersonsListModel @{ ViewData["Title"] = "Persons List"; } <div class="text-center"> <h2 class="display-4">Persons</h2> </div> <table class="table"> <thead> <tr> <td><b>Last name</b></td> <td><b>First name</b></td> <td><b>Age</b></td> </tr> </thead> @foreach (var p in Model.Persons) { <tr> <td>@p.LastName</td> <td>@p.FirstName</td> <td>@p.Age</td> </tr> } </table>
рдХреБрдЫ рднреА рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИ - рд╣рдордиреЗ рд╕реВрдЪреА рд▓реЛрдб рдХреА, рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рдбреЗрдЯрд╛-рдЯреНрд░рд╛рдВрд╕рдлрд░ рдСрдмреНрдЬреЗрдХреНрдЯ (рдкрд░реНрд╕рдиреЛрдбреЗрд▓) рдмрдирд╛рдпрд╛
рд╡реНрдпрдХреНрддрд┐ рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП рднреЗрдЬрд╛ред
рдмрд╣реБрдд рдЕрдзрд┐рдХ рджрд┐рд▓рдЪрд╕реНрдк рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдЬреЛрдбрд╝ рд╣реИ:
[HttpPost] public async Task<IActionResult> AddPerson(PersonModel model) { if (model == null) { return BadRequest(); } if (!Name.IsValid(model.FirstName)) { ModelState.AddModelError(nameof(model.FirstName), "FirstName is invalid"); } if (!Name.IsValid(model.LastName)) { ModelState.AddModelError(nameof(model.LastName), "LastName is invalid"); } if (!Age.IsValid(model.Age)) { ModelState.AddModelError(nameof(model.Age), "Age is invalid"); } if (!ModelState.IsValid) { return View(); } var firstName = new Name(model.FirstName); var lastName = new Name(model.LastName); var person = new Person( new PersonalName(firstName, lastName), new Age(model.Age)); await _persons.Add(person); await _unitOfWork.Commit(); var persons = await _persons.GetList(); var result = new PersonsListModel { Persons = persons .Select(CreateModel) .ToArray() }; return View("Index", result); }
рд░рд╛рдп @model PersonDemo.Models.PersonModel @{ ViewData["Title"] = "Add Person"; } <h2 class="display-4">Add Person</h2> <div class="row"> <div class="col-md-4"> <form asp-action="AddPerson"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="FirstName" class="control-label"></label> <input asp-for="FirstName" class="form-control" /> <span asp-validation-for="FirstName" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="LastName" class="control-label"></label> <input asp-for="LastName" class="form-control" /> <span asp-validation-for="LastName" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Age" class="control-label"></label> <input asp-for="Age" class="form-control" /> <span asp-validation-for="Age" class="text-danger"></span> </div> <div class="form-group"> <input type="submit" value="Create" class="btn btn-primary" /> </div> </form> </div> </div> @section Scripts { @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} }
рдЖрдиреЗ рд╡рд╛рд▓реЗ рдбреЗрдЯрд╛ рдХреА рдПрдХ рдЕрдирд┐рд╡рд╛рд░реНрдп рдорд╛рдиреНрдпрддрд╛ рд╣реИ:
if (!Name.IsValid(model.FirstName)) { ModelState.AddModelError(nameof(model.FirstName), "FirstName is invalid"); }
рдпрджрд┐ рдРрд╕рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЧрд▓рдд рдорд╛рди рдХреЗ рд╕рд╛рде VO рдмрдирд╛рддреЗ рд╕рдордп, рдПрдХ ArgumentException рдХреЛ рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ (VO рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░реНрд╕ рдореЗрдВ рдЧрд╛рд░реНрдб рдХреНрд▓реЙрдЬ рдХреЛ рдпрд╛рдж рд░рдЦреЗрдВ)ред рд╕рддреНрдпрд╛рдкрди рдХреЗ рд╕рд╛рде, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╕рдВрджреЗрд╢ рднреЗрдЬрдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ рдХрд┐ рдореВрд▓реНрдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдЧрд▓рдд рд╣реИред
рдпрд╣рд╛рдВ рдЖрдкрдХреЛ рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рд╡рд┐рд╖рдпрд╛рдВрддрд░ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ - рдПрд╕реНрдк рдиреЗрдЯ рдХреЛрд░ рдореЗрдВ рдбреЗрдЯрд╛ рд╕рддреНрдпрд╛рдкрди рдХрд╛ рдПрдХ рдирд┐рдпрдорд┐рдд рддрд░реАрдХрд╛ рд╣реИ - рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред рд▓реЗрдХрд┐рди DDD рдореЗрдВ, рд╕рддреНрдпрд╛рдкрди рдХрд╛ рдпрд╣ рддрд░реАрдХрд╛ рдХрдИ рдХрд╛рд░рдгреЛрдВ рд╕реЗ рд╕рд╣реА рдирд╣реАрдВ рд╣реИ:
- рд╕рддреНрдпрд╛рдкрди рддрд░реНрдХ рдХреЗ рд▓рд┐рдП рдЧреБрдг рдХреНрд╖рдорддрд╛рдПрдВ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВ;
- рдХрд┐рд╕реА рднреА рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ, рдЬрд┐рд╕рдореЗрдВ рдорд╛рдирдХреЛрдВ рдХреЛ рдорд╛рдиреНрдп рдХрд░рдиреЗ рдХреЗ рдирд┐рдпрдо рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдбреЛрдореЗрди рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕ рдкрд░ рдЙрдирдХрд╛ рдПрдХрд╛рдзрд┐рдХрд╛рд░ рд╣реИ рдФрд░ рдЕрдиреНрдп рд╕рднреА рдкрд░рддреЛрдВ рдХреЛ рдЗрд╕ рдкрд░ рдзреНрдпрд╛рди рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдПред рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдЙрди рдкрд░ рднрд░реЛрд╕рд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рд╡рд┐рд╢реЗрд╖рддрд╛ рдЧрд▓рдд рдбреЗрдЯрд╛ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддреА рд╣реИ, рддреЛ VO рдмрдирд╛рддреЗ рд╕рдордп рд╣рдореЗрдВ рдлрд┐рд░ рд╕реЗ рдПрдХ рдЕрдкрд╡рд╛рдж рдорд┐рд▓реЗрдЧрд╛ред
AddPerson () рдкрд░ рд╡рд╛рдкрд╕ рдЬрд╛рдПрдВред рдбреЗрдЯрд╛ рд╕рддреНрдпрд╛рдкрди рдХреЗ рдмрд╛рдж, PersonalName, Age рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж Person рдмрдирд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдмрд╛рдж, рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рд╕рд╣реЗрдЬреЗрдВ (рдХрдорд┐рдЯ рдХрд░реЗрдВ)ред рдпрд╣ рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ EfPersons рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдкреНрд░рддрд┐рдмрджреНрдз рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХрд╛ рдХрд╛рд░реНрдп рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХреБрдЫ рдХреНрд░рд┐рдпрд╛ рдХрд░рдирд╛ рд╣реИ, рдФрд░ рдирд╣реАрдВред рдкреНрд░рддрд┐рдмрджреНрдз рдХреЗрд╡рд▓ рдмрд╛рд╣рд░ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрдм рдмрд┐рд▓реНрдХреБрд▓ - рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рддрдп рдХрд░рддрд╛ рд╣реИред рдЕрдиреНрдпрдерд╛, рдПрдХ рд╕реНрдерд┐рддрд┐ рд╕рдВрднрд╡ рд╣реИ рдЬрдм рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╡реНрдпрд╛рдкрд╛рд░ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЗ рдмреАрдЪ рдореЗрдВ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИ - рдХреБрдЫ рдбреЗрдЯрд╛ рд╕рд╣реЗрдЬреЗ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдХреБрдЫ рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВред рд╣рдо "рдЯреВрдЯреА рд╣реБрдИ" рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдбреЛрдореЗрди рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рдХрдорд┐рдЯ рдмрд╣реБрдд рдЕрдВрдд рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрджрд┐ рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИ, рддреЛ рд▓реЗрдирджреЗрди рдмрд╕ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧрд╛ред
рдирд┐рд╖реНрдХрд░реНрд╖
рдореИрдВрдиреЗ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рд╡реИрд▓реНрдпреВ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдФрд░ рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛрд░ рдореЗрдВ рдореИрдкрд┐рдВрдЧ рдХреА рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдХрд╛ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рд╕рд╛рдордЧреНрд░реА рдХреЛ рд╕рдордЭрдиреЗ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ рдХрд┐ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдбреЛрдореЗрди рдбреНрд░рд┐рд╡реЗрди рдбрд┐рдЬрд╝рд╛рдЗрди рдХреЗ рддрддреНрд╡реЛрдВ рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПред
рдкреВрд░рд╛ PersonsDemo рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реЛрд░реНрд╕ рдХреЛрдб -
GitHubрд╕рд╛рдордЧреНрд░реА рд╡реИрдХрд▓реНрдкрд┐рдХ (рдЕрд╢рдХреНрдд) рдорд╛рди рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдЦреБрд▓рд╛рд╕рд╛ рдирд╣реАрдВ рдХрд░рддреА рд╣реИ - рдпрджрд┐ PersonalName рдпрд╛ рдЖрдпреБ рдХреЛ рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдЧреБрдгреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рдереАред рдореИрдВ рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдЗрд╕рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХреБрдЫ рдЕрддрд┐рднрд╛рд░рд┐рдд рдерд╛ред рдпрджрд┐ рдЗрд╕ рдореБрджреНрджреЗ рдореЗрдВ рд░реБрдЪрд┐ рд╣реИ - рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд▓рд┐рдЦреЗрдВ, рдирд┐рд░рдВрддрд░рддрд╛ рд╣реЛрдЧреАред
рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ "рд╕реБрдВрджрд░ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░" рдХреЗ рдкреНрд░рд╢рдВрд╕рдХреЛрдВ рдХреЗ рд▓рд┐рдП рдФрд░ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдбреЛрдореЗрди рдбреНрд░рд┐рд╡реЗрди рдбрд┐рдЬрд╝рд╛рдЗрди рдореЗрдВ, рдореИрдВ
рдПрдВрдЯрд░рдкреНрд░рд╛рдЗрдЬрд╝ рд╢рд┐рд▓реНрдк рдХреМрд╢рд▓ рд╕рдВрд╕рд╛рдзрди рдХреА рдЕрддреНрдпрдзрд┐рдХ рдЕрдиреБрд╢рдВрд╕рд╛ рдХрд░рддрд╛ рд╣реВрдВред
рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рд╕рд╣реА рдирд┐рд░реНрдорд╛рдг рдФрд░ .Net рдкрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХрдИ рдЙрдкрдпреЛрдЧреА рд▓реЗрдЦ рд╣реИрдВред рдХреБрдЫ рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЛ рд╡рд╣рд╛рдБ рдЙрдзрд╛рд░ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ "рдореБрдХрд╛рдмрд▓рд╛" рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдкрд░рд┐рд▓рдХреНрд╖рд┐рдд рд╣реБрдЖ рдерд╛ред
рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рдкреНрд░рдХрд╛рд░ рдФрд░
рдореВрд▓реНрдп рд░реВрдкрд╛рдВрддрд░рдг рдХреЗ рд▓рд┐рдП рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рджрд╕реНрддрд╛рд╡реЗрдЬ
рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛
рдЧрдпрд╛ рдерд╛ ред