diff --git a/COP/COP.sln b/COP/COP.sln index 6433672..17e749e 100644 --- a/COP/COP.sln +++ b/COP/COP.sln @@ -5,7 +5,17 @@ VisualStudioVersion = 17.3.32825.248 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Components", "Components\Components.csproj", "{F22A3AAE-6F8D-4AEB-91B1-E8303166B5FF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinFormsTest", "WinFormsTest\WinFormsTest.csproj", "{F589AB00-F69A-4826-BE33-662F14E39F25}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinFormsTest", "WinFormsTest\WinFormsTest.csproj", "{F589AB00-F69A-4826-BE33-662F14E39F25}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientsDataModels", "ClientsDataModels\ClientsDataModels.csproj", "{9BE06619-49B5-4C59-984B-A70E7BF352D7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientsBusinessLogics", "ClientsBusinessLogics\ClientsBusinessLogics.csproj", "{BF3640B7-0602-4D4A-95CF-51E2DD9E1A9D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientsContracts", "ClientsContracts\ClientsContracts.csproj", "{8E8650C4-A930-442C-92CC-56082F3E072F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientDataBaseImplement", "ClientDataBaseImplement\ClientDataBaseImplement.csproj", "{4FB19656-B4A9-4070-BAD4-D9649DBEFB40}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChubykinaComponents", "ChubykinaComponents\ChubykinaComponents.csproj", "{335CABB5-5AC4-4688-92DD-5B91FEB16192}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -21,6 +31,26 @@ Global {F589AB00-F69A-4826-BE33-662F14E39F25}.Debug|Any CPU.Build.0 = Debug|Any CPU {F589AB00-F69A-4826-BE33-662F14E39F25}.Release|Any CPU.ActiveCfg = Release|Any CPU {F589AB00-F69A-4826-BE33-662F14E39F25}.Release|Any CPU.Build.0 = Release|Any CPU + {9BE06619-49B5-4C59-984B-A70E7BF352D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9BE06619-49B5-4C59-984B-A70E7BF352D7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9BE06619-49B5-4C59-984B-A70E7BF352D7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9BE06619-49B5-4C59-984B-A70E7BF352D7}.Release|Any CPU.Build.0 = Release|Any CPU + {BF3640B7-0602-4D4A-95CF-51E2DD9E1A9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BF3640B7-0602-4D4A-95CF-51E2DD9E1A9D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BF3640B7-0602-4D4A-95CF-51E2DD9E1A9D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BF3640B7-0602-4D4A-95CF-51E2DD9E1A9D}.Release|Any CPU.Build.0 = Release|Any CPU + {8E8650C4-A930-442C-92CC-56082F3E072F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8E8650C4-A930-442C-92CC-56082F3E072F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8E8650C4-A930-442C-92CC-56082F3E072F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8E8650C4-A930-442C-92CC-56082F3E072F}.Release|Any CPU.Build.0 = Release|Any CPU + {4FB19656-B4A9-4070-BAD4-D9649DBEFB40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4FB19656-B4A9-4070-BAD4-D9649DBEFB40}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4FB19656-B4A9-4070-BAD4-D9649DBEFB40}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4FB19656-B4A9-4070-BAD4-D9649DBEFB40}.Release|Any CPU.Build.0 = Release|Any CPU + {335CABB5-5AC4-4688-92DD-5B91FEB16192}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {335CABB5-5AC4-4688-92DD-5B91FEB16192}.Debug|Any CPU.Build.0 = Debug|Any CPU + {335CABB5-5AC4-4688-92DD-5B91FEB16192}.Release|Any CPU.ActiveCfg = Release|Any CPU + {335CABB5-5AC4-4688-92DD-5B91FEB16192}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/COP/ChubykinaComponents/ChubykinaComponents.csproj b/COP/ChubykinaComponents/ChubykinaComponents.csproj new file mode 100644 index 0000000..89d5eb4 --- /dev/null +++ b/COP/ChubykinaComponents/ChubykinaComponents.csproj @@ -0,0 +1,20 @@ + + + + net6.0 + enable + true + enable + True + + + + + + + + + + + + diff --git a/COP/ChubykinaComponents/Components/UserCheckedListBox.Designer.cs b/COP/ChubykinaComponents/Components/UserCheckedListBox.Designer.cs new file mode 100644 index 0000000..251a25a --- /dev/null +++ b/COP/ChubykinaComponents/Components/UserCheckedListBox.Designer.cs @@ -0,0 +1,58 @@ +namespace ChubykinaComponents.Components +{ + partial class UserCheckedListBox + { + /// + /// Обязательная переменная конструктора. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Освободить все используемые ресурсы. + /// + /// истинно, если управляемый ресурс должен быть удален; иначе ложно. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Код, автоматически созданный конструктором компонентов + + /// + /// Требуемый метод для поддержки конструктора — не изменяйте + /// содержимое этого метода с помощью редактора кода. + /// + private void InitializeComponent() + { + this.checkedListBox = new System.Windows.Forms.CheckedListBox(); + this.SuspendLayout(); + // + // checkedListBox + // + this.checkedListBox.FormattingEnabled = true; + this.checkedListBox.Location = new System.Drawing.Point(0, 0); + this.checkedListBox.Name = "checkedListBox"; + this.checkedListBox.Size = new System.Drawing.Size(150, 114); + this.checkedListBox.TabIndex = 0; + this.checkedListBox.SelectedIndexChanged += new System.EventHandler(this.checkedListBox_SelectedIndexChanged); + // + // UserCheckedListBox + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.checkedListBox); + this.Name = "UserCheckedListBox"; + this.Size = new System.Drawing.Size(150, 115); + this.ResumeLayout(false); + + } + + #endregion + + private CheckedListBox checkedListBox; + } +} \ No newline at end of file diff --git a/COP/ChubykinaComponents/Components/UserCheckedListBox.cs b/COP/ChubykinaComponents/Components/UserCheckedListBox.cs new file mode 100644 index 0000000..6162067 --- /dev/null +++ b/COP/ChubykinaComponents/Components/UserCheckedListBox.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace ChubykinaComponents.Components +{ + public partial class UserCheckedListBox : UserControl + { + public UserCheckedListBox() + { + InitializeComponent(); + } + + public string? selectedItem + { + get + { + return checkedListBox.SelectedItem is null ? null : checkedListBox.SelectedItem.ToString(); + } + set + { + if (value != null && checkedListBox.Items.Contains(value)) checkedListBox.SelectedItem = value; + } + } + + public event Action SelectedItemChange; + + public void addItems(List items) + { + foreach (string item in items) + { + checkedListBox.Items.Add(item); + } + } + + public void clear() + { + checkedListBox.Items.Clear(); + } + + private void checkedListBox_SelectedIndexChanged(object sender, EventArgs e) + { + if (checkedListBox.CheckedItems.Count > 1) + { + foreach (int index in checkedListBox.CheckedIndices) + { + if (index != checkedListBox.SelectedIndex) + { + checkedListBox.SetItemChecked(index, false); + } + } + } + SelectedItemChange?.Invoke(checkedListBox.SelectedItem.ToString()); + } + } +} diff --git a/COP/ChubykinaComponents/Components/UserCheckedListBox.resx b/COP/ChubykinaComponents/Components/UserCheckedListBox.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/COP/ChubykinaComponents/Components/UserCheckedListBox.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/COP/ChubykinaComponents/Components/UserDatePicker.Designer.cs b/COP/ChubykinaComponents/Components/UserDatePicker.Designer.cs new file mode 100644 index 0000000..255c5be --- /dev/null +++ b/COP/ChubykinaComponents/Components/UserDatePicker.Designer.cs @@ -0,0 +1,56 @@ +namespace ChubykinaComponents.Components +{ + partial class UserDatePicker + { + /// + /// Обязательная переменная конструктора. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Освободить все используемые ресурсы. + /// + /// истинно, если управляемый ресурс должен быть удален; иначе ложно. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Код, автоматически созданный конструктором компонентов + + /// + /// Требуемый метод для поддержки конструктора — не изменяйте + /// содержимое этого метода с помощью редактора кода. + /// + private void InitializeComponent() + { + this.dateTimePicker = new System.Windows.Forms.DateTimePicker(); + this.SuspendLayout(); + // + // dateTimePicker + // + this.dateTimePicker.Location = new System.Drawing.Point(3, 3); + this.dateTimePicker.Name = "dateTimePicker"; + this.dateTimePicker.Size = new System.Drawing.Size(250, 27); + this.dateTimePicker.TabIndex = 0; + this.dateTimePicker.ValueChanged += new System.EventHandler(this.dateTimePicker_ValueChanged); + // + // UserDatePicker + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.dateTimePicker); + this.Name = "UserDatePicker"; + this.Size = new System.Drawing.Size(257, 38); + this.ResumeLayout(false); + } + + #endregion + + private DateTimePicker dateTimePicker; + } +} diff --git a/COP/ChubykinaComponents/Components/UserDatePicker.cs b/COP/ChubykinaComponents/Components/UserDatePicker.cs new file mode 100644 index 0000000..d5c4de3 --- /dev/null +++ b/COP/ChubykinaComponents/Components/UserDatePicker.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using ChubykinaComponents.Exceptions; + +namespace ChubykinaComponents.Components +{ + public partial class UserDatePicker : UserControl + { + public UserDatePicker() + { + InitializeComponent(); + } + + public event Action DateChange; + private bool lowBoundrySet = false; + private bool highBoundrySet = false; + + public bool BoundriesSet { get { return lowBoundrySet && highBoundrySet; } } + + public DateTime? dateFrom + { + get + { + return lowBoundrySet ? dateTimePicker.MinDate : null; + } + set + { + if (value.HasValue) + { + dateTimePicker.MinDate = value.Value; + lowBoundrySet = true; + } + } + } + + public DateTime? dateTo + { + get + { + return highBoundrySet ? dateTimePicker.MaxDate : null; + } + set + { + if (value.HasValue) + { + dateTimePicker.MaxDate = value.Value; + highBoundrySet = true; + } + } + } + + public DateTime? Value + { + get + { + if (!lowBoundrySet || !highBoundrySet) + { + throw new DateBoundsNotSetException("Date bounds are not set."); + } + return dateTimePicker.Value; + } + set + { + if (lowBoundrySet && highBoundrySet && value.HasValue && value.Value >= dateFrom && value.Value <= dateTo) dateTimePicker.Value = value.Value; + } + } + + private void dateTimePicker_ValueChanged(object sender, EventArgs e) + { + DateChange?.Invoke(dateTimePicker.Value); + } + } +} \ No newline at end of file diff --git a/COP/ChubykinaComponents/Components/UserDatePicker.resx b/COP/ChubykinaComponents/Components/UserDatePicker.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/COP/ChubykinaComponents/Components/UserDatePicker.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/COP/ChubykinaComponents/Components/UserTreeView.Designer.cs b/COP/ChubykinaComponents/Components/UserTreeView.Designer.cs new file mode 100644 index 0000000..1c07199 --- /dev/null +++ b/COP/ChubykinaComponents/Components/UserTreeView.Designer.cs @@ -0,0 +1,55 @@ +namespace ChubykinaComponents.Components +{ + partial class UserTreeView + { + /// + /// Обязательная переменная конструктора. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Освободить все используемые ресурсы. + /// + /// истинно, если управляемый ресурс должен быть удален; иначе ложно. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Код, автоматически созданный конструктором компонентов + + /// + /// Требуемый метод для поддержки конструктора — не изменяйте + /// содержимое этого метода с помощью редактора кода. + /// + private void InitializeComponent() + { + this.treeView = new System.Windows.Forms.TreeView(); + this.SuspendLayout(); + // + // treeView + // + this.treeView.Location = new System.Drawing.Point(0, 0); + this.treeView.Name = "treeView"; + this.treeView.Size = new System.Drawing.Size(295, 212); + this.treeView.TabIndex = 0; + // + // UserTreeView + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.treeView); + this.Name = "UserTreeView"; + this.Size = new System.Drawing.Size(295, 212); + this.ResumeLayout(false); + } + + #endregion + + private TreeView treeView; + } +} diff --git a/COP/ChubykinaComponents/Components/UserTreeView.cs b/COP/ChubykinaComponents/Components/UserTreeView.cs new file mode 100644 index 0000000..7f75c08 --- /dev/null +++ b/COP/ChubykinaComponents/Components/UserTreeView.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using static System.Windows.Forms.VisualStyles.VisualStyleElement; + +namespace ChubykinaComponents.Components +{ + public partial class UserTreeView : UserControl + { + public UserTreeView() + { + InitializeComponent(); + } + private List<(string, bool)> hierarchy = new List<(string, bool)>(); + + public int SelectedNodeIndex + { + get + { + return treeView.SelectedNode?.Index ?? -1; + } + set + { + if (treeView.SelectedNode == null) treeView.SelectedNode = value >= 0 && value < treeView.Nodes.Count ? treeView.Nodes[value] : treeView.SelectedNode; + else treeView.SelectedNode = value >= 0 && value < treeView.SelectedNode.Nodes.Count ? treeView.SelectedNode.Nodes[value] : treeView.SelectedNode; + } + } + public T? getSelecetedNodeValue() + { + if (treeView.SelectedNode == null || treeView.SelectedNode.Nodes.Count > 0) return default(T); + TreeNode? node = treeView.SelectedNode; + var type = typeof(T); + var fields = type.GetFields(); + var item = Activator.CreateInstance(type); + + while (node != null) + { + var field = fields.FirstOrDefault(x => x.Name == node.Name); + if (field != null) + { + field.SetValue(item, node.Text); + } + node = node.Parent; + } + + return item != null ? (T)item : default(T); + } + + public void setHierarchy(List<(string, bool)> fields) + { + hierarchy = fields; + } + + public void addItems(List items) + { + var type = typeof(T); + var fields = type.GetFields(); + foreach (T item in items) + { + TreeNodeCollection nodes = treeView.Nodes; + for (int i = 0; i < hierarchy.Count; i++) + { + var field = fields.FirstOrDefault(x => x.Name.Equals(hierarchy[i].Item1)); + if (field is not null) + { + var node = nodes.Find(field.Name, false).FirstOrDefault(x => x.Text == field.GetValue(item).ToString()); + if (node is not null && !hierarchy[i].Item2) + { + nodes = node.Nodes; + } + else + { + TreeNode newNode = nodes.Add(field.Name, field.GetValue(item).ToString()); + nodes = newNode.Nodes; + } + } + } + } + } + } +} diff --git a/COP/ChubykinaComponents/Components/UserTreeView.resx b/COP/ChubykinaComponents/Components/UserTreeView.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/COP/ChubykinaComponents/Components/UserTreeView.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/COP/ChubykinaComponents/Exceptions/DateBoundsNotSetException.cs b/COP/ChubykinaComponents/Exceptions/DateBoundsNotSetException.cs new file mode 100644 index 0000000..ea9424e --- /dev/null +++ b/COP/ChubykinaComponents/Exceptions/DateBoundsNotSetException.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Runtime.Serialization; + +namespace ChubykinaComponents.Exceptions +{ + [Serializable] + public class DateBoundsNotSetException : ApplicationException + { + public DateBoundsNotSetException() : base() { } + public DateBoundsNotSetException(string message) : base(message) { } + public DateBoundsNotSetException(string message, Exception exception) : base(message, exception) { } + protected DateBoundsNotSetException(SerializationInfo info, StreamingContext contex) : base(info, contex) { } + } +} diff --git a/COP/ChubykinaComponents/Exceptions/DateOutOfBoundsException.cs b/COP/ChubykinaComponents/Exceptions/DateOutOfBoundsException.cs new file mode 100644 index 0000000..91eafa0 --- /dev/null +++ b/COP/ChubykinaComponents/Exceptions/DateOutOfBoundsException.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace ChubykinaComponents.Exceptions +{ + public class DateOutOfBoundsException : ApplicationException + { + public DateOutOfBoundsException() : base() { } + public DateOutOfBoundsException(string message) : base(message) { } + public DateOutOfBoundsException(string message, Exception exception) : base(message, exception) { } + protected DateOutOfBoundsException(SerializationInfo info, StreamingContext contex) : base(info, contex) { } + } +} diff --git a/COP/ChubykinaComponents/LogicalComponents/DiagramLegendEnum.cs b/COP/ChubykinaComponents/LogicalComponents/DiagramLegendEnum.cs new file mode 100644 index 0000000..217e6de --- /dev/null +++ b/COP/ChubykinaComponents/LogicalComponents/DiagramLegendEnum.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ChubykinaComponents.LogicalComponents +{ + public enum DiagramLegendEnum + { + TopLeft = 0, + TopRight = 1, + BottomRight = 2, + BottomLeft = 3, + } +} diff --git a/COP/ChubykinaComponents/LogicalComponents/ExcelDiagramComponent.Designer.cs b/COP/ChubykinaComponents/LogicalComponents/ExcelDiagramComponent.Designer.cs new file mode 100644 index 0000000..4954a14 --- /dev/null +++ b/COP/ChubykinaComponents/LogicalComponents/ExcelDiagramComponent.Designer.cs @@ -0,0 +1,36 @@ +namespace ChubykinaComponents.LogicalComponents +{ + partial class ExcelDiagramComponent + { + /// + /// Обязательная переменная конструктора. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Освободить все используемые ресурсы. + /// + /// истинно, если управляемый ресурс должен быть удален; иначе ложно. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Код, автоматически созданный конструктором компонентов + + /// + /// Требуемый метод для поддержки конструктора — не изменяйте + /// содержимое этого метода с помощью редактора кода. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/COP/ChubykinaComponents/LogicalComponents/ExcelDiagramComponent.cs b/COP/ChubykinaComponents/LogicalComponents/ExcelDiagramComponent.cs new file mode 100644 index 0000000..78d254e --- /dev/null +++ b/COP/ChubykinaComponents/LogicalComponents/ExcelDiagramComponent.cs @@ -0,0 +1,117 @@ +using Microsoft.Office.Interop.Excel; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace ChubykinaComponents.LogicalComponents +{ + public partial class ExcelDiagramComponent : Component + { + public ExcelDiagramComponent() + { + InitializeComponent(); + } + + public ExcelDiagramComponent(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } + public bool createWithDiagram(string path, string title, string diagramTitle, DiagramLegendEnum diagramLegendAnchor, List data, string seriesNameField, string valueField) + { + var excelApp = new Microsoft.Office.Interop.Excel.Application { SheetsInNewWorkbook = 1 }; + Workbook workbook = excelApp.Workbooks.Add(Type.Missing); + try + { + Worksheet worksheet = (Worksheet)workbook.Worksheets.get_Item(1); + + FieldInfo? seriesName = typeof(T).GetField(seriesNameField); + FieldInfo? value = typeof(T).GetField(valueField); + if (seriesName == null || value == null) throw new ArgumentException("Переданного поля не существует"); + int columnCount = 2; + foreach (var item in data) + { + var cell = worksheet.get_Range("A" + columnCount, "A" + columnCount); + cell.Font.Size = 14; + cell.Font.Name = "Times New Roman"; + cell.ColumnWidth = 8; + cell.RowHeight = 25; + cell.HorizontalAlignment = Constants.xlCenter; + cell.VerticalAlignment = Constants.xlCenter; + cell.Value2 = seriesName.GetValue(item); + + cell = worksheet.get_Range("B" + columnCount, "B" + columnCount); + cell.Font.Size = 14; + cell.Font.Name = "Times New Roman"; + cell.ColumnWidth = 8; + cell.RowHeight = 25; + cell.HorizontalAlignment = Constants.xlCenter; + cell.VerticalAlignment = Constants.xlCenter; + cell.Value2 = value.GetValue(item); + + columnCount++; + } + + //header + var excelcells = worksheet.get_Range("A1", "A1"); + excelcells.Font.Bold = true; + excelcells.Font.Size = 14; + excelcells.Font.Name = "Times New Roman"; + excelcells.ColumnWidth = 8; + excelcells.RowHeight = 25; + excelcells.HorizontalAlignment = Constants.xlCenter; + excelcells.VerticalAlignment = Constants.xlCenter; + excelcells.Value2 = title; + + var charts = worksheet.ChartObjects() as ChartObjects; + int chartWidth = 300; + int chartHeight = 300; + var chartObject = charts.Add(250, 10, chartWidth, chartHeight); + var chart = chartObject.Chart; + var range = worksheet.get_Range($"A2", $"B{columnCount - 1}"); + chart.SetSourceData(range); + chart.ChartType = XlChartType.xlPie; + switch (diagramLegendAnchor) + { + case DiagramLegendEnum.TopLeft: + chart.Legend.Top = 0; + chart.Legend.Left = 0; + break; + case DiagramLegendEnum.TopRight: + chart.Legend.Top = 0; + chart.Legend.Left = chartWidth - chart.Legend.Width; + break; + case DiagramLegendEnum.BottomLeft: + chart.Legend.Top = chartHeight - chart.Legend.Height; + chart.Legend.Left = 0; + break; + case DiagramLegendEnum.BottomRight: + chart.Legend.Top = chartHeight - chart.Legend.Height; + chart.Legend.Left = chartWidth - chart.Legend.Width; + break; + } + chart.ChartWizard(Source: range, Title: diagramTitle); + + object missing = System.Reflection.Missing.Value; + workbook.SaveAs(path, XlFileFormat.xlOpenXMLWorkbook, missing, missing, false, false, XlSaveAsAccessMode.xlNoChange, + XlSaveConflictResolution.xlUserResolution, true, missing, missing, missing); + workbook.Close(); + excelApp.Quit(); + + return true; + } + catch (Exception) + { + workbook.Close(); + excelApp.Quit(); + throw; + } + } + } +} diff --git a/COP/ChubykinaComponents/LogicalComponents/ExcelDiagramComponent.resx b/COP/ChubykinaComponents/LogicalComponents/ExcelDiagramComponent.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/COP/ChubykinaComponents/LogicalComponents/ExcelDiagramComponent.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/COP/ChubykinaComponents/LogicalComponents/ExcelImageInfo.cs b/COP/ChubykinaComponents/LogicalComponents/ExcelImageInfo.cs new file mode 100644 index 0000000..e72fea6 --- /dev/null +++ b/COP/ChubykinaComponents/LogicalComponents/ExcelImageInfo.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ChubykinaComponents.LogicalComponents +{ + public class ExcelImageInfo + { + public ExcelImageInfo(string path, string title, string[] imagePaths) + { + this.path = path; + this.title = title; + this.imagePaths = imagePaths; + } + + public string path; + public string title; + public string[] imagePaths; + } +} diff --git a/COP/ChubykinaComponents/LogicalComponents/ExcelImagesComponent.Designer.cs b/COP/ChubykinaComponents/LogicalComponents/ExcelImagesComponent.Designer.cs new file mode 100644 index 0000000..df017a3 --- /dev/null +++ b/COP/ChubykinaComponents/LogicalComponents/ExcelImagesComponent.Designer.cs @@ -0,0 +1,36 @@ +namespace ChubykinaComponents.LogicalComponents +{ + partial class ExcelImagesComponent + { + /// + /// Обязательная переменная конструктора. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Освободить все используемые ресурсы. + /// + /// истинно, если управляемый ресурс должен быть удален; иначе ложно. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Код, автоматически созданный конструктором компонентов + + /// + /// Требуемый метод для поддержки конструктора — не изменяйте + /// содержимое этого метода с помощью редактора кода. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/COP/ChubykinaComponents/LogicalComponents/ExcelImagesComponent.cs b/COP/ChubykinaComponents/LogicalComponents/ExcelImagesComponent.cs new file mode 100644 index 0000000..af5acad --- /dev/null +++ b/COP/ChubykinaComponents/LogicalComponents/ExcelImagesComponent.cs @@ -0,0 +1,77 @@ +using Microsoft.Office.Core; +using Microsoft.Office.Interop.Excel; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ChubykinaComponents.LogicalComponents +{ + public partial class ExcelImagesComponent : Component + { + public ExcelImagesComponent() + { + InitializeComponent(); + } + + public ExcelImagesComponent(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } + public bool createWithImages(ExcelImageInfo info) + { + if (string.IsNullOrEmpty(info.path) || string.IsNullOrEmpty(info.title) || info.imagePaths == null || info.imagePaths.Length == 0) + { + throw new ArgumentException("Не все поля заполнены."); + } + var excelApp = new Microsoft.Office.Interop.Excel.Application { SheetsInNewWorkbook = 1 }; + Workbook workbook = excelApp.Workbooks.Add(Type.Missing); + try + { + //create + Worksheet worksheet = (Worksheet)workbook.Worksheets.get_Item(1); + + //header + var excelcells = worksheet.get_Range("A1", "D1"); + excelcells.Merge(Type.Missing); + excelcells.Font.Bold = true; + excelcells.Font.Size = 14; + excelcells.Font.Name = "Times New Roman"; + excelcells.ColumnWidth = 8; + excelcells.RowHeight = 25; + excelcells.HorizontalAlignment = Constants.xlCenter; + excelcells.VerticalAlignment = Constants.xlCenter; + excelcells.Value2 = info.title; + + int topOffset = 25; + foreach (string path in info.imagePaths) + { + Bitmap bm = new Bitmap(path); + worksheet.Shapes.AddPicture2(path, MsoTriState.msoFalse, MsoTriState.msoCTrue, 0, topOffset, bm.Width, bm.Height, MsoPictureCompress.msoPictureCompressFalse); + topOffset += bm.Height; + bm.Dispose(); + } + + //save + object missing = System.Reflection.Missing.Value; + workbook.SaveAs(info.path, XlFileFormat.xlOpenXMLWorkbook, missing, missing, false, false, XlSaveAsAccessMode.xlNoChange, + XlSaveConflictResolution.xlUserResolution, true, missing, missing, missing); + workbook.Close(); + excelApp.Quit(); + + return true; + } + catch (Exception) + { + workbook.Close(); + excelApp.Quit(); + return false; + } + } + } +} diff --git a/COP/ChubykinaComponents/LogicalComponents/ExcelTableComponent.Designer.cs b/COP/ChubykinaComponents/LogicalComponents/ExcelTableComponent.Designer.cs new file mode 100644 index 0000000..9f0eca4 --- /dev/null +++ b/COP/ChubykinaComponents/LogicalComponents/ExcelTableComponent.Designer.cs @@ -0,0 +1,37 @@ +namespace ChubykinaComponents.LogicalComponents +{ + partial class ExcelTableComponent + { + /// + /// Обязательная переменная конструктора. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Освободить все используемые ресурсы. + /// + /// истинно, если управляемый ресурс должен быть удален; иначе ложно. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Код, автоматически созданный конструктором компонентов + + /// + /// Требуемый метод для поддержки конструктора — не изменяйте + /// содержимое этого метода с помощью редактора кода. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + } + + #endregion + } +} diff --git a/COP/ChubykinaComponents/LogicalComponents/ExcelTableComponent.cs b/COP/ChubykinaComponents/LogicalComponents/ExcelTableComponent.cs new file mode 100644 index 0000000..bbca81e --- /dev/null +++ b/COP/ChubykinaComponents/LogicalComponents/ExcelTableComponent.cs @@ -0,0 +1,193 @@ +using Microsoft.Office.Interop.Excel; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace ChubykinaComponents.LogicalComponents +{ + public partial class ExcelTableComponent : UserControl + { + public ExcelTableComponent() + { + InitializeComponent(); + } + + public ExcelTableComponent(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } + private string GetExcelColumnName(int columnNumber) + { + string columnName = ""; + + while (columnNumber > 0) + { + int modulo = (columnNumber - 1) % 26; + columnName = Convert.ToChar('A' + modulo) + columnName; + columnNumber = (columnNumber - modulo) / 26; + } + + return columnName; + } + + public bool createWithTable(string path, string title, List<(int, int)> merges, List heights, List<(string, string)> headers, List items) + { + if (merges.Count == 0 || heights.Count == 0 || headers.Count == 0 || items.Count == 0) throw new ArgumentException("Недостаточно данных"); + int[] cellsArray = new int[heights.Count]; + foreach (var merge in merges) + { + if (merge.Item1 >= merge.Item2) throw new ArgumentException("Неправильно заполнены объединения строк"); + for (int i = merge.Item1; i < merge.Item2; i++) + { + cellsArray[i]++; + } + } + foreach (int cell in cellsArray) + { + if (cell > 1) throw new ArgumentException("Объединения заходят друг на друга"); + } + + var excelApp = new Microsoft.Office.Interop.Excel.Application { SheetsInNewWorkbook = 1 }; + Workbook workbook = excelApp.Workbooks.Add(Type.Missing); + try + { + //create + Worksheet worksheet = (Worksheet)workbook.Worksheets.get_Item(1); + + //header + var excelcells = worksheet.get_Range("A1", "A1"); + excelcells.Font.Bold = true; + excelcells.Font.Size = 14; + excelcells.Font.Name = "Times New Roman"; + excelcells.ColumnWidth = 8; + excelcells.RowHeight = 25; + excelcells.HorizontalAlignment = Constants.xlCenter; + excelcells.VerticalAlignment = Constants.xlCenter; + excelcells.Value2 = title; + + //checks + List ranges = new List(); + foreach (var merge in merges) + { + ranges.Add(worksheet.get_Range("A" + (merge.Item1 + 2), "A" + (merge.Item2 + 2))); + } + + int rangeIndex = 0; + int headerIndex = 0; + List cellFields = new List(); + var type = typeof(T); + for (int i = 0; i < heights.Count; i++) + { + if (cellsArray[i] == 1) + { + //work with merge + if (!string.IsNullOrEmpty(headers[headerIndex].Item1)) throw new ArgumentException("Заголовки и объединения строк не совпадают"); + + var groupRange = ranges[rangeIndex]; + groupRange.Merge(Type.Missing); + groupRange.Font.Bold = true; + groupRange.Font.Size = 14; + groupRange.Font.Name = "Times New Roman"; + groupRange.ColumnWidth = 20; + groupRange.HorizontalAlignment = Constants.xlCenter; + groupRange.VerticalAlignment = Constants.xlCenter; + groupRange.Value2 = headers[headerIndex].Item2; + headerIndex++; + + //work with cells in merge + for (; i <= merges[rangeIndex].Item2; i++) + { + //work with cell + if (string.IsNullOrEmpty(headers[headerIndex].Item1)) throw new ArgumentException("Заголовки и объединения строк не совпадают"); + var field = type.GetField(headers[headerIndex].Item1); + if (field == null) throw new ArgumentException("В заголовках указано поле, которого нет в переданном классе"); + //format header + var range = worksheet.get_Range("B" + (i + 2), "B" + (i + 2)); + range.Font.Bold = true; + range.Font.Size = 14; + range.Font.Name = "Times New Roman"; + range.ColumnWidth = 20; + range.RowHeight = heights[i]; + range.HorizontalAlignment = Constants.xlCenter; + range.VerticalAlignment = Constants.xlCenter; + range.Value2 = headers[headerIndex].Item2; + + cellFields.Add(field); + headerIndex++; + } + i--; + rangeIndex++; + } + else + { + //work with cell + if (string.IsNullOrEmpty(headers[headerIndex].Item1)) throw new ArgumentException("Заголовки и объединения строк не совпадают"); + var field = type.GetField(headers[headerIndex].Item1); + if (field == null) throw new ArgumentException("В заголовках указано поле, которого нет в переданном классе"); + //format header + var range = worksheet.get_Range("A" + (i + 2), "B" + (i + 2)); + range.Merge(Type.Missing); + range.Font.Bold = true; + range.Font.Size = 14; + range.Font.Name = "Times New Roman"; + range.ColumnWidth = 40; + range.RowHeight = heights[i]; + range.HorizontalAlignment = Constants.xlCenter; + range.VerticalAlignment = Constants.xlCenter; + range.Value2 = headers[headerIndex].Item2; + + cellFields.Add(field); + headerIndex++; + } + } + + int columnNum = 3; + foreach (T item in items) + { + string column = GetExcelColumnName(columnNum); + int rowNum = 2; + foreach (var cellField in cellFields) + { + var range = worksheet.get_Range(column + rowNum, column + rowNum); + range.Font.Size = 14; + range.Font.Name = "Times New Roman"; + range.ColumnWidth = 20; + range.HorizontalAlignment = Constants.xlCenter; + range.VerticalAlignment = Constants.xlCenter; + range.Value2 = cellField.FieldType == typeof(bool) ? ((bool)cellField.GetValue(item) ? "Да" : "Нет") : cellField.GetValue(item); + + rowNum++; + } + columnNum++; + } + var borderRange = worksheet.get_Range("A2", GetExcelColumnName(columnNum - 1) + (headerIndex - 1)); + borderRange.Borders.LineStyle = XlLineStyle.xlContinuous; + borderRange.Borders.Weight = 2d; + + //save + object missing = System.Reflection.Missing.Value; + workbook.SaveAs(path, XlFileFormat.xlOpenXMLWorkbook, missing, missing, false, false, XlSaveAsAccessMode.xlNoChange, + XlSaveConflictResolution.xlUserResolution, true, missing, missing, missing); + workbook.Close(); + excelApp.Quit(); + + return true; + } + catch (Exception ex) + { + workbook.Close(); + excelApp.Quit(); + throw; + } + } + } +} diff --git a/COP/ChubykinaComponents/LogicalComponents/ExcelTableComponent.resx b/COP/ChubykinaComponents/LogicalComponents/ExcelTableComponent.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/COP/ChubykinaComponents/LogicalComponents/ExcelTableComponent.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/COP/ClientDataBaseImplement/ClientDataBaseImplement.csproj b/COP/ClientDataBaseImplement/ClientDataBaseImplement.csproj new file mode 100644 index 0000000..f1c0ef6 --- /dev/null +++ b/COP/ClientDataBaseImplement/ClientDataBaseImplement.csproj @@ -0,0 +1,24 @@ + + + + net6.0 + enable + enable + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + diff --git a/COP/ClientDataBaseImplement/ClientsDatabase.cs b/COP/ClientDataBaseImplement/ClientsDatabase.cs new file mode 100644 index 0000000..b687ab6 --- /dev/null +++ b/COP/ClientDataBaseImplement/ClientsDatabase.cs @@ -0,0 +1,26 @@ +using Microsoft.EntityFrameworkCore; +using ClientDataBaseImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Principal; +using System.Text; +using System.Threading.Tasks; + +namespace ClientDataBaseImplement +{ + public class ClientsDatabase : DbContext + { + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (optionsBuilder.IsConfigured == false) + { + optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-0CI5KVE\SQLEXPRESS;Initial Catalog=ClientDatabase;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); + } + base.OnConfiguring(optionsBuilder); + } + + public virtual DbSet Clients { set; get; } + public virtual DbSet Categories { set; get; } + } +} diff --git a/COP/ClientDataBaseImplement/Implements/CategoryStorage.cs b/COP/ClientDataBaseImplement/Implements/CategoryStorage.cs new file mode 100644 index 0000000..14b934b --- /dev/null +++ b/COP/ClientDataBaseImplement/Implements/CategoryStorage.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ClientsContracts.BindingModels; +using ClientsContracts.SearchModels; +using ClientsContracts.StorageContracts; +using ClientsContracts.ViewModels; +using ClientDataBaseImplement.Models; +using Microsoft.EntityFrameworkCore; +using System.Security.Principal; + +namespace ClientDataBaseImplement.Implements +{ + public class CategoryStorage : ICategoryStorage + { + public List GetFullList() + { + using var context = new ClientsDatabase(); + return context.Categories + .Select(x => x.GetViewModel) + .ToList(); + } + public List GetFilteredList(CategorySearchModel model) + { + if (!model.Id.HasValue) + { + return new(); + } + using var context = new ClientsDatabase(); + return context.Categories + .Where(x => x.Id == model.Id) + .Select(x => x.GetViewModel) + .ToList(); + } + public CategoryViewModel? GetElement(CategorySearchModel model) + { + if (!model.Id.HasValue) + { + return null; + } + using var context = new ClientsDatabase(); + return context.Categories + .FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id) + ?.GetViewModel; + } + public CategoryViewModel? Insert(CategoryBindingModel model) + { + var newCategory = Category.Create(model); + if (newCategory == null) + { + return null; + } + using var context = new ClientsDatabase(); + context.Categories.Add(newCategory); + context.SaveChanges(); + return newCategory.GetViewModel; + } + public CategoryViewModel? Update(CategoryBindingModel model) + { + using var context = new ClientsDatabase(); + var component = context.Categories.FirstOrDefault(x => x.Id == model.Id); + if (component == null) + { + return null; + } + component.Update(model); + context.SaveChanges(); + return component.GetViewModel; + } + public CategoryViewModel? Delete(CategoryBindingModel model) + { + using var context = new ClientsDatabase(); + var element = context.Categories.FirstOrDefault(rec => rec.Id == model.Id); + if (element != null) + { + context.Categories.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + } +} diff --git a/COP/ClientDataBaseImplement/Implements/ClientStorage.cs b/COP/ClientDataBaseImplement/Implements/ClientStorage.cs new file mode 100644 index 0000000..6367a59 --- /dev/null +++ b/COP/ClientDataBaseImplement/Implements/ClientStorage.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ClientsContracts.BindingModels; +using ClientsContracts.SearchModels; +using ClientsContracts.StorageContracts; +using ClientsContracts.ViewModels; +using ClientDataBaseImplement.Models; +using Microsoft.EntityFrameworkCore; +using System.Security.Principal; + +namespace ClientDataBaseImplement.Implements +{ + public class ClientStorage : IClientStorage + { + public List GetFullList() + { + using var context = new ClientsDatabase(); + return context.Clients + .Include(x => x.Category) + .Select(x => x.GetViewModel) + .ToList(); + } + public List GetFilteredList(ClientSearchModel model) + { + if (!model.Id.HasValue) + { + return new(); + } + + using var context = new ClientsDatabase(); + return context.Clients + .Include(x => x.Category) + .Where(x => x.Id == model.Id) + .Select(x => x.GetViewModel) + .ToList(); + } + public ClientViewModel? GetElement(ClientSearchModel model) + { + if (!model.Id.HasValue) + { + return null; + } + + using var context = new ClientsDatabase(); + return context.Clients + .Include(x => x.Category) + .FirstOrDefault(x => x.Id == model.Id) + ?.GetViewModel; + } + public ClientViewModel? Insert(ClientBindingModel model) + { + using var context = new ClientsDatabase(); + var newClient = Client.Create(context, model); + if (newClient == null) + { + return null; + } + context.Clients.Add(newClient); + context.SaveChanges(); + return newClient.GetViewModel; + } + public ClientViewModel? Update(ClientBindingModel model) + { + using var context = new ClientsDatabase(); + var account = context.Clients.FirstOrDefault(x => x.Id == model.Id); + if (account == null) + { + return null; + } + account.Update(model, context); + context.SaveChanges(); + return account.GetViewModel; + } + public ClientViewModel? Delete(ClientBindingModel model) + { + using var context = new ClientsDatabase(); + var element = context.Clients + .Include(x => x.Category) + .FirstOrDefault(rec => rec.Id == model.Id); + if (element != null) + { + context.Clients.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + } +} diff --git a/COP/ClientDataBaseImplement/Migrations/20241028080342_InitialCreate.Designer.cs b/COP/ClientDataBaseImplement/Migrations/20241028080342_InitialCreate.Designer.cs new file mode 100644 index 0000000..b181b10 --- /dev/null +++ b/COP/ClientDataBaseImplement/Migrations/20241028080342_InitialCreate.Designer.cs @@ -0,0 +1,87 @@ +// +using ClientDataBaseImplement; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace ClientDataBaseImplement.Migrations +{ + [DbContext(typeof(ClientsDatabase))] + [Migration("20241028080342_InitialCreate")] + partial class InitialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.20") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("ClientDataBaseImplement.Models.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("ClientDataBaseImplement.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CategoryId") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Fio") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Photo") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CategoryId"); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("ClientDataBaseImplement.Models.Client", b => + { + b.HasOne("ClientDataBaseImplement.Models.Category", "Category") + .WithMany() + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/COP/ClientDataBaseImplement/Migrations/20241028080342_InitialCreate.cs b/COP/ClientDataBaseImplement/Migrations/20241028080342_InitialCreate.cs new file mode 100644 index 0000000..cca47bb --- /dev/null +++ b/COP/ClientDataBaseImplement/Migrations/20241028080342_InitialCreate.cs @@ -0,0 +1,64 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ClientDataBaseImplement.Migrations +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Categories", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Categories", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Clients", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Fio = table.Column(type: "nvarchar(max)", nullable: false), + Email = table.Column(type: "nvarchar(max)", nullable: false), + CategoryId = table.Column(type: "int", nullable: false), + Photo = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Clients", x => x.Id); + table.ForeignKey( + name: "FK_Clients_Categories_CategoryId", + column: x => x.CategoryId, + principalTable: "Categories", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Clients_CategoryId", + table: "Clients", + column: "CategoryId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Clients"); + + migrationBuilder.DropTable( + name: "Categories"); + } + } +} diff --git a/COP/ClientDataBaseImplement/Migrations/ClientsDatabaseModelSnapshot.cs b/COP/ClientDataBaseImplement/Migrations/ClientsDatabaseModelSnapshot.cs new file mode 100644 index 0000000..1090e22 --- /dev/null +++ b/COP/ClientDataBaseImplement/Migrations/ClientsDatabaseModelSnapshot.cs @@ -0,0 +1,84 @@ +// +using ClientDataBaseImplement; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace ClientDataBaseImplement.Migrations +{ + [DbContext(typeof(ClientsDatabase))] + partial class ClientsDatabaseModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.20") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("ClientDataBaseImplement.Models.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("ClientDataBaseImplement.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CategoryId") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Fio") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Photo") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CategoryId"); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("ClientDataBaseImplement.Models.Client", b => + { + b.HasOne("ClientDataBaseImplement.Models.Category", "Category") + .WithMany() + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/COP/ClientDataBaseImplement/Models/Category.cs b/COP/ClientDataBaseImplement/Models/Category.cs new file mode 100644 index 0000000..c8a72b8 --- /dev/null +++ b/COP/ClientDataBaseImplement/Models/Category.cs @@ -0,0 +1,54 @@ +using ClientsDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Security.Principal; +using System.Text; +using System.Threading.Tasks; +using ClientsContracts.BindingModels; +using ClientsContracts.ViewModels; + +namespace ClientDataBaseImplement.Models +{ + public class Category : ICategoryModel + { + public int Id { get; private set; } + [Required] + public string Name { get; private set; } = string.Empty; + + public static Category? Create(CategoryBindingModel? model) + { + if (model == null) + { + return null; + } + return new Category() + { + Id = model.Id, + Name = model.Name, + }; + } + public static Category? Create(CategoryViewModel? model) + { + return new Category() + { + Id = model.Id, + Name = model.Name, + }; + } + public void Update(CategoryBindingModel? model) + { + if (model == null) + { + return; + } + Name = model.Name; + } + public CategoryViewModel GetViewModel => new() + { + Id = Id, + Name = Name, + }; + } +} diff --git a/COP/ClientDataBaseImplement/Models/Client.cs b/COP/ClientDataBaseImplement/Models/Client.cs new file mode 100644 index 0000000..39937cf --- /dev/null +++ b/COP/ClientDataBaseImplement/Models/Client.cs @@ -0,0 +1,68 @@ +using ClientsDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Security.Principal; +using System.Text; +using System.Threading.Tasks; +using ClientsContracts.BindingModels; +using ClientsContracts.ViewModels; + +namespace ClientDataBaseImplement.Models +{ + public class Client : IClientModel + { + [Required] + public string Fio { get; set; } = string.Empty; + [Required] + public string Email { get; set; } = string.Empty; + + public int Id { get; private set; } + + public int CategoryId { get; set; } + + public virtual Category Category { get; set; } = new(); + [Required] + public string Photo { get; set; } = string.Empty; + + public static Client? Create(ClientsDatabase context, ClientBindingModel? model) + { + if (model == null) + { + return null; + } + return new Client() + { + Id = model.Id, + Fio = model.Fio, + Email = model.Email, + CategoryId = model.CategoryId, + Category = context.Categories.First(x => x.Id == model.CategoryId), + Photo = model.Photo, + }; + } + + public void Update(ClientBindingModel? model, ClientsDatabase context) + { + if (model == null) + { + return; + } + Fio = model.Fio; + CategoryId = model.CategoryId; + Category = context.Categories.First(x => x.Id == model.CategoryId); + Photo = model.Photo; + } + + public ClientViewModel GetViewModel => new() + { + Id = Id, + Fio = Fio, + Email = Email, + CategoryId = CategoryId, + CategoryName = Category.Name, + Photo = Photo, + }; + } +} diff --git a/COP/ClientsBusinessLogics/BusinessLogics/CategoryLogic.cs b/COP/ClientsBusinessLogics/BusinessLogics/CategoryLogic.cs new file mode 100644 index 0000000..f43806c --- /dev/null +++ b/COP/ClientsBusinessLogics/BusinessLogics/CategoryLogic.cs @@ -0,0 +1,92 @@ +using ClientsContracts.BusinessLogicContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ClientsContracts.StorageContracts; +using ClientsContracts.ViewModels; +using ClientsContracts.SearchModels; +using ClientsContracts.BindingModels; + +namespace ClientsBusinessLogics.BusinessLogics +{ + public class CategoryLogic : ICategoryLogic + { + private readonly ICategoryStorage _categoryStorage; + + public CategoryLogic(ICategoryStorage categoryStorage) + { + _categoryStorage = categoryStorage; + } + + public List? ReadList(CategorySearchModel? model) + { + var list = model == null ? _categoryStorage.GetFullList() : _categoryStorage.GetFilteredList(model); + if (list == null) + { + return null; + } + return list; + } + + public CategoryViewModel? ReadElement(CategorySearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + var element = _categoryStorage.GetElement(model); + if (element == null) + { + return null; + } + return element; + } + + public bool Create(CategoryBindingModel model) + { + CheckModel(model); + if (_categoryStorage.Insert(model) == null) + { + return false; + } + return true; + } + + public bool Update(CategoryBindingModel model) + { + CheckModel(model); + if (_categoryStorage.Update(model) == null) + { + return false; + } + return true; + } + public bool Delete(CategoryBindingModel model) + { + CheckModel(model, false); + if (_categoryStorage.Delete(model) == null) + { + return false; + } + return true; + } + + private void CheckModel(CategoryBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (string.IsNullOrEmpty(model.Name)) + { + throw new ArgumentNullException("Нет названия категории", nameof(model.Name)); + } + } + } +} diff --git a/COP/ClientsBusinessLogics/BusinessLogics/ClientLogic.cs b/COP/ClientsBusinessLogics/BusinessLogics/ClientLogic.cs new file mode 100644 index 0000000..da0afee --- /dev/null +++ b/COP/ClientsBusinessLogics/BusinessLogics/ClientLogic.cs @@ -0,0 +1,96 @@ +using ClientsContracts.BusinessLogicContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ClientsContracts.StorageContracts; +using ClientsContracts.ViewModels; +using ClientsContracts.SearchModels; +using ClientsContracts.BindingModels; + +namespace ClientsBusinessLogics.BusinessLogics +{ + public class ClientLogic : IClientLogic + { + private readonly IClientStorage _clientStorage; + + public ClientLogic(IClientStorage clientStorage) + { + _clientStorage = clientStorage; + } + + public List? ReadList(ClientSearchModel? model) + { + var list = model == null ? _clientStorage.GetFullList() : _clientStorage.GetFilteredList(model); + if (list == null) + { + return null; + } + return list; + } + + public ClientViewModel? ReadElement(ClientSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + var element = _clientStorage.GetElement(model); + if (element == null) + { + return null; + } + return element; + } + + public bool Create(ClientBindingModel model) + { + CheckModel(model); + if (_clientStorage.Insert(model) == null) + { + return false; + } + return true; + } + + public bool Update(ClientBindingModel model) + { + CheckModel(model); + if (_clientStorage.Update(model) == null) + { + return false; + } + return true; + } + public bool Delete(ClientBindingModel model) + { + CheckModel(model, false); + if (_clientStorage.Delete(model) == null) + { + return false; + } + return true; + } + + private void CheckModel(ClientBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (string.IsNullOrEmpty(model.Fio)) + { + throw new ArgumentNullException("Нет имени клиента", nameof(model.Fio)); + } + if (string.IsNullOrEmpty(model.Email)) + { + throw new ArgumentNullException("Нет электронной почты пользователя", nameof(model.Email)); + } + } + } +} diff --git a/COP/ClientsBusinessLogics/ClientsBusinessLogics.csproj b/COP/ClientsBusinessLogics/ClientsBusinessLogics.csproj new file mode 100644 index 0000000..21d9b6c --- /dev/null +++ b/COP/ClientsBusinessLogics/ClientsBusinessLogics.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/COP/ClientsContracts/BindingModels/CategoryBindingModel.cs b/COP/ClientsContracts/BindingModels/CategoryBindingModel.cs new file mode 100644 index 0000000..9f1d65e --- /dev/null +++ b/COP/ClientsContracts/BindingModels/CategoryBindingModel.cs @@ -0,0 +1,16 @@ +using ClientsDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClientsContracts.BindingModels +{ + public class CategoryBindingModel : ICategoryModel + { + public string Name { get; set; } = String.Empty; + + public int Id { get; set; } + } +} diff --git a/COP/ClientsContracts/BindingModels/ClientBindingModel.cs b/COP/ClientsContracts/BindingModels/ClientBindingModel.cs new file mode 100644 index 0000000..5b01141 --- /dev/null +++ b/COP/ClientsContracts/BindingModels/ClientBindingModel.cs @@ -0,0 +1,22 @@ +using ClientsDataModels.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClientsContracts.BindingModels +{ + public class ClientBindingModel : IClientModel + { + public string Fio { get; set; } = string.Empty; + + public string Email { get; set; } = string.Empty; + + public int Id { get; set; } + + public int CategoryId { get; set; } + + public string Photo { get; set; } + } +} diff --git a/COP/ClientsContracts/BusinessLogicContracts/ICategoryLogic.cs b/COP/ClientsContracts/BusinessLogicContracts/ICategoryLogic.cs new file mode 100644 index 0000000..2433c89 --- /dev/null +++ b/COP/ClientsContracts/BusinessLogicContracts/ICategoryLogic.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ClientsContracts.ViewModels; +using ClientsContracts.SearchModels; +using ClientsContracts.BindingModels; + +namespace ClientsContracts.BusinessLogicContracts +{ + public interface ICategoryLogic + { + List? ReadList(CategorySearchModel? model); + CategoryViewModel? ReadElement(CategorySearchModel model); + bool Create(CategoryBindingModel model); + bool Update(CategoryBindingModel model); + bool Delete(CategoryBindingModel model); + } +} diff --git a/COP/ClientsContracts/BusinessLogicContracts/IClientLogic.cs b/COP/ClientsContracts/BusinessLogicContracts/IClientLogic.cs new file mode 100644 index 0000000..84ab82c --- /dev/null +++ b/COP/ClientsContracts/BusinessLogicContracts/IClientLogic.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ClientsContracts.ViewModels; +using ClientsContracts.BindingModels; +using ClientsContracts.SearchModels; + +namespace ClientsContracts.BusinessLogicContracts +{ + public interface IClientLogic + { + List? ReadList(ClientSearchModel? model); + ClientViewModel? ReadElement(ClientSearchModel model); + bool Create(ClientBindingModel model); + bool Update(ClientBindingModel model); + bool Delete(ClientBindingModel model); + } +} diff --git a/COP/ClientsContracts/ClientsContracts.csproj b/COP/ClientsContracts/ClientsContracts.csproj new file mode 100644 index 0000000..db532a4 --- /dev/null +++ b/COP/ClientsContracts/ClientsContracts.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/COP/ClientsContracts/SearchModels/CategorySearchModel.cs b/COP/ClientsContracts/SearchModels/CategorySearchModel.cs new file mode 100644 index 0000000..2bf04f8 --- /dev/null +++ b/COP/ClientsContracts/SearchModels/CategorySearchModel.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClientsContracts.SearchModels +{ + public class CategorySearchModel + { + public int? Id { get; set; } + } +} diff --git a/COP/ClientsContracts/SearchModels/ClientSearchModel.cs b/COP/ClientsContracts/SearchModels/ClientSearchModel.cs new file mode 100644 index 0000000..f37858f --- /dev/null +++ b/COP/ClientsContracts/SearchModels/ClientSearchModel.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClientsContracts.SearchModels +{ + public class ClientSearchModel + { + public int? Id { get; set; } + } +} diff --git a/COP/ClientsContracts/StorageContracts/ICategoryStorage.cs b/COP/ClientsContracts/StorageContracts/ICategoryStorage.cs new file mode 100644 index 0000000..0aae5bc --- /dev/null +++ b/COP/ClientsContracts/StorageContracts/ICategoryStorage.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ClientsContracts.ViewModels; +using ClientsContracts.BindingModels; +using ClientsContracts.SearchModels; + +namespace ClientsContracts.StorageContracts +{ + public interface ICategoryStorage + { + List GetFullList(); + List GetFilteredList(CategorySearchModel model); + CategoryViewModel? GetElement(CategorySearchModel model); + CategoryViewModel? Insert(CategoryBindingModel model); + CategoryViewModel? Update(CategoryBindingModel model); + CategoryViewModel? Delete(CategoryBindingModel model); + } +} diff --git a/COP/ClientsContracts/StorageContracts/IClientStorage.cs b/COP/ClientsContracts/StorageContracts/IClientStorage.cs new file mode 100644 index 0000000..6dcaa27 --- /dev/null +++ b/COP/ClientsContracts/StorageContracts/IClientStorage.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ClientsContracts.ViewModels; +using ClientsContracts.BindingModels; +using ClientsContracts.SearchModels; + +namespace ClientsContracts.StorageContracts +{ + public interface IClientStorage + { + List GetFullList(); + List GetFilteredList(ClientSearchModel model); + ClientViewModel? GetElement(ClientSearchModel model); + ClientViewModel? Insert(ClientBindingModel model); + ClientViewModel? Update(ClientBindingModel model); + ClientViewModel? Delete(ClientBindingModel model); + } +} diff --git a/COP/ClientsContracts/ViewModels/CategoryViewModel.cs b/COP/ClientsContracts/ViewModels/CategoryViewModel.cs new file mode 100644 index 0000000..88d04ba --- /dev/null +++ b/COP/ClientsContracts/ViewModels/CategoryViewModel.cs @@ -0,0 +1,17 @@ +using ClientsDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClientsContracts.ViewModels +{ + public class CategoryViewModel : ICategoryModel + { + [DisplayName("Название")] + public string Name { get; set; } = string.Empty; + public int Id { get; set; } + } +} diff --git a/COP/ClientsContracts/ViewModels/ClientViewModel.cs b/COP/ClientsContracts/ViewModels/ClientViewModel.cs new file mode 100644 index 0000000..85c0cb4 --- /dev/null +++ b/COP/ClientsContracts/ViewModels/ClientViewModel.cs @@ -0,0 +1,23 @@ +using ClientsContracts.BusinessLogicContracts; +using ClientsDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClientsContracts.ViewModels +{ + public class ClientViewModel : IClientModel + { + [DisplayName("ФИО")] + public string Fio { get; set; } = string.Empty; + [DisplayName("Электронная почта")] + public string Email { get; set; } = string.Empty; + public int Id { get; set; } + public int CategoryId { get; set; } + public string CategoryName { get; set; } = string.Empty; + public string Photo { get; set; } = string.Empty; + } +} diff --git a/COP/ClientsDataModels/ClientsDataModels.csproj b/COP/ClientsDataModels/ClientsDataModels.csproj new file mode 100644 index 0000000..6aa140a --- /dev/null +++ b/COP/ClientsDataModels/ClientsDataModels.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/COP/ClientsDataModels/IId.cs b/COP/ClientsDataModels/IId.cs new file mode 100644 index 0000000..9c13d93 --- /dev/null +++ b/COP/ClientsDataModels/IId.cs @@ -0,0 +1,7 @@ +namespace ClientsDataModels +{ + public interface IId + { + int Id { get; } + } +} \ No newline at end of file diff --git a/COP/ClientsDataModels/Models/ICategoryModel.cs b/COP/ClientsDataModels/Models/ICategoryModel.cs new file mode 100644 index 0000000..c89b9af --- /dev/null +++ b/COP/ClientsDataModels/Models/ICategoryModel.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClientsDataModels.Models +{ + public interface ICategoryModel : IId + { + string Name { get; } + } +} diff --git a/COP/ClientsDataModels/Models/IClientModel.cs b/COP/ClientsDataModels/Models/IClientModel.cs new file mode 100644 index 0000000..d5b98f3 --- /dev/null +++ b/COP/ClientsDataModels/Models/IClientModel.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClientsDataModels.Models +{ + public interface IClientModel : IId + { + string Fio { get; } + string Email { get; } + public int CategoryId { get; } + public string Photo { get; } + } +} diff --git a/COP/Components/Components.csproj b/COP/Components/Components.csproj index 57ac473..5ce4c2a 100644 --- a/COP/Components/Components.csproj +++ b/COP/Components/Components.csproj @@ -5,6 +5,7 @@ enable true enable + True diff --git a/COP/WinFormsTest/FormCategories.Designer.cs b/COP/WinFormsTest/FormCategories.Designer.cs new file mode 100644 index 0000000..ec75734 --- /dev/null +++ b/COP/WinFormsTest/FormCategories.Designer.cs @@ -0,0 +1,90 @@ +namespace WinFormsTest +{ + partial class FormCategories + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.dataGridView = new System.Windows.Forms.DataGridView(); + this.NameCol = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Id = new System.Windows.Forms.DataGridViewTextBoxColumn(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); + this.SuspendLayout(); + // + // dataGridView + // + this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.NameCol, + this.Id}); + this.dataGridView.Dock = System.Windows.Forms.DockStyle.Fill; + this.dataGridView.Location = new System.Drawing.Point(0, 0); + this.dataGridView.Name = "dataGridView"; + this.dataGridView.RowHeadersWidth = 51; + this.dataGridView.RowTemplate.Height = 29; + this.dataGridView.Size = new System.Drawing.Size(613, 304); + this.dataGridView.TabIndex = 0; + this.dataGridView.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellValueChanged); + this.dataGridView.UserDeletingRow += new System.Windows.Forms.DataGridViewRowCancelEventHandler(this.dataGridView_UserDeletingRow); + this.dataGridView.KeyUp += new System.Windows.Forms.KeyEventHandler(this.dataGridView_KeyUp); + // + // NameCol + // + this.NameCol.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + this.NameCol.HeaderText = "Название"; + this.NameCol.MinimumWidth = 6; + this.NameCol.Name = "NameCol"; + // + // Id + // + this.Id.HeaderText = "Id"; + this.Id.MinimumWidth = 6; + this.Id.Name = "Id"; + this.Id.Visible = false; + this.Id.Width = 125; + // + // FormCategories + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.White; + this.ClientSize = new System.Drawing.Size(613, 304); + this.Controls.Add(this.dataGridView); + this.Name = "FormCategories"; + this.Text = "Категории"; + this.Load += new System.EventHandler(this.FormCategories_Load); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private DataGridView dataGridView; + private DataGridViewTextBoxColumn NameCol; + private DataGridViewTextBoxColumn Id; + } +} \ No newline at end of file diff --git a/COP/WinFormsTest/FormCategories.cs b/COP/WinFormsTest/FormCategories.cs new file mode 100644 index 0000000..4b85409 --- /dev/null +++ b/COP/WinFormsTest/FormCategories.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using ClientsContracts.BindingModels; +using ClientsContracts.BusinessLogicContracts; + +namespace WinFormsTest +{ + public partial class FormCategories : Form + { + private readonly ICategoryLogic _logic; + private bool loading = false; + + public FormCategories(ICategoryLogic logic) + { + InitializeComponent(); + _logic = logic; + } + + private void FormCategories_Load(object sender, EventArgs e) + { + LoadData(); + } + + private void LoadData() + { + loading = true; + try + { + var list = _logic.ReadList(null); + if (list != null) + { + foreach (var interest in list) + { + int rowIndex = dataGridView.Rows.Add(); + dataGridView.Rows[rowIndex].Cells[0].Value = interest.Name; + dataGridView.Rows[rowIndex].Cells[1].Value = interest.Id; + } + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + finally + { + loading = false; + } + } + + private void dataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e) + { + if (loading || e.RowIndex < 0 || e.ColumnIndex != 0) return; + if (dataGridView.Rows[e.RowIndex].Cells[1].Value != null && !string.IsNullOrEmpty(dataGridView.Rows[e.RowIndex].Cells[1].Value.ToString())) + { + var name = dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value; + if (name is null) return; + _logic.Update(new CategoryBindingModel { Id = Convert.ToInt32(dataGridView.Rows[e.RowIndex].Cells[1].Value), Name = name.ToString() }); + } + else + { + var name = dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value; + if (name is null) return; + _logic.Create(new CategoryBindingModel { Id = 0, Name = name.ToString() }); + int newCategoryId = _logic.ReadList(null).ToList().Last().Id; + dataGridView.Rows[e.RowIndex].Cells[1].Value = newCategoryId; + } + } + + private void dataGridView_KeyUp(object sender, KeyEventArgs e) + { + switch (e.KeyCode) + { + case Keys.Insert: + dataGridView.Rows.Add(); + break; + } + } + + private void deleteRows(DataGridViewSelectedRowCollection rows) + { + for (int i = 0; i < rows.Count; i++) + { + DataGridViewRow row = rows[i]; + if (!_logic.Delete(new CategoryBindingModel { Id = Convert.ToInt32(row.Cells[1].Value) })) continue; + dataGridView.Rows.Remove(row); + } + } + + private void dataGridView_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e) + { + e.Cancel = true; + if (dataGridView.SelectedRows == null) return; + if (MessageBox.Show("Удалить записи?", "Подтвердите действие", MessageBoxButtons.YesNo) == DialogResult.No) return; + deleteRows(dataGridView.SelectedRows); + } + } +} diff --git a/COP/WinFormsTest/FormCategories.resx b/COP/WinFormsTest/FormCategories.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/COP/WinFormsTest/FormCategories.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/COP/WinFormsTest/FormClient.Designer.cs b/COP/WinFormsTest/FormClient.Designer.cs new file mode 100644 index 0000000..ff44df7 --- /dev/null +++ b/COP/WinFormsTest/FormClient.Designer.cs @@ -0,0 +1,193 @@ +namespace WinFormsTest +{ + partial class FormClient + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.textBoxLogin = new System.Windows.Forms.TextBox(); + this.textBoxPassword = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.mailControl = new BulatovaComponents.Components.UserEmailTextBox(); + this.UserCheckedListBox = new Components.Components.UserCheckedListBox(); + this.label4 = new System.Windows.Forms.Label(); + this.buttonSave = new System.Windows.Forms.Button(); + this.buttonCancel = new System.Windows.Forms.Button(); + this.openFileDialog = new System.Windows.Forms.OpenFileDialog(); + this.buttonAvatar = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 9); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(52, 20); + this.label1.TabIndex = 0; + this.label1.Text = "Логин"; + // + // textBoxLogin + // + this.textBoxLogin.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.textBoxLogin.Location = new System.Drawing.Point(12, 32); + this.textBoxLogin.Name = "textBoxLogin"; + this.textBoxLogin.Size = new System.Drawing.Size(389, 27); + this.textBoxLogin.TabIndex = 1; + // + // textBoxPassword + // + this.textBoxPassword.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.textBoxPassword.Location = new System.Drawing.Point(12, 86); + this.textBoxPassword.Name = "textBoxPassword"; + this.textBoxPassword.Size = new System.Drawing.Size(389, 27); + this.textBoxPassword.TabIndex = 3; + // + // label2 + // + this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(12, 63); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(62, 20); + this.label2.TabIndex = 2; + this.label2.Text = "Пароль"; + // + // label3 + // + this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(12, 116); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(51, 20); + this.label3.TabIndex = 4; + this.label3.Text = "Почта"; + // + // mailControl + // + this.mailControl.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.mailControl.Email = null; + this.mailControl.Location = new System.Drawing.Point(12, 139); + this.mailControl.Name = "mailControl"; + this.mailControl.Size = new System.Drawing.Size(389, 42); + this.mailControl.TabIndex = 5; + this.mailControl.validateEmailRegex = null; + // + // UserCheckedListBox + // + this.UserCheckedListBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.UserCheckedListBox.Location = new System.Drawing.Point(12, 207); + this.UserCheckedListBox.Name = "UserCheckedListBox"; + this.UserCheckedListBox.selectedItem = null; + this.UserCheckedListBox.Size = new System.Drawing.Size(389, 130); + this.UserCheckedListBox.TabIndex = 6; + // + // label4 + // + this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(12, 184); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(78, 20); + this.label4.TabIndex = 7; + this.label4.Text = "Интересы"; + // + // buttonSave + // + this.buttonSave.Location = new System.Drawing.Point(12, 420); + this.buttonSave.Name = "buttonSave"; + this.buttonSave.Size = new System.Drawing.Size(94, 29); + this.buttonSave.TabIndex = 8; + this.buttonSave.Text = "Сохранить"; + this.buttonSave.UseVisualStyleBackColor = true; + this.buttonSave.Click += new System.EventHandler(this.buttonSave_Click); + // + // buttonCancel + // + this.buttonCancel.Location = new System.Drawing.Point(307, 420); + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.Size = new System.Drawing.Size(94, 29); + this.buttonCancel.TabIndex = 9; + this.buttonCancel.Text = "Отмена"; + this.buttonCancel.UseVisualStyleBackColor = true; + this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click); + // + // openFileDialog + // + this.openFileDialog.FileName = "openFileDialog1"; + // + // buttonAvatar + // + this.buttonAvatar.Location = new System.Drawing.Point(12, 343); + this.buttonAvatar.Name = "buttonAvatar"; + this.buttonAvatar.Size = new System.Drawing.Size(389, 29); + this.buttonAvatar.TabIndex = 10; + this.buttonAvatar.Text = "Выбрать аватар"; + this.buttonAvatar.UseVisualStyleBackColor = true; + this.buttonAvatar.Click += new System.EventHandler(this.buttonAvatar_Click); + // + // FormAccount + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(413, 461); + this.Controls.Add(this.buttonAvatar); + this.Controls.Add(this.buttonCancel); + this.Controls.Add(this.buttonSave); + this.Controls.Add(this.label4); + this.Controls.Add(this.UserCheckedListBox); + this.Controls.Add(this.mailControl); + this.Controls.Add(this.label3); + this.Controls.Add(this.textBoxPassword); + this.Controls.Add(this.label2); + this.Controls.Add(this.textBoxLogin); + this.Controls.Add(this.label1); + this.Name = "FormClient"; + this.Text = "Аккаунт"; + this.Load += new System.EventHandler(this.FormClient_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private Label label1; + private TextBox textBoxLogin; + private TextBox textBoxPassword; + private Label label2; + private Label label3; + private BulatovaComponents.Components.UserEmailTextBox mailControl; + private Components.Components.UserCheckedListBox UserCheckedListBox; + private Label label4; + private Button buttonSave; + private Button buttonCancel; + private OpenFileDialog openFileDialog; + private Button buttonAvatar; + } +} \ No newline at end of file diff --git a/COP/WinFormsTest/FormClient.cs b/COP/WinFormsTest/FormClient.cs new file mode 100644 index 0000000..1cd9ff0 --- /dev/null +++ b/COP/WinFormsTest/FormClient.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using ClientsContracts.BusinessLogicContracts; +using ClientsContracts.ViewModels; +using ClientsContracts.SearchModels; +using Components.Components; +using ClientsContracts.BindingModels; + +namespace WinFormsTest +{ + public partial class FormClient : Form + { + private int? _id; + private readonly IClientLogic _logic; + private readonly ICategoryLogic _categoryLogic; + private List _categories; + private string? photo = null; + public int Id { set { _id = value; } } + + public FormClient(IClientLogic logic, ICategoryLogic categoryLogic) + { + InitializeComponent(); + _logic = logic; + _categoryLogic = categoryLogic; + _categories = new List(); + } + + private void FormClient_Load(object sender, EventArgs e) + { + _categories = _categoryLogic.ReadList(null); + UserCheckedListBox.addItems(_categories.Select(x => x.Name).ToList()); + mailControl.validateEmailRegex = new System.Text.RegularExpressions.Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$"); + mailControl.setTooltipText("name@example.com"); + if (_id.HasValue) + { + try + { + var view = _logic.ReadElement(new ClientSearchModel { Id = _id.Value }); + if (view != null) + { + textBoxLogin.Text = view.Fio; + mailControl.Email = view.Email; + photo = view.Photo; + + UserCheckedListBox.selectedItem = view.CategoryName; + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + + private void buttonCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + + private void buttonSave_Click(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(textBoxLogin.Text)) + { + MessageBox.Show("Заполните название", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (string.IsNullOrEmpty(mailControl.Email)) + { + MessageBox.Show("Заполните почту или исправьте написание почты", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (UserCheckedListBox.selectedItem == null) + { + MessageBox.Show("Заполните интересы", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + if (photo == null) + { + MessageBox.Show("Выберите аватар", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + try + { + var model = new ClientBindingModel + { + Id = _id ?? 0, + Fio = textBoxLogin.Text, + Email = mailControl.Email, + CategoryId = _categories.First(x => x.Name == UserCheckedListBox.selectedItem).Id, + Photo = photo + }; + var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model); + if (!operationResult) + { + throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); + } + MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); + DialogResult = DialogResult.OK; + Close(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void buttonAvatar_Click(object sender, EventArgs e) + { + if (openFileDialog.ShowDialog() != DialogResult.Cancel) + { + photo = openFileDialog.FileName; + } + } + } +} diff --git a/COP/WinFormsTest/FormClient.resx b/COP/WinFormsTest/FormClient.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/COP/WinFormsTest/FormClient.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/COP/WinFormsTest/FormMain.Designer.cs b/COP/WinFormsTest/FormMain.Designer.cs new file mode 100644 index 0000000..af36509 --- /dev/null +++ b/COP/WinFormsTest/FormMain.Designer.cs @@ -0,0 +1,39 @@ +namespace WinFormsTest +{ + partial class FormMain + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Text = "FormMain"; + } + + #endregion + } +} \ No newline at end of file diff --git a/COP/WinFormsTest/FormMain.cs b/COP/WinFormsTest/FormMain.cs new file mode 100644 index 0000000..4a4ff40 --- /dev/null +++ b/COP/WinFormsTest/FormMain.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace WinFormsTest +{ + public partial class FormMain : Form + { + public FormMain() + { + InitializeComponent(); + } + } +} diff --git a/COP/WinFormsTest/FormMain.resx b/COP/WinFormsTest/FormMain.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/COP/WinFormsTest/FormMain.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/COP/WinFormsTest/Program.cs b/COP/WinFormsTest/Program.cs index 58dce58..8482fd7 100644 --- a/COP/WinFormsTest/Program.cs +++ b/COP/WinFormsTest/Program.cs @@ -1,7 +1,15 @@ +using Microsoft.Extensions.DependencyInjection; +using ClientsContracts.BusinessLogicContracts; +using ClientsContracts.StorageContracts; +using ClientsBusinessLogics.BusinessLogics; +using ClientDataBaseImplement.Implements; + namespace WinFormsTest { internal static class Program { + private static ServiceProvider? _serviceProvider; + public static ServiceProvider? ServiceProvider => _serviceProvider; /// /// The main entry point for the application. /// @@ -11,7 +19,21 @@ namespace WinFormsTest // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); + var services = new ServiceCollection(); + ConfigureServices(services); + _serviceProvider = services.BuildServiceProvider(); Application.Run(new FormTest()); } + + private static void ConfigureServices(ServiceCollection services) + { + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + } } } \ No newline at end of file diff --git a/COP/WinFormsTest/WinFormsTest.csproj b/COP/WinFormsTest/WinFormsTest.csproj index a813ce4..7223cef 100644 --- a/COP/WinFormsTest/WinFormsTest.csproj +++ b/COP/WinFormsTest/WinFormsTest.csproj @@ -9,6 +9,18 @@ + + + + + all + runtime; build; native; contentfiles; analyzers; buildtrsansitive + + + + + +