Compare commits

..

No commits in common. "dev" and "LABWORK-2" have entirely different histories.

102 changed files with 224 additions and 4161 deletions

View File

@ -7,13 +7,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cop.Borovkov.Var3", "Cop.Bo
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestCustomComponents", "TestCustomComponents\TestCustomComponents.csproj", "{E2C46D08-ACCE-4547-922B-E92AD76D99C8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lab3", "Lab3\Lab3.csproj", "{1E630CC7-090F-471C-ADA1-74107CF3DC2A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lab3.Database", "Lab3.Database\Lab3.Database.csproj", "{698DE9E8-7885-4F98-AFE3-9A9C6CD2FCF5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lab4", "Lab4\Lab4.csproj", "{FAE92C0B-0A2D-48B6-A55C-DE58A310CD58}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lab4.Plugins", "Lab4.Plugins\Lab4.Plugins.csproj", "{F30C8C78-98CB-4C5E-BEE8-125791A9D7AF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PIHelperSh.PdfCreator", "PIHelperSh.PdfCreater\PIHelperSh.PdfCreator.csproj", "{572BD835-A500-43C9-A66F-648540F4A1C8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -29,22 +23,10 @@ Global
{E2C46D08-ACCE-4547-922B-E92AD76D99C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E2C46D08-ACCE-4547-922B-E92AD76D99C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E2C46D08-ACCE-4547-922B-E92AD76D99C8}.Release|Any CPU.Build.0 = Release|Any CPU
{1E630CC7-090F-471C-ADA1-74107CF3DC2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E630CC7-090F-471C-ADA1-74107CF3DC2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E630CC7-090F-471C-ADA1-74107CF3DC2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E630CC7-090F-471C-ADA1-74107CF3DC2A}.Release|Any CPU.Build.0 = Release|Any CPU
{698DE9E8-7885-4F98-AFE3-9A9C6CD2FCF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{698DE9E8-7885-4F98-AFE3-9A9C6CD2FCF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{698DE9E8-7885-4F98-AFE3-9A9C6CD2FCF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{698DE9E8-7885-4F98-AFE3-9A9C6CD2FCF5}.Release|Any CPU.Build.0 = Release|Any CPU
{FAE92C0B-0A2D-48B6-A55C-DE58A310CD58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FAE92C0B-0A2D-48B6-A55C-DE58A310CD58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FAE92C0B-0A2D-48B6-A55C-DE58A310CD58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FAE92C0B-0A2D-48B6-A55C-DE58A310CD58}.Release|Any CPU.Build.0 = Release|Any CPU
{F30C8C78-98CB-4C5E-BEE8-125791A9D7AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F30C8C78-98CB-4C5E-BEE8-125791A9D7AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F30C8C78-98CB-4C5E-BEE8-125791A9D7AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F30C8C78-98CB-4C5E-BEE8-125791A9D7AF}.Release|Any CPU.Build.0 = Release|Any CPU
{572BD835-A500-43C9-A66F-648540F4A1C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{572BD835-A500-43C9-A66F-648540F4A1C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{572BD835-A500-43C9-A66F-648540F4A1C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{572BD835-A500-43C9-A66F-648540F4A1C8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -41,7 +41,7 @@ namespace Cop.Borovkov.Var3.Components
column.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
}
_ = outDataGridView.Columns.Add(column);
outDataGridView.Columns.Add(column);
}
}
@ -108,10 +108,10 @@ namespace Cop.Borovkov.Var3.Components
Type type = typeof(TType);
for (int i = 0; i < insertValues.Count; ++i)
for (int i = 0; i < insertValues.Count(); ++i)
{
var row = insertValues[i];
_ = outDataGridView.Rows.Add();
outDataGridView.Rows.Add();
for (int j = 0; j < outDataGridView.ColumnCount; ++j)
{

View File

@ -0,0 +1,36 @@
namespace Cop.Borovkov.Var3.Components
{
partial class CustomPdfTable
{
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@ -0,0 +1,92 @@
using Cop.Borovkov.Var3.Models;
using PIHelperSh.PdfCreator;
using PIHelperSh.PdfCreator.Enums;
using PIHelperSh.PdfCreator.Interfaces;
using PIHelperSh.PdfCreator.Models.TableModels;
using System.ComponentModel;
namespace Cop.Borovkov.Var3.Components
{
/// <summary>
/// Компонент для сохранения таблицы в пдф
/// </summary>
public partial class CustomPdfTable : Component
{
/// <summary>
/// </summary>
public CustomPdfTable()
{
InitializeComponent();
}
/// <summary>
/// </summary>
/// <param name="container"></param>
public CustomPdfTable(IContainer container)
{
container.Add(this);
InitializeComponent();
}
/// <summary>
/// Сохранить набор таблиц в пдф
/// </summary>
/// <param name="fileName"></param>
/// <param name="title"></param>
/// <param name="tables"></param>
public void SaveToPdf(PdfTableInfo tableInfo)
{
if (!tableInfo.Tables.Any())
{
return;
}
PdfCreator creator = new PdfCreator();
creator.AddParagraph(new()
{
Style = PdfStyleType.Title,
Text = tableInfo.Title,
MarginAfter = PdfMargin.Smal,
});
foreach (string[,] table in tableInfo.Tables)
{
List<PDFSimpleTableRow> rows = new();
for (int i = 0; i < table.GetLength(0); ++i)
{
PDFSimpleTableRow row = new();
for (int j = 0; j < table.GetLength(1); ++j)
{
row.Items.Add(table[i, j]);
}
rows.Add(row);
}
creator.AddSimpleTable(new()
{
Header = rows.First().Items.Select(item => new PdfTableColumn()
{
Title = item,
Size = 3,
} as IPdfColumnItem).ToList(),
Rows = rows.Skip(1).ToList(),
HeaderStyle = PdfStyleType.Basic,
HeaderHorizontalAlignment = PdfAlignmentType.Left,
RowHorizontalAlignment = PdfAlignmentType.Left,
});
creator.AddParagraph(new()
{
MarginAfter = PdfMargin.Smal,
});
}
creator.SavePdf(tableInfo.FilePath);
}
}
}

View File

@ -5,28 +5,10 @@
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageId>$(AssemblyName)</PackageId>
<Version>$(VersionPrefix)8.0.2</Version>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\LICENSE" Link="PdfCreator\LICENSE">
<PackagePath>\</PackagePath>
<Pack>True</Pack>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
<PackageReference Include="PIHelperSh.Core" Version="1.0.1" />
</ItemGroup>
<ItemGroup>
<None Update="PdfCreator\README.md">
<PackagePath>\</PackagePath>
<Pack>True</Pack>
</None>
<ProjectReference Include="..\PIHelperSh.PdfCreater\PIHelperSh.PdfCreator.csproj" />
</ItemGroup>
</Project>

View File

@ -3,7 +3,7 @@
namespace Cop.Borovkov.Var3.Models
{
/// <summary>
/// Параметры для создания линейной диаграммы
/// Параметры для создания линейной диограммы
/// </summary>
public record PdfHistigramInfo
{
@ -18,7 +18,7 @@ namespace Cop.Borovkov.Var3.Models
public string DocumentTitle { get; init; } = "Гистограмма";
/// <summary>
/// Заголовок диаграммы
/// Заголовок диограммы
/// </summary>
public string HistogramTitle { get; init; } = "Гистограмма";

View File

@ -0,0 +1,23 @@
namespace Cop.Borovkov.Var3.Models
{
/// <summary>
/// Параметры для создания таблиц в пдф
/// </summary>
public record PdfTableInfo
{
/// <summary>
/// имя файла (включая путь до файла)
/// </summary>
public string FilePath { get; init; } = @"C:\pdfTable.pdf";
/// <summary>
/// название документа(заголовок в документе)
/// </summary>
public string Title { get; init; } = "Таблица";
/// <summary>
/// Список таблиц
/// </summary>
public IEnumerable<string[,]> Tables { get; init; } = [];
}
}

View File

@ -1,7 +1,7 @@
namespace Cop.Borovkov.Var3.Models
{
/// <summary>
/// Параметры для создания таблицы в пдф с группировкой по 1 столбцу
/// Параметры для создания таблици в пдф с группировкой по 1 столбцу
/// </summary>
public class PdfTableWithGroupingInfo<TType> where TType : class
{

View File

@ -1,34 +0,0 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
using Lab3.Database.Context.Configurations;
using Lab3.Database.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
#nullable disable
namespace Lab3.Database.Context;
public partial class COPContext : DbContext
{
public COPContext(DbContextOptions<COPContext> options)
: base(options)
{
}
public virtual DbSet<EducationForm> EducationForms { get; set; }
public virtual DbSet<Student> Students { get; set; }
public virtual DbSet<StudentSession> StudentSessions { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new Configurations.EducationFormConfiguration());
modelBuilder.ApplyConfiguration(new Configurations.StudentConfiguration());
modelBuilder.ApplyConfiguration(new Configurations.StudentSessionConfiguration());
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}

View File

@ -1,46 +0,0 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
#nullable disable
using Lab3.Database.Models;
using Microsoft.EntityFrameworkCore;
using Npgsql;
using System;
using System.Collections.Generic;
using System.Data;
using System.Threading;
using System.Threading.Tasks;
namespace Lab3.Database.Context
{
public partial class COPContext
{
private ICOPContextFunctions _procedures;
public virtual ICOPContextFunctions Functions
{
get
{
if (_procedures is null) _procedures = new COPContextFunctions(this);
return _procedures;
}
set
{
_procedures = value;
}
}
public ICOPContextFunctions GetFunctions()
{
return Functions;
}
}
public partial class COPContextFunctions : ICOPContextFunctions
{
private readonly COPContext _context;
public COPContextFunctions(COPContext context)
{
_context = context;
}
}
}

View File

@ -1,31 +0,0 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
using Lab3.Database.Context;
using Lab3.Database.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
namespace Lab3.Database.Context.Configurations
{
public partial class EducationFormConfiguration : IEntityTypeConfiguration<EducationForm>
{
public void Configure(EntityTypeBuilder<EducationForm> entity)
{
entity.HasKey(e => e.Id).HasName("EducationForm_pkey");
entity.ToTable("EducationForm");
entity.HasIndex(e => e.Name, "EducationForm_Name_Name1_key").IsUnique();
entity.Property(e => e.Id).ValueGeneratedNever();
entity.Property(e => e.Name)
.IsRequired()
.HasColumnType("character varying");
OnConfigurePartial(entity);
}
partial void OnConfigurePartial(EntityTypeBuilder<EducationForm> entity);
}
}

View File

@ -1,33 +0,0 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
using Lab3.Database.Context;
using Lab3.Database.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
namespace Lab3.Database.Context.Configurations
{
public partial class StudentConfiguration : IEntityTypeConfiguration<Student>
{
public void Configure(EntityTypeBuilder<Student> entity)
{
entity.HasKey(e => e.Id).HasName("Student_pkey");
entity.ToTable("Student");
entity.Property(e => e.Id).ValueGeneratedNever();
entity.Property(e => e.EducationForm)
.IsRequired()
.HasColumnType("character varying");
entity.Property(e => e.Name)
.IsRequired()
.HasColumnType("character varying");
entity.Property(e => e.StartEducation).HasColumnType("timestamp without time zone");
OnConfigurePartial(entity);
}
partial void OnConfigurePartial(EntityTypeBuilder<Student> entity);
}
}

View File

@ -1,30 +0,0 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
using Lab3.Database.Context;
using Lab3.Database.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
namespace Lab3.Database.Context.Configurations
{
public partial class StudentSessionConfiguration : IEntityTypeConfiguration<StudentSession>
{
public void Configure(EntityTypeBuilder<StudentSession> entity)
{
entity.HasKey(e => e.Id).HasName("StudentSession_pkey");
entity.ToTable("StudentSession");
entity.Property(e => e.Id).ValueGeneratedNever();
entity.HasOne(d => d.Student).WithMany(p => p.StudentSessions)
.HasForeignKey(d => d.StudentId)
.HasConstraintName("StudentSession");
OnConfigurePartial(entity);
}
partial void OnConfigurePartial(EntityTypeBuilder<StudentSession> entity);
}
}

View File

@ -1,62 +0,0 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Lab3.Database.Context
{
public static class DbContextExtensions
{
public static async Task<List<T>> SqlQueryAsync<T>(this DbContext db, string sql, object[] parameters = null, CancellationToken cancellationToken = default)
where T : class
{
if (parameters is null)
{
parameters = new object[] { };
}
if (typeof(T).GetProperties().Any())
{
return await db.Database
.SqlQueryRaw<T>(sql, parameters)
.ToListAsync(cancellationToken);
}
else
{
await db.Database.ExecuteSqlRawAsync(sql, parameters, cancellationToken);
return default;
}
}
}
public class OutputParameter<TValue>
{
private bool _valueSet = false;
public TValue _value;
public TValue Value
{
get
{
if (!_valueSet)
throw new InvalidOperationException("Value not set.");
return _value;
}
}
internal void SetValue(object value)
{
_valueSet = true;
_value = null == value || Convert.IsDBNull(value) ? default(TValue) : (TValue)value;
}
}
}

View File

@ -1,17 +0,0 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
#nullable disable
using Lab3.Database.Models;
using Microsoft.EntityFrameworkCore;
using Npgsql;
using System;
using System.Collections.Generic;
using System.Data;
using System.Threading;
using System.Threading.Tasks;
namespace Lab3.Database.Context
{
public partial interface ICOPContextFunctions
{
}
}

View File

@ -1,15 +0,0 @@
namespace Lab3.Database.DTO
{
public record StudentDTO
{
public Guid Id { get; init; }
public string Name { get; init; } = null!;
public DateTime StartEducation { get; init; }
public string EducationForm { get; init; } = null!;
public List<StudentSessionDTO> StudentSessions { get; init; } = [];
}
}

View File

@ -1,9 +0,0 @@
namespace Lab3.Database.DTO
{
public record StudentSessionDTO
{
public decimal Score { get; init; }
public int Number { get; init; }
}
}

View File

@ -1,49 +0,0 @@
using Lab3.Database.Context;
using Lab3.Database.MappingProfiles;
using Lab3.Database.Repository.Implementations;
using Lab3.Database.Repository.Interfaces;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Lab3.Database.Extensions
{
public static class DiExtension
{
public static IServiceCollection AddDatabase(
this IServiceCollection services,
IConfiguration configuration)
{
_ = services.AddDbContextPool<COPContext>(
dbContextOptions =>
{
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
_ = dbContextOptions.UseNpgsql(configuration.GetConnectionString("COPDataBase"));
_ = dbContextOptions.ConfigureWarnings(warnings => { });
}
);
return services;
}
public static IServiceCollection AddDbMapping(
this IServiceCollection services)
{
services.AddAutoMapper(typeof(StudentMappingProfile));
services.AddAutoMapper(typeof(SessionMappingProfile));
return services;
}
public static IServiceCollection AddRepositories(
this IServiceCollection services)
{
services.AddScoped<IStudentRepository, StudentRepository>();
services.AddScoped<IEducationFormRepository, EducationFormRepository>();
return services;
}
}
}

View File

@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
</ItemGroup>
</Project>

View File

@ -1,16 +0,0 @@
using AutoMapper;
using Lab3.Database.DTO;
using Lab3.Database.Models;
namespace Lab3.Database.MappingProfiles
{
public class SessionMappingProfile : Profile
{
public SessionMappingProfile()
{
_ = CreateMap<StudentSession, StudentSessionDTO>();
_ = CreateMap<StudentSessionDTO, StudentSession>()
.ForMember(s => s.Id, opt => opt.MapFrom(s => Guid.NewGuid()));
}
}
}

View File

@ -1,15 +0,0 @@
using AutoMapper;
using Lab3.Database.DTO;
using Lab3.Database.Models;
namespace Lab3.Database.MappingProfiles
{
public class StudentMappingProfile : Profile
{
public StudentMappingProfile()
{
_ = CreateMap<Student, StudentDTO>();
_ = CreateMap<StudentDTO, Student>();
}
}
}

View File

@ -1,13 +0,0 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
#nullable disable
using System;
using System.Collections.Generic;
namespace Lab3.Database.Models;
public partial class EducationForm
{
public Guid Id { get; set; }
public string Name { get; set; }
}

View File

@ -1,19 +0,0 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
#nullable disable
using System;
using System.Collections.Generic;
namespace Lab3.Database.Models;
public partial class Student
{
public Guid Id { get; set; }
public string Name { get; set; }
public DateTime StartEducation { get; set; }
public string EducationForm { get; set; }
public virtual ICollection<StudentSession> StudentSessions { get; set; } = new List<StudentSession>();
}

View File

@ -1,19 +0,0 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
#nullable disable
using System;
using System.Collections.Generic;
namespace Lab3.Database.Models;
public partial class StudentSession
{
public Guid Id { get; set; }
public Guid StudentId { get; set; }
public decimal Score { get; set; }
public int Number { get; set; }
public virtual Student Student { get; set; }
}

View File

@ -1,35 +0,0 @@
using Lab3.Database.Context;
using Lab3.Database.Models;
using Lab3.Database.Repository.Interfaces;
using Microsoft.EntityFrameworkCore;
namespace Lab3.Database.Repository.Implementations
{
public class EducationFormRepository : IEducationFormRepository
{
private readonly COPContext _context;
public EducationFormRepository(COPContext context)
{
_context = context;
}
public async Task<IEnumerable<string>> Get()
{
return await _context.EducationForms
.Select(f => f.Name)
.ToListAsync();
}
public async Task Update(IEnumerable<string> educationForms)
{
await _context.EducationForms.ExecuteDeleteAsync();
await _context.EducationForms.AddRangeAsync(educationForms.Select(f => new EducationForm()
{
Id = Guid.NewGuid(),
Name = f,
}));
await _context.SaveChangesAsync();
}
}
}

View File

@ -1,89 +0,0 @@
using AutoMapper;
using Lab3.Database.Context;
using Lab3.Database.DTO;
using Lab3.Database.Models;
using Lab3.Database.Repository.Interfaces;
using Microsoft.EntityFrameworkCore;
namespace Lab3.Database.Repository.Implementations
{
public class StudentRepository : IStudentRepository
{
private readonly IMapper _mapper;
private readonly COPContext _context;
public StudentRepository(IMapper mapper, COPContext context)
{
_mapper = mapper;
_context = context;
}
public async Task<StudentDTO> CreateAsync(StudentDTO studentDTO)
{
var student = _mapper.Map<Student>(studentDTO);
var result = await _context.Students.AddAsync(student);
await _context.SaveChangesAsync();
return _mapper.Map<StudentDTO>(result.Entity);
}
public async Task<StudentDTO?> DeleteAsync(Guid id)
{
var student = await _context.Students.FindAsync(id);
if (student == null)
{
return null;
}
var result = _context.Students.Remove(student);
await _context.SaveChangesAsync();
return _mapper.Map<StudentDTO>(result.Entity);
}
public async Task<List<StudentDTO>> GetAsync(int limit = 10000, int offset = 0)
=> _mapper.Map<List<StudentDTO>>(
await _context.Students
.Include(s => s.StudentSessions)
.Skip(offset)
.Take(limit)
.ToListAsync());
public async Task<StudentDTO?> GetAsync(Guid id)
{
return _mapper.Map<StudentDTO>(
await _context.Students
.Include(s => s.StudentSessions)
.FirstOrDefaultAsync(s =>s.Id == id));
}
public async Task<StudentDTO?> UpdateAsync(StudentDTO studentDTO)
{
var student = _mapper.Map<Student>(studentDTO);
var currStudent = await _context.Students.FindAsync(student.Id);
if (currStudent == null)
{
return null;
}
currStudent.Name = student.Name;
currStudent.StartEducation = student.StartEducation;
currStudent.EducationForm = student.EducationForm;
foreach (var session in currStudent.StudentSessions)
{
session.Score = student.StudentSessions
.FirstOrDefault(s => s.Number == session.Number)?.Score ?? session.Score;
}
await _context.SaveChangesAsync();
return _mapper.Map<StudentDTO>(currStudent);
}
}
}

View File

@ -1,9 +0,0 @@
namespace Lab3.Database.Repository.Interfaces
{
public interface IEducationFormRepository
{
Task<IEnumerable<string>> Get();
Task Update(IEnumerable<string> educationForms);
}
}

View File

@ -1,17 +0,0 @@
using Lab3.Database.DTO;
namespace Lab3.Database.Repository.Interfaces
{
public interface IStudentRepository
{
Task<List<StudentDTO>> GetAsync(int limit = 10000, int offset = 0);
Task<StudentDTO?> GetAsync(Guid id);
Task<StudentDTO?> UpdateAsync(StudentDTO studentDTO);
Task<StudentDTO?> DeleteAsync(Guid id);
Task<StudentDTO> CreateAsync(StudentDTO studentDTO);
}
}

View File

@ -1,54 +0,0 @@
{
"CodeGenerationMode": 4,
"ContextClassName": "COPContext",
"ContextNamespace": "Context",
"FilterSchemas": false,
"IncludeConnectionString": false,
"ModelNamespace": "Models",
"OutputContextPath": "Context",
"OutputPath": "Models",
"PreserveCasingWithRegex": true,
"ProjectRootNamespace": "Lab3.Database",
"Schemas": null,
"SelectedHandlebarsLanguage": 2,
"SelectedToBeGenerated": 0,
"T4TemplatePath": null,
"Tables": [
{
"Name": "public.EducationForm",
"ObjectType": 0
},
{
"Name": "public.Student",
"ObjectType": 0
},
{
"Name": "public.StudentSession",
"ObjectType": 0
}
],
"UiHint": null,
"UncountableWords": null,
"UseAsyncStoredProcedureCalls": true,
"UseBoolPropertiesWithoutDefaultSql": false,
"UseDatabaseNames": false,
"UseDateOnlyTimeOnly": true,
"UseDbContextSplitting": true,
"UseDecimalDataAnnotationForSprocResult": true,
"UseFluentApiOnly": true,
"UseHandleBars": false,
"UseHierarchyId": false,
"UseInflector": true,
"UseLegacyPluralizer": false,
"UseManyToManyEntity": false,
"UseNoDefaultConstructor": true,
"UseNoNavigations": false,
"UseNoObjectFilter": true,
"UseNodaTime": false,
"UseNullableReferences": false,
"UsePrefixNavigationNaming": false,
"UseSchemaFolders": false,
"UseSchemaNamespaces": false,
"UseSpatial": false,
"UseT4": false
}

View File

@ -1,48 +0,0 @@
using DocumentFormat.OpenXml.Office2010.Excel;
using Lab3.Database.Extensions;
using Lab3.Database.Repository.Interfaces;
using Lab3.Forms;
using Lab3.MappingProfiles;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Lab3.Extensions
{
public static class DIExtension
{
public static IServiceCollection ConfigureDAL(
this IServiceCollection services,
IConfiguration configuration)
{
services.AddDatabase(configuration);
services.AddDbMapping();
services.AddRepositories();
return services;
}
public static IServiceCollection AddLab3Forms(
this IServiceCollection services)
{
services.AddScoped<MainForm>();
services.AddScoped<CatalogForm>();
services.AddScoped<Func<Guid?, CreateForm>>(sp => (id
=> new CreateForm(
sp.GetRequiredService<IStudentRepository>(),
sp.GetRequiredService<IEducationFormRepository>(),
id
)));
return services;
}
public static IServiceCollection AddMapping(
this IServiceCollection services)
{
services.AddAutoMapper(typeof(StudentViewMappingProfile));
return services;
}
}
}

View File

@ -1,76 +0,0 @@
namespace Lab3.Forms
{
partial class CatalogForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
Catalog = new DataGridView();
EducationForm = new DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)Catalog).BeginInit();
SuspendLayout();
//
// Catalog
//
Catalog.AllowUserToAddRows = false;
Catalog.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
Catalog.Columns.AddRange(new DataGridViewColumn[] { EducationForm });
Catalog.Dock = DockStyle.Fill;
Catalog.Location = new Point(0, 0);
Catalog.Name = "Catalog";
Catalog.RowHeadersWidth = 51;
Catalog.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
Catalog.Size = new Size(800, 450);
Catalog.TabIndex = 0;
Catalog.CellEndEdit += Catalog_CellEndEditAsync;
Catalog.KeyDown += Catalog_KeyDownAsync;
//
// EducationForm
//
EducationForm.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
EducationForm.HeaderText = "Форма обучения";
EducationForm.MinimumWidth = 6;
EducationForm.Name = "EducationForm";
//
// CatalogForm
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(Catalog);
Name = "CatalogForm";
Text = "CatalogForm";
Load += CatalogForm_LoadAsync;
((System.ComponentModel.ISupportInitialize)Catalog).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView Catalog;
private DataGridViewTextBoxColumn EducationForm;
}
}

View File

@ -1,97 +0,0 @@
using Lab3.Database.Repository.Interfaces;
namespace Lab3.Forms
{
public partial class CatalogForm : Form
{
private readonly IEducationFormRepository _repository;
public CatalogForm(IEducationFormRepository educationFormRepository)
{
_repository = educationFormRepository;
InitializeComponent();
}
private async void CatalogForm_LoadAsync(object sender, EventArgs e)
{
Catalog.Rows.Clear();
var values = (await _repository.Get()).ToList();
for (int i = 0; i < values.Count; i++)
{
_ = Catalog.Rows.Add();
Catalog.Rows[i].Cells[0].Value = values[i];
}
}
private async void Catalog_CellEndEditAsync(object sender, DataGridViewCellEventArgs e)
{
await LoadAsync();
}
private async Task LoadAsync()
{
try
{
List<string> values = new List<string>();
for (int i = 0; i < Catalog.Rows.Count; ++i)
{
string? val = (string?)Catalog.Rows[i].Cells[0].Value;
if (string.IsNullOrEmpty(val))
{
_ = MessageBox.Show(
"Неверные данные",
"Ошибка",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
values.Add(val);
}
await _repository.Update(values);
}
catch (Exception ex)
{
_ = MessageBox.Show(
ex.Message,
"Ошибка",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
private async void Catalog_KeyDownAsync(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Insert)
{
_ = Catalog.Rows.Add();
}
if (e.KeyCode == Keys.Delete && Catalog.SelectedRows.Count == 1)
{
if (MessageBox.Show(
"Удалить?",
"Удаление",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question) == DialogResult.Yes)
{
try
{
Catalog.Rows.RemoveAt(Catalog.SelectedRows[0].Index);
await LoadAsync();
}
catch (Exception ex)
{
_ = MessageBox.Show(
ex.Message,
"Ошибка",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
}
}
}

View File

@ -1,123 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="EducationForm.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@ -1,317 +0,0 @@
namespace Lab3.Forms
{
partial class CreateForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
StartEducationDataPicker = new CustomsComponentsVar2.CustomDateTimePicker();
FormSelector = new ComponentsLab.VisualSelectionComponent();
label1 = new Label();
label2 = new Label();
NameTextBox = new TextBox();
label3 = new Label();
session1Score = new NumericUpDown();
label4 = new Label();
label5 = new Label();
label6 = new Label();
session2Score = new NumericUpDown();
label7 = new Label();
session3Score = new NumericUpDown();
label8 = new Label();
session6Score = new NumericUpDown();
label9 = new Label();
session5Score = new NumericUpDown();
label10 = new Label();
session4Score = new NumericUpDown();
ButtonSave = new Button();
buttonCancel = new Button();
((System.ComponentModel.ISupportInitialize)session1Score).BeginInit();
((System.ComponentModel.ISupportInitialize)session2Score).BeginInit();
((System.ComponentModel.ISupportInitialize)session3Score).BeginInit();
((System.ComponentModel.ISupportInitialize)session6Score).BeginInit();
((System.ComponentModel.ISupportInitialize)session5Score).BeginInit();
((System.ComponentModel.ISupportInitialize)session4Score).BeginInit();
SuspendLayout();
//
// StartEducationDataPicker
//
StartEducationDataPicker.Location = new Point(430, 32);
StartEducationDataPicker.Name = "StartEducationDataPicker";
StartEducationDataPicker.Size = new Size(456, 55);
StartEducationDataPicker.TabIndex = 0;
StartEducationDataPicker.Value = new DateTime(2024, 11, 6, 22, 54, 54, 353);
//
// FormSelector
//
FormSelector.BorderStyle = BorderStyle.FixedSingle;
FormSelector.ComboBoxSelectedValue = "";
FormSelector.Location = new Point(436, 133);
FormSelector.Margin = new Padding(3, 4, 3, 4);
FormSelector.Name = "FormSelector";
FormSelector.Size = new Size(352, 31);
FormSelector.TabIndex = 1;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(430, 9);
label1.Name = "label1";
label1.Size = new Size(134, 20);
label1.TabIndex = 2;
label1.Text = "Дата поступления";
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(436, 101);
label2.Name = "label2";
label2.Size = new Size(128, 20);
label2.TabIndex = 3;
label2.Text = "Форма обучения";
//
// NameTextBox
//
NameTextBox.Location = new Point(12, 60);
NameTextBox.Name = "NameTextBox";
NameTextBox.Size = new Size(315, 27);
NameTextBox.TabIndex = 4;
//
// label3
//
label3.AutoSize = true;
label3.Location = new Point(12, 18);
label3.Name = "label3";
label3.Size = new Size(42, 20);
label3.TabIndex = 5;
label3.Text = "ФИО";
//
// session1Score
//
session1Score.DecimalPlaces = 2;
session1Score.Increment = new decimal(new int[] { 1, 0, 0, 131072 });
session1Score.Location = new Point(12, 156);
session1Score.Maximum = new decimal(new int[] { 5, 0, 0, 0 });
session1Score.Name = "session1Score";
session1Score.Size = new Size(150, 27);
session1Score.TabIndex = 6;
//
// label4
//
label4.AutoSize = true;
label4.Location = new Point(12, 101);
label4.Name = "label4";
label4.Size = new Size(107, 20);
label4.TabIndex = 7;
label4.Text = "Успеваемость";
//
// label5
//
label5.AutoSize = true;
label5.Location = new Point(12, 133);
label5.Name = "label5";
label5.Size = new Size(65, 20);
label5.TabIndex = 8;
label5.Text = "Сессия1";
//
// label6
//
label6.AutoSize = true;
label6.Location = new Point(12, 188);
label6.Name = "label6";
label6.Size = new Size(65, 20);
label6.TabIndex = 10;
label6.Text = "Сессия2";
//
// session2Score
//
session2Score.DecimalPlaces = 2;
session2Score.Increment = new decimal(new int[] { 1, 0, 0, 131072 });
session2Score.Location = new Point(12, 211);
session2Score.Maximum = new decimal(new int[] { 5, 0, 0, 0 });
session2Score.Name = "session2Score";
session2Score.Size = new Size(150, 27);
session2Score.TabIndex = 9;
//
// label7
//
label7.AutoSize = true;
label7.Location = new Point(12, 247);
label7.Name = "label7";
label7.Size = new Size(65, 20);
label7.TabIndex = 12;
label7.Text = "Сессия3";
//
// session3Score
//
session3Score.DecimalPlaces = 2;
session3Score.Increment = new decimal(new int[] { 1, 0, 0, 131072 });
session3Score.Location = new Point(12, 270);
session3Score.Maximum = new decimal(new int[] { 5, 0, 0, 0 });
session3Score.Name = "session3Score";
session3Score.Size = new Size(150, 27);
session3Score.TabIndex = 11;
//
// label8
//
label8.AutoSize = true;
label8.Location = new Point(177, 247);
label8.Name = "label8";
label8.Size = new Size(65, 20);
label8.TabIndex = 18;
label8.Text = "Сессия6";
//
// session6Score
//
session6Score.DecimalPlaces = 2;
session6Score.Increment = new decimal(new int[] { 1, 0, 0, 131072 });
session6Score.Location = new Point(177, 270);
session6Score.Maximum = new decimal(new int[] { 5, 0, 0, 0 });
session6Score.Name = "session6Score";
session6Score.Size = new Size(150, 27);
session6Score.TabIndex = 17;
//
// label9
//
label9.AutoSize = true;
label9.Location = new Point(177, 188);
label9.Name = "label9";
label9.Size = new Size(65, 20);
label9.TabIndex = 16;
label9.Text = "Сессия5";
//
// session5Score
//
session5Score.DecimalPlaces = 2;
session5Score.Increment = new decimal(new int[] { 1, 0, 0, 131072 });
session5Score.Location = new Point(177, 211);
session5Score.Maximum = new decimal(new int[] { 5, 0, 0, 0 });
session5Score.Name = "session5Score";
session5Score.Size = new Size(150, 27);
session5Score.TabIndex = 15;
//
// label10
//
label10.AutoSize = true;
label10.Location = new Point(177, 133);
label10.Name = "label10";
label10.Size = new Size(65, 20);
label10.TabIndex = 14;
label10.Text = "Сессия4";
//
// session4Score
//
session4Score.DecimalPlaces = 2;
session4Score.Increment = new decimal(new int[] { 1, 0, 0, 131072 });
session4Score.Location = new Point(177, 156);
session4Score.Maximum = new decimal(new int[] { 5, 0, 0, 0 });
session4Score.Name = "session4Score";
session4Score.Size = new Size(150, 27);
session4Score.TabIndex = 13;
//
// ButtonSave
//
ButtonSave.Location = new Point(430, 258);
ButtonSave.Name = "ButtonSave";
ButtonSave.Size = new Size(164, 39);
ButtonSave.TabIndex = 19;
ButtonSave.Text = "Сохранить";
ButtonSave.UseVisualStyleBackColor = true;
ButtonSave.Click += ButtonSave_ClickAsync;
//
// buttonCancel
//
buttonCancel.Location = new Point(624, 258);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(164, 39);
buttonCancel.TabIndex = 20;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
//
// CreateForm
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 309);
Controls.Add(buttonCancel);
Controls.Add(ButtonSave);
Controls.Add(label8);
Controls.Add(session6Score);
Controls.Add(label9);
Controls.Add(session5Score);
Controls.Add(label10);
Controls.Add(session4Score);
Controls.Add(label7);
Controls.Add(session3Score);
Controls.Add(label6);
Controls.Add(session2Score);
Controls.Add(label5);
Controls.Add(label4);
Controls.Add(session1Score);
Controls.Add(label3);
Controls.Add(NameTextBox);
Controls.Add(label2);
Controls.Add(label1);
Controls.Add(StartEducationDataPicker);
Controls.Add(FormSelector);
Name = "CreateForm";
Text = "CreateForm";
Load += CreateForm_LoadAsync;
((System.ComponentModel.ISupportInitialize)session1Score).EndInit();
((System.ComponentModel.ISupportInitialize)session2Score).EndInit();
((System.ComponentModel.ISupportInitialize)session3Score).EndInit();
((System.ComponentModel.ISupportInitialize)session6Score).EndInit();
((System.ComponentModel.ISupportInitialize)session5Score).EndInit();
((System.ComponentModel.ISupportInitialize)session4Score).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private CustomsComponentsVar2.CustomDateTimePicker StartEducationDataPicker;
private ComponentsLab.VisualSelectionComponent FormSelector;
private Label label1;
private Label label2;
private TextBox NameTextBox;
private Label label3;
private NumericUpDown session1Score;
private Label label4;
private Label label5;
private Label label6;
private NumericUpDown session2Score;
private Label label7;
private NumericUpDown session3Score;
private Label label8;
private NumericUpDown session6Score;
private Label label9;
private NumericUpDown session5Score;
private Label label10;
private NumericUpDown session4Score;
private Button ButtonSave;
private Button buttonCancel;
}
}

View File

@ -1,118 +0,0 @@
using Lab3.Database.DTO;
using Lab3.Database.Models;
using Lab3.Database.Repository.Interfaces;
namespace Lab3.Forms
{
public partial class CreateForm : Form
{
private readonly IStudentRepository _studentRepository;
private readonly IEducationFormRepository _educationFormRepository;
private readonly Guid? _updatedStudentGuid = null;
public CreateForm(
IStudentRepository studentRepository,
IEducationFormRepository educationFormRepository,
Guid? updatedStudentGuid)
{
_studentRepository = studentRepository;
_educationFormRepository = educationFormRepository;
_updatedStudentGuid = updatedStudentGuid;
InitializeComponent();
}
private async void CreateForm_LoadAsync(object sender, EventArgs e)
{
FormSelector.Fill(await _educationFormRepository.Get());
StartEducationDataPicker.DateStart = DateTime.Now.AddYears(-6);
StartEducationDataPicker.DateEnd = DateTime.Now;
if (_updatedStudentGuid == null)
{
return;
}
var student = await _studentRepository.GetAsync(_updatedStudentGuid.Value);
NameTextBox.Text = student!.Name;
StartEducationDataPicker.Value = student.StartEducation;
FormSelector.ComboBoxSelectedValue = student.EducationForm;
session1Score.Value = student.StudentSessions
.FirstOrDefault(s => s.Number == 1)?.Score ?? decimal.Zero;
session2Score.Value = student.StudentSessions
.FirstOrDefault(s => s.Number == 2)?.Score ?? decimal.Zero;
session3Score.Value = student.StudentSessions
.FirstOrDefault(s => s.Number == 3)?.Score ?? decimal.Zero;
session4Score.Value = student.StudentSessions
.FirstOrDefault(s => s.Number == 4)?.Score ?? decimal.Zero;
session5Score.Value = student.StudentSessions
.FirstOrDefault(s => s.Number == 5)?.Score ?? decimal.Zero;
session6Score.Value = student.StudentSessions
.FirstOrDefault(s => s.Number == 6)?.Score ?? decimal.Zero;
}
private async void ButtonSave_ClickAsync(object sender, EventArgs e)
{
try
{
if (string.IsNullOrEmpty(NameTextBox.Text)
|| string.IsNullOrEmpty(FormSelector.ComboBoxSelectedValue))
{
throw new Exception();
}
StudentDTO student = new()
{
Id = _updatedStudentGuid ?? Guid.NewGuid(),
Name = NameTextBox.Text,
StartEducation = StartEducationDataPicker.Value,
EducationForm = FormSelector.ComboBoxSelectedValue,
StudentSessions = [
new(){
Score = session1Score.Value,
Number = 1,
},
new(){
Score = session2Score.Value,
Number = 2,
},
new(){
Score = session3Score.Value,
Number = 3,
},
new(){
Score = session4Score.Value,
Number = 4,
},
new(){
Score = session5Score.Value,
Number = 5,
},
new(){
Score = session6Score.Value,
Number = 6,
},
],
};
if (_updatedStudentGuid != null)
{
_ = await _studentRepository.UpdateAsync(student);
}
else
{
_ = await _studentRepository.CreateAsync(student);
}
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,66 +0,0 @@
namespace Lab3.Forms
{
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
StudentsListBox = new Cop.Borovkov.Var3.Components.CustomListBox();
SimpleTableCreator = new Cop.Borovkov.Var3.Components.CustomPdfTable(components);
ExcelTableCreator = new CustomComponentsVar2.CustomExcelTable(components);
WordDiogramCreator = new ComponentsLibrary.ComponentDiagram(components);
SuspendLayout();
//
// StudentsListBox
//
StudentsListBox.Dock = DockStyle.Fill;
StudentsListBox.Location = new Point(0, 0);
StudentsListBox.Name = "StudentsListBox";
StudentsListBox.Selected = "";
StudentsListBox.Size = new Size(800, 450);
StudentsListBox.TabIndex = 0;
//
// MainForm
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(StudentsListBox);
Name = "MainForm";
Text = "MainForm";
Load += MainForm_LoadAsync;
ResumeLayout(false);
}
#endregion
private Cop.Borovkov.Var3.Components.CustomListBox StudentsListBox;
private Cop.Borovkov.Var3.Components.CustomPdfTable SimpleTableCreator;
private CustomComponentsVar2.CustomExcelTable ExcelTableCreator;
private ComponentsLibrary.ComponentDiagram WordDiogramCreator;
}
}

View File

@ -1,265 +0,0 @@
using AutoMapper;
using ComponentsLibrary.entities;
using ComponentsLibrary.entities.enums;
using Lab3.Database.DTO;
using Lab3.Database.Repository.Interfaces;
using Lab3.Models;
namespace Lab3.Forms
{
public partial class MainForm : Form
{
private readonly IStudentRepository _studentRepository;
private readonly IMapper _mapper;
private readonly Func<Guid?, CreateForm> _getCreateOrUpdateForm;
private readonly CatalogForm _catalogForm;
private bool _cont = false;
public MainForm(
IStudentRepository repository,
IMapper mapper,
Func<Guid?, CreateForm> getCreateOrUpdateForm,
CatalogForm catalogForm)
{
_studentRepository = repository;
_mapper = mapper;
_getCreateOrUpdateForm = getCreateOrUpdateForm;
_catalogForm = catalogForm;
InitializeComponent();
}
private void MainForm_LoadAsync(object sender, EventArgs e)
{
LoadAsync();
}
private async void LoadAsync()
{
try
{
var students = _mapper.Map<List<StudentViewModel>>(await _studentRepository.GetAsync());
StudentsListBox.FillValues(
students.Select(s => string.Join(" ",
[
s.Id,
s.Name,
s.EducationForm,
s.StartEducation.ToLongDateString(),
s.SessionMarks,
]
))
);
}
catch (Exception ex)
{
MessageBox.Show(
ex.Message,
"Ошибка",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
private async void RemoveStudentAsync()
{
if (MessageBox.Show("Удалить запись", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
try
{
await _studentRepository
.DeleteAsync(Guid.Parse(StudentsListBox.Selected.Split()[0]));
LoadAsync();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private async void CreateSimpleDocAsync()
{
try
{
using var saveFileDialog = new SaveFileDialog
{
Filter = "pdf|*.pdf"
};
if (saveFileDialog.ShowDialog() != DialogResult.OK)
{
return;
}
var values = (await _studentRepository.GetAsync())
.Select(s => s.StudentSessions
.OrderBy(x => x.Number)
.Select(x => x.Score.ToString())
.ToArray())
.ToArray();
var tables = new string[values.Length, 6];
for (int i = 0; i < values.Length; ++i)
{
for (int j = 0; j < 6; ++j)
{
tables[i, j] = values[i][j];
}
}
SimpleTableCreator.SaveToPdf(new()
{
FilePath = saveFileDialog.FileName,
Title = "Сессии",
Tables = [tables]
});
_ = MessageBox.Show("Простой документ сформирован",
"Успешный результат",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
catch (Exception ex)
{
_ = MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private async void CreateTableAsync()
{
try
{
using var saveFileDialog = new SaveFileDialog
{
Filter = "xlsx|*.xlsx"
};
if (saveFileDialog.ShowDialog() != DialogResult.OK)
{
return;
}
ExcelTableCreator.SaveToExcel<StudentDTO>(new()
{
FilePath = saveFileDialog.FileName,
Title = "Студенты",
Headers =
[
("Id", nameof(StudentDTO.Id)),
("ФИО", nameof(StudentDTO.Name)),
("Форма обучения", nameof(StudentDTO.EducationForm)),
("Дата поступления", nameof(StudentDTO.StartEducation)),
],
HeaderGroups = [new() {
GroupHeader = "Образование",
FirstHeader = 2,
LastHeader = 3,
}],
Values = await _studentRepository.GetAsync()
});
_ = MessageBox.Show("Документ с таблицей сформирован",
"Успешный результат",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
catch (Exception ex)
{
_ = MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private async void CreateWordDocAsync()
{
try
{
using var saveFileDialog = new SaveFileDialog
{
Filter = "docx|*.docx"
};
if (saveFileDialog.ShowDialog() != DialogResult.OK)
{
return;
}
var data = (await _studentRepository.GetAsync())
.GroupBy(s => s.EducationForm)
.Select(s => new DataLine(
s.Key,
s.GroupBy(x => x.StartEducation.Year)
.Select(x => (year: x.Key.ToString(), count: (double)x.Count()))
.ToArray()))
.ToList();
WordDiogramCreator.AddDiagram(
new(
saveFileDialog.FileName,
"Поступления",
"Диаграмма",
EnumAreaLegend.Bottom,
data
)
);
_ = MessageBox.Show("Документ с диаграммой сформирован",
"Успешный результат",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
catch (Exception ex)
{
_ = MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.ControlKey | Keys.Control)) _cont = true;
if (_cont && keyData == Keys.A)
{
_getCreateOrUpdateForm(null).ShowDialog(this);
LoadAsync();
}
else if (_cont && keyData == Keys.U)
{
var elem = StudentsListBox.Selected;
_getCreateOrUpdateForm(
Guid.Parse(elem.Split()[0])
).ShowDialog(this);
LoadAsync();
}
else if (_cont && keyData == Keys.D)
{
RemoveStudentAsync();
}
else if (_cont && keyData == Keys.S)
{
CreateSimpleDocAsync();
}
else if (_cont && keyData == Keys.T)
{
CreateTableAsync();
}
else if (_cont && keyData == Keys.C)
{
CreateWordDocAsync();
}
else if (_cont && keyData == Keys.G)
{
_catalogForm.ShowDialog(this);
}
if (keyData == Keys.A ||
keyData == Keys.U ||
keyData == Keys.D ||
keyData == Keys.S ||
keyData == Keys.T ||
keyData == Keys.C ||
keyData == Keys.G) _cont = false;
return true;
}
}
}

View File

@ -1,129 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="SimpleTableCreator.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="ExcelTableCreator.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>203, 17</value>
</metadata>
<metadata name="WordDiogramCreator.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>377, 17</value>
</metadata>
</root>

View File

@ -1,33 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<Folder Include="Logic\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="ComponentsLibraryLab1" Version="8.0.2" />
<PackageReference Include="ComponentsLibraryLab2" Version="8.0.1" />
<PackageReference Include="Cop.Borovkov.Var3" Version="8.0.2" />
<PackageReference Include="CustomComponentsVar2" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Lab3.Database\Lab3.Database.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -1,15 +0,0 @@
using AutoMapper;
using Lab3.Database.DTO;
using Lab3.Models;
namespace Lab3.MappingProfiles
{
public class StudentViewMappingProfile : Profile
{
public StudentViewMappingProfile()
{
_ = CreateMap<StudentDTO, StudentViewModel>()
;
}
}
}

View File

@ -1,11 +0,0 @@
using Lab3.Database.DTO;
namespace Lab3.Models
{
public record StudentViewModel : StudentDTO
{
public string SessionMarks => string.Join("; ", StudentSessions
.OrderBy(s => s.Number)
.Select(s => $"сессия{s.Number:d}: {s.Score:n2}"));
}
}

View File

@ -1,41 +0,0 @@
using Lab3.Extensions;
using Lab3.Forms;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace Lab3
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
var app = CreateHostBuilder().Build();
Application.Run(app.Services.GetRequiredService<MainForm>());
}
static IHostBuilder CreateHostBuilder()
{
return Host.CreateDefaultBuilder()
.ConfigureAppConfiguration(c
=> c.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true))
.ConfigureServices((context, services) => {
services.ConfigureDAL(context.Configuration);
services.AddMapping();
services.AddLab3Forms();
});
}
}
}

View File

@ -1,5 +0,0 @@
{
"ConnectionStrings": {
"COPDataBase": "Host=localhost;Username=postgres;Password=postgres;Database=COP"
}
}

View File

@ -1,20 +0,0 @@
using Lab4.Interfaces;
using Lab4.Plugins.Implementations;
using Microsoft.Extensions.DependencyInjection;
namespace Lab4.Plugins.Extensions
{
public static class DiExtensions
{
public static IServiceCollection AddScopes(
this IServiceCollection services)
{
services.AddScoped<PluginsConvention>();
services.AddScoped<Func<Type, IPluginsConvention>>(sp
=> (type) => (sp.GetRequiredService(type) as IPluginsConvention)!);
return services;
}
}
}

View File

@ -1,223 +0,0 @@
using Lab4.Plugins.Models;
using AutoMapper;
using Lab3.Database.Repository.Interfaces;
using Cop.Borovkov.Var3.Components;
using CustomComponentsVar2;
using ComponentsLibrary;
using System.Windows.Forms;
using ComponentsLibrary.entities;
using ComponentsLibrary.entities.enums;
using Lab3.Database.DTO;
using Lab3.Forms;
using Lab3.Models;
using Lab4.Interfaces;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using Lab3.Extensions;
using Microsoft.Extensions.DependencyInjection;
namespace Lab4.Plugins.Implementations
{
public class PluginsConvention : IPluginsConvention
{
private readonly IMapper _mapper;
private readonly IStudentRepository _studentRepository;
private readonly IEducationFormRepository _educationFormRepository;
private readonly CustomListBox _control;
private readonly CustomPdfTable _simpleDocumentCreator;
private readonly CustomExcelTable _tableCreator;
private readonly ComponentDiagram _chartCreator;
public PluginsConvention()
{
_control = new();
_chartCreator = new();
_tableCreator = new();
_simpleDocumentCreator = new();
var serviceProvider = CreateServiceProvider();
_mapper = serviceProvider.GetRequiredService<IMapper>();
_studentRepository = serviceProvider.GetRequiredService<IStudentRepository>();
_educationFormRepository = serviceProvider.GetRequiredService<IEducationFormRepository>();
}
public string PluginName => "Успеваемость";
public UserControl GetControl => _control;
public PluginsConventionElement GetElement
{
get
{
var filds = _control.Selected.Split();
Guid id = Guid.Parse(filds[0]);
return new()
{
Id = id,
};
}
}
public bool CreateChartDocument(PluginsConventionSaveDocument saveDocument)
{
try
{
var data = _studentRepository.GetAsync().Result
.GroupBy(s => s.EducationForm)
.Select(s => new DataLine(
s.Key,
s.GroupBy(x => x.StartEducation.Year)
.Select(x => (year: x.Key.ToString(), count: (double)x.Count()))
.ToArray()))
.ToList();
_chartCreator.AddDiagram(
new(
saveDocument.FileName,
"Поступления",
"Диаграмма",
EnumAreaLegend.Bottom,
data
)
);
return true;
}
catch
{
return false;
}
}
public bool CreateSimpleDocument(PluginsConventionSaveDocument saveDocument)
{
try
{
var values = _studentRepository.GetAsync().Result
.Select(s => s.StudentSessions
.OrderBy(x => x.Number)
.Select(x => x.Score.ToString())
.ToArray())
.ToArray();
var tables = new string[values.Length, 6];
for (int i = 0; i < values.Length; ++i)
{
for (int j = 0; j < 6; ++j)
{
tables[i, j] = values[i][j];
}
}
_simpleDocumentCreator.SaveToPdf(new()
{
FilePath = saveDocument.FileName,
Title = "Сессии",
Tables = [tables]
});
return true;
}
catch
{
return false;
}
}
public bool CreateTableDocument(PluginsConventionSaveDocument saveDocument)
{
try
{
_tableCreator.SaveToExcel<StudentDTO>(new()
{
FilePath = saveDocument.FileName,
Title = "Студенты",
Headers =
[
("Id", nameof(StudentDTO.Id)),
("ФИО", nameof(StudentDTO.Name)),
("Форма обучения", nameof(StudentDTO.EducationForm)),
("Дата поступления", nameof(StudentDTO.StartEducation)),
],
HeaderGroups = [new() {
GroupHeader = "Образование",
FirstHeader = 2,
LastHeader = 3,
}],
Values = _studentRepository.GetAsync().Result
});
return true;
}
catch
{
return false;
}
}
public bool DeleteElement(PluginsConventionElement element)
{
try
{
_studentRepository
.DeleteAsync(element.Id).Wait();
return true;
}
catch
{
return false;
}
}
public Form GetForm(PluginsConventionElement? element = null)
=> new CreateForm(_studentRepository, _educationFormRepository, element?.Id);
public Form GetThesaurus()
=> new CatalogForm(_educationFormRepository);
public async void ReloadData()
{
try
{
var students = _mapper.Map<List<StudentViewModel>>(await _studentRepository.GetAsync());
_control.FillValues(
students.Select(s => string.Join(" ",
[
s.Id,
s.Name,
s.EducationForm,
s.StartEducation.ToLongDateString(),
s.SessionMarks,
]
))
);
}
catch
{
}
}
static IServiceProvider CreateServiceProvider()
{
var builder = Host.CreateDefaultBuilder()
.ConfigureAppConfiguration(c
=> c.AddJsonFile("appsettings.plugins.json", optional: true, reloadOnChange: true))
.ConfigureServices((context, services) => {
services.ConfigureDAL(context.Configuration);
services.AddMapping();
services.AddLab3Forms();
});
return builder.Build().Services;
}
}
}

View File

@ -1,13 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Lab3\Lab3.csproj" />
<ProjectReference Include="..\Lab4\Lab4.csproj" />
</ItemGroup>
</Project>

View File

@ -1,7 +0,0 @@
namespace Lab4
{
public record PluginsConfigurations
{
public string FolderPath { get; set; } = string.Empty;
}
}

View File

@ -1,16 +0,0 @@
using Lab4.Forms;
using Microsoft.Extensions.DependencyInjection;
namespace Lab4.Extensions
{
public static class DiExtensions
{
public static IServiceCollection AddForms(
this IServiceCollection services)
{
services.AddScoped<FormMain>();
return services;
}
}
}

View File

@ -1,188 +0,0 @@
using System.ComponentModel;
namespace Lab4.Forms
{
partial class FormMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.menuStrip = new MenuStrip();
this.ControlsStripMenuItem = new ToolStripMenuItem();
this.ActionsToolStripMenuItem = new ToolStripMenuItem();
this.DocsToolStripMenuItem = new ToolStripMenuItem();
this.SimpleDocToolStripMenuItem = new ToolStripMenuItem();
this.TableDocToolStripMenuItem = new ToolStripMenuItem();
this.ChartDocToolStripMenuItem = new ToolStripMenuItem();
this.panelControl = new Panel();
this.ThesaurusToolStripMenuItem = new ToolStripMenuItem();
this.AddElementToolStripMenuItem = new ToolStripMenuItem();
this.UpdElementToolStripMenuItem = new ToolStripMenuItem();
this.DelElementToolStripMenuItem = new ToolStripMenuItem();
this.menuStrip.SuspendLayout();
this.SuspendLayout();
//
// menuStrip
//
this.menuStrip.Items.AddRange(new ToolStripItem[] {
this.ControlsStripMenuItem,
this.ActionsToolStripMenuItem,
this.DocsToolStripMenuItem});
this.menuStrip.Location = new Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Size = new Size(800, 24);
this.menuStrip.TabIndex = 0;
this.menuStrip.Text = "Меню";
//
// ControlsStripMenuItem
//
this.ControlsStripMenuItem.Name = "ControlsStripMenuItem";
this.ControlsStripMenuItem.Size = new Size(94, 20);
this.ControlsStripMenuItem.Text = "Компоненты";
//
// ActionsToolStripMenuItem
//
this.ActionsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] {
this.ThesaurusToolStripMenuItem,
this.AddElementToolStripMenuItem,
this.UpdElementToolStripMenuItem,
this.DelElementToolStripMenuItem});
this.ActionsToolStripMenuItem.Name = "ActionsToolStripMenuItem";
this.ActionsToolStripMenuItem.Size = new Size(70, 20);
this.ActionsToolStripMenuItem.Text = "Действия";
//
// DocsToolStripMenuItem
//
this.DocsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] {
this.SimpleDocToolStripMenuItem,
this.TableDocToolStripMenuItem,
this.ChartDocToolStripMenuItem});
this.DocsToolStripMenuItem.Name = "DocsToolStripMenuItem";
this.DocsToolStripMenuItem.Size = new Size(82, 20);
this.DocsToolStripMenuItem.Text = "Документы";
//
// SimpleDocToolStripMenuItem
//
this.SimpleDocToolStripMenuItem.Name = "SimpleDocToolStripMenuItem";
this.SimpleDocToolStripMenuItem.ShortcutKeys = ((Keys)((Keys.Control | Keys.S)));
this.SimpleDocToolStripMenuItem.Size = new Size(233, 22);
this.SimpleDocToolStripMenuItem.Text = "Простой документ";
this.SimpleDocToolStripMenuItem.Click += new EventHandler(this.SimpleDocToolStripMenuItem_Click);
//
// TableDocToolStripMenuItem
//
this.TableDocToolStripMenuItem.Name = "TableDocToolStripMenuItem";
this.TableDocToolStripMenuItem.ShortcutKeys = ((Keys)((Keys.Control | Keys.T)));
this.TableDocToolStripMenuItem.Size = new Size(233, 22);
this.TableDocToolStripMenuItem.Text = "Документ с таблицей";
this.TableDocToolStripMenuItem.Click += new EventHandler(this.TableDocToolStripMenuItem_Click);
//
// ChartDocToolStripMenuItem
//
this.ChartDocToolStripMenuItem.Name = "ChartDocToolStripMenuItem";
this.ChartDocToolStripMenuItem.ShortcutKeys = ((Keys)((Keys.Control | Keys.C)));
this.ChartDocToolStripMenuItem.Size = new Size(233, 22);
this.ChartDocToolStripMenuItem.Text = "Диаграмма";
this.ChartDocToolStripMenuItem.Click += new EventHandler(this.ChartDocToolStripMenuItem_Click);
//
// panelControl
//
this.panelControl.Dock = DockStyle.Fill;
this.panelControl.Location = new Point(0, 24);
this.panelControl.Name = "panelControl";
this.panelControl.Size = new Size(800, 426);
this.panelControl.TabIndex = 1;
//
// ThesaurusToolStripMenuItem
//
this.ThesaurusToolStripMenuItem.Name = "ThesaurusToolStripMenuItem";
this.ThesaurusToolStripMenuItem.ShortcutKeys = ((Keys)((Keys.Control | Keys.I)));
this.ThesaurusToolStripMenuItem.Size = new Size(180, 22);
this.ThesaurusToolStripMenuItem.Text = "Справочник";
this.ThesaurusToolStripMenuItem.Click += new EventHandler(this.ThesaurusToolStripMenuItem_Click);
//
// AddElementToolStripMenuItem
//
this.AddElementToolStripMenuItem.Name = "AddElementToolStripMenuItem";
this.AddElementToolStripMenuItem.ShortcutKeys = ((Keys)((Keys.Control | Keys.A)));
this.AddElementToolStripMenuItem.Size = new Size(180, 22);
this.AddElementToolStripMenuItem.Text = "Добавить";
this.AddElementToolStripMenuItem.Click += new EventHandler(this.AddElementToolStripMenuItem_Click);
//
// UpdElementToolStripMenuItem
//
this.UpdElementToolStripMenuItem.Name = "UpdElementToolStripMenuItem";
this.UpdElementToolStripMenuItem.ShortcutKeys = ((Keys)((Keys.Control | Keys.U)));
this.UpdElementToolStripMenuItem.Size = new Size(180, 22);
this.UpdElementToolStripMenuItem.Text = "Изменить";
this.UpdElementToolStripMenuItem.Click += new EventHandler(this.UpdElementToolStripMenuItem_Click);
//
// DelElementToolStripMenuItem
//
this.DelElementToolStripMenuItem.Name = "DelElementToolStripMenuItem";
this.DelElementToolStripMenuItem.ShortcutKeys = ((Keys)((Keys.Control | Keys.D)));
this.DelElementToolStripMenuItem.Size = new Size(180, 22);
this.DelElementToolStripMenuItem.Text = "Удалить";
this.DelElementToolStripMenuItem.Click += new EventHandler(this.DelElementToolStripMenuItem_Click);
//
// FormMain
//
this.AutoScaleDimensions = new SizeF(7F, 15F);
this.AutoScaleMode = AutoScaleMode.Font;
this.ClientSize = new Size(800, 450);
this.Controls.Add(this.panelControl);
this.Controls.Add(this.menuStrip);
this.MainMenuStrip = this.menuStrip;
this.Name = "FormMain";
this.StartPosition =
FormStartPosition.CenterScreen;
this.Text = "Главная форма";
this.WindowState =
FormWindowState.Maximized;
this.KeyDown += new
KeyEventHandler(this.FormMain_KeyDown);
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private MenuStrip menuStrip;
private ToolStripMenuItem ControlsStripMenuItem;
private ToolStripMenuItem DocsToolStripMenuItem;
private ToolStripMenuItem SimpleDocToolStripMenuItem;
private ToolStripMenuItem TableDocToolStripMenuItem;
private ToolStripMenuItem ChartDocToolStripMenuItem;
private Panel panelControl;
private ToolStripMenuItem ActionsToolStripMenuItem;
private ToolStripMenuItem ThesaurusToolStripMenuItem;
private ToolStripMenuItem AddElementToolStripMenuItem;
private ToolStripMenuItem UpdElementToolStripMenuItem;
private ToolStripMenuItem DelElementToolStripMenuItem;
}
}

View File

@ -1,261 +0,0 @@
using Lab4.Interfaces;
using Lab4.Plugins.Models;
using Microsoft.Extensions.Options;
using System.Reflection;
namespace Lab4.Forms
{
public partial class FormMain : Form
{
private readonly Dictionary<string, IPluginsConvention> _plugins;
private readonly PluginsConfigurations _pluginsConfigurations;
private string _selectedPlugin = string.Empty;
public FormMain(IOptions<PluginsConfigurations> pluginsConfigs)
{
InitializeComponent();
_pluginsConfigurations = pluginsConfigs.Value;
_plugins = LoadPlugins();
}
private Dictionary<string, IPluginsConvention> LoadPlugins()
{
Dictionary<string, IPluginsConvention> result = [];
var plurinInterface = typeof(IPluginsConvention);
foreach (var type in Directory
.GetFiles(_pluginsConfigurations.FolderPath, "*.dll", SearchOption.AllDirectories)
.Select(Assembly.LoadFrom)
.SelectMany(x => x.GetTypes())
.Where(x => plurinInterface.IsAssignableFrom(x) && !x.IsInterface))
{
var plugin = type.GetConstructor([])?.Invoke([]);
if (plugin == null)
{
continue;
}
IPluginsConvention pluginObject = (plugin as IPluginsConvention)!;
string key = pluginObject.PluginName;
result[key] = pluginObject;
var item = new ToolStripMenuItem(key);
item.Click += (s, e) =>
{
_selectedPlugin = key;
panelControl.Controls.Clear();
_plugins[_selectedPlugin].ReloadData();
var control = _plugins[key].GetControl;
control.Parent = panelControl;
control.Dock = DockStyle.Fill;
panelControl.Controls.Add(control);
};
ControlsStripMenuItem.DropDownItems!.Add(item);
}
return result;
}
private void FormMain_KeyDown(object sender, KeyEventArgs e)
{
if (string.IsNullOrEmpty(_selectedPlugin) || !_plugins.ContainsKey(_selectedPlugin))
{
return;
}
if (!e.Control)
{
return;
}
switch (e.KeyCode)
{
case Keys.I:
ShowThesaurus();
break;
case Keys.A:
AddNewElement();
break;
case Keys.U:
UpdateElement();
break;
case Keys.D:
DeleteElement();
break;
case Keys.S:
CreateSimpleDoc();
break;
case Keys.T:
CreateTableDoc();
break;
case Keys.C:
CreateChartDoc();
break;
}
}
private void ShowThesaurus()
{
_plugins[_selectedPlugin].GetThesaurus()?.Show();
}
private void AddNewElement()
{
var form = _plugins[_selectedPlugin].GetForm();
if (form != null && form.ShowDialog() == DialogResult.OK)
{
_plugins[_selectedPlugin].ReloadData();
}
}
private void UpdateElement()
{
var element = _plugins[_selectedPlugin].GetElement;
if (element == null)
{
_ = MessageBox.Show("Нет выбранного элемента", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
var form = _plugins[_selectedPlugin].GetForm(element);
if (form != null && form.ShowDialog() == DialogResult.OK)
{
_plugins[_selectedPlugin].ReloadData();
}
}
private void DeleteElement()
{
if (MessageBox.Show("Удалить выбранный элемент", "Удаление",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
{
return;
}
var element = _plugins[_selectedPlugin].GetElement;
if (element == null)
{
_ = MessageBox.Show("Нет выбранного элемента", "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (_plugins[_selectedPlugin].DeleteElement(element))
{
_plugins[_selectedPlugin].ReloadData();
}
}
private void CreateSimpleDoc()
{
using var saveFileDialog = new SaveFileDialog
{
Filter = "pdf|*.pdf"
};
if (saveFileDialog.ShowDialog() != DialogResult.OK)
{
return;
}
if (_plugins[_selectedPlugin].CreateSimpleDocument(new PluginsConventionSaveDocument()
{
FileName = saveFileDialog.FileName,
}))
{
_ = MessageBox.Show("Документ сохранен",
"Создание документа",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
else
{
_ = MessageBox.Show("Ошибка при создании документа", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void CreateTableDoc()
{
using var saveFileDialog = new SaveFileDialog
{
Filter = "xlsx|*.xlsx"
};
if (saveFileDialog.ShowDialog() != DialogResult.OK)
{
return;
}
if (_plugins[_selectedPlugin].CreateTableDocument(new
PluginsConventionSaveDocument()
{
FileName = saveFileDialog.FileName,
}))
{
_ = MessageBox.Show("Документ сохранен",
"Создание документа",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
else
{
_ = MessageBox.Show("Ошибка при создании документа", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void CreateChartDoc()
{
using var saveFileDialog = new SaveFileDialog
{
Filter = "docx|*.docx"
};
if (saveFileDialog.ShowDialog() != DialogResult.OK)
{
return;
}
if (_plugins[_selectedPlugin].CreateChartDocument(new PluginsConventionSaveDocument()
{
FileName = saveFileDialog.FileName,
}))
{
_ = MessageBox.Show("Документ сохранен",
"Создание документа",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
else
{
_ = MessageBox.Show("Ошибка при создании документа", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ThesaurusToolStripMenuItem_Click(object sender, EventArgs e) => ShowThesaurus();
private void AddElementToolStripMenuItem_Click(object sender, EventArgs e) => AddNewElement();
private void UpdElementToolStripMenuItem_Click(object sender, EventArgs e) => UpdateElement();
private void DelElementToolStripMenuItem_Click(object sender, EventArgs e) => DeleteElement();
private void SimpleDocToolStripMenuItem_Click(object sender, EventArgs e) => CreateSimpleDoc();
private void TableDocToolStripMenuItem_Click(object sender, EventArgs e) => CreateTableDoc();
private void ChartDocToolStripMenuItem_Click(object sender, EventArgs e) => CreateChartDoc();
}
}

View File

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,68 +0,0 @@
using Lab4.Plugins.Models;
namespace Lab4.Interfaces
{
public interface IPluginsConvention
{
/// <summary>
/// Название плагина
/// </summary>
string PluginName { get; }
/// <summary>
/// Получение контрола для вывода набора данных
/// </summary>
UserControl GetControl { get; }
/// <summary>
/// Получение элемента, выбранного в контроле
/// </summary>
PluginsConventionElement GetElement { get; }
/// <summary>
/// Получение формы для создания/редактирования объекта
/// </summary>
/// <param name="element"></param>
/// <returns></returns>
Form GetForm(PluginsConventionElement? element = null);
/// <summary>
/// Получение формы для работы со справочником
/// </summary>
/// <returns></returns>
Form GetThesaurus();
/// <summary>
/// Удаление элемента
/// </summary>
/// <param name="element"></param>
/// <returns></returns>
bool DeleteElement(PluginsConventionElement element);
/// <summary>
/// Обновление набора данных в контроле
/// </summary>
void ReloadData();
/// <summary>
/// Создание простого документа
/// </summary>
/// <param name="saveDocument"></param>
/// <returns></returns>
bool CreateSimpleDocument(PluginsConventionSaveDocument saveDocument);
/// <summary>
/// Создание простого документа
/// </summary>
/// <param name="saveDocument"></param>
/// <returns></returns>
bool CreateTableDocument(PluginsConventionSaveDocument saveDocument);
/// <summary>
/// Создание документа с диаграммой
/// </summary>
/// <param name="saveDocument"></param>
/// <returns></returns>
bool CreateChartDocument(PluginsConventionSaveDocument saveDocument);
}
}

View File

@ -1,23 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -1,7 +0,0 @@
namespace Lab4.Plugins.Models
{
public class PluginsConventionElement
{
public Guid Id { get; set; }
}
}

View File

@ -1,7 +0,0 @@
namespace Lab4.Plugins.Models
{
public class PluginsConventionSaveDocument
{
public string FileName { get; set; } = null!;
}
}

View File

@ -1,38 +0,0 @@
using Lab4.Extensions;
using Lab4.Forms;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace Lab4
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
var app = CreateHostBuilder().Build();
Application.Run(app.Services.GetRequiredService<FormMain>());
}
static IHostBuilder CreateHostBuilder()
{
return Host.CreateDefaultBuilder()
.ConfigureAppConfiguration(c
=> c.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true))
.ConfigureServices((context, services) => {
services.AddForms();
services.Configure<PluginsConfigurations>(
context.Configuration.GetSection(nameof(PluginsConfigurations)));
});
}
}
}

View File

@ -1,8 +0,0 @@
{
"PluginsConfigurations": {
"FolderPath": "C:\\data\\Plugins"
},
"ConnectionStrings": {
"COPDataBase": "Host=localhost;Username=postgres;Password=postgres;Database=COP"
}
}

View File

@ -15,7 +15,7 @@ namespace PIHelperSh.PdfCreator.Enums
/// <summary>
/// Отступа нет
/// </summary>
[TypeValue<string>("0cm")]
[TypeValue<string>("ocm")]
None,
/// <summary>
/// Отступ небольшой

View File

@ -29,7 +29,7 @@ namespace PIHelperSh.PdfCreator.Models.ImageModels
public int? Height { get; set; } = null;
/// <summary>
/// Выравнивание текста внутри параграфа (по умолчанию - по левой стороне)
/// Выравнивание текста внутри параграфа (по умолчанию - по левой строне)
/// </summary>
public PdfAlignmentType ImageAlignment { get; set; } = PdfAlignmentType.Left;

View File

@ -18,7 +18,7 @@ namespace PIHelperSh.PdfCreator.Models.PieChartModel
public IEnumerable<(string Name, double Value)> Value { get; set; }
/// <summary>
/// Цвет области на диаграмме. При null будет использоваться выдача цветов по умолчанию)
/// Цвет области на диаграме. При null будет использоватсся выдача цветов по умолчанию)
/// </summary>
public Color? Color { get; set; } = null;

View File

@ -1,7 +1,7 @@
namespace PIHelperSh.PdfCreator.Models.PieChartModel
{
/// <summary>
/// Модель линейной диаграммы
/// Модель линейной диограммы
/// </summary>
public class PdfHistogramModel : PdfPieChartModel
{

View File

@ -18,7 +18,7 @@ namespace PIHelperSh.PdfCreator.Models.PieChartModel
public double Value { get; set; }
/// <summary>
/// Цвет области на диаграмме. При null будет использоваться выдача цветов по умолчанию)
/// Цвет области на диаграме. При null будет использоватсся выдача цветов по умолчанию)
/// </summary>
public Color? Color { get; set; } = null;

View File

@ -34,7 +34,7 @@ namespace PIHelperSh.PdfCreator.Models.TableModels
public PdfStyleType RowStyle = PdfStyleType.Basic;
/// <summary>
/// Базовое выравнивание элементов в строке
/// Базовое выравнивание элементов сторок
/// </summary>
public PdfAlignmentType RowHorizontalAlignment = PdfAlignmentType.Rigth;

View File

@ -13,7 +13,7 @@ namespace PIHelperSh.PdfCreator.Models.TableModels
public class PDFSimpleTableRow
{
/// <summary>
/// Элементы данной стоки
/// Элемменты данной стоки
/// </summary>
public List<string> Items = new List<string>();

View File

@ -35,7 +35,7 @@ namespace PIHelperSh.PdfCreator.Models.TableModels
public PdfStyleType RecordStyle { get; set; } = PdfStyleType.Basic;
/// <summary>
/// Выравнивание текста объектов в таблице (по умолчанию - по левой стороне)
/// Выравнивание текста объектов в таблице (по умолчанию - по левой строне)
/// </summary>
public PdfAlignmentType RecordHorizontalAlignment { get; set; } = PdfAlignmentType.Left;

View File

@ -1,5 +1,10 @@
using PIHelperSh.PdfCreator.Enums;
using PIHelperSh.PdfCreator.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PIHelperSh.PdfCreator.Models.TextModels
{
@ -9,7 +14,7 @@ namespace PIHelperSh.PdfCreator.Models.TextModels
public class PdfList : IPdfElement
{
/// <summary>
/// Элементы списка (параграфы или иные списки)
/// Элементы списка (параграфы или иные спсики)
/// </summary>
public List<IPdfElement> Content { get; set; } = new();

View File

@ -24,7 +24,7 @@ namespace PIHelperSh.PdfCreator.Models.TextModels
public PdfStyleType Style { get; set; } = PdfStyleType.Basic;
/// <summary>
/// Выравнивание текста внутри параграфа (по умолчанию - по левой стороне)
/// Выравнивание текста внутри параграфа (по умолчанию - по левой строне)
/// </summary>
public PdfAlignmentType ParagraphAlignment { get; set; } = PdfAlignmentType.Left;

View File

@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Title>Библиотека PDF</Title>
<Authors>MaximK</Authors>
<Description>Небольшая надстройка для более удобной работы с PDF</Description>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/KuzarinM/PIHelperSh/tree/master/PIHelperSh.PdfCreater</RepositoryUrl>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<Version>1.1.1</Version>
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\LICENSE">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
<PackageReference Include="PIHelperSh.Core" Version="1.0.1" />
</ItemGroup>
<ItemGroup>
<None Update="README.md">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
</Project>

View File

@ -1,6 +1,8 @@
using MigraDoc.DocumentObjectModel;
using System.Text;
using MigraDoc.Rendering;
using MigraDoc.DocumentObjectModel.Tables;
using System.Reflection;
using MigraDoc.DocumentObjectModel.Shapes.Charts;
using PIHelperSh.Core.Extensions;
using PIHelperSh.PdfCreator.Enums;
@ -9,11 +11,6 @@ using PIHelperSh.PdfCreator.Models.TextModels;
using PIHelperSh.PdfCreator.Models.ImageModels;
using PIHelperSh.PdfCreator.Models.PieChartModel;
using PIHelperSh.PdfCreator.Interfaces;
using System.Text;
using TabAlignment = MigraDoc.DocumentObjectModel.TabAlignment;
using System.Reflection;
using HorizontalAlignment = MigraDoc.DocumentObjectModel.Shapes.Charts.HorizontalAlignment;
using Color = MigraDoc.DocumentObjectModel.Color;
namespace PIHelperSh.PdfCreator
{
@ -416,7 +413,7 @@ namespace PIHelperSh.PdfCreator
if (rowHeaded)
{
_section!.PageSetup.Orientation = MigraDoc.DocumentObjectModel.Orientation.Landscape;
_section!.PageSetup.Orientation = Orientation.Landscape;
_section.PageSetup.LeftMargin = 10;
MakeTableWithHederInRow(_document.LastSection.AddTable(), header);
return;
@ -459,7 +456,7 @@ namespace PIHelperSh.PdfCreator
if (tableData.ChangePageOrientation)
{
_section!.PageSetup.Orientation = MigraDoc.DocumentObjectModel.Orientation.Landscape;
_section!.PageSetup.Orientation = Orientation.Landscape;
_section.PageSetup.LeftMargin = 10;
_section.PageSetup.BottomMargin = 5;
}
@ -538,7 +535,7 @@ namespace PIHelperSh.PdfCreator
if (item.Color.HasValue)
{
series.FillFormat.Color = new MigraDoc.DocumentObjectModel.Color((uint)item.Color.Value.ToArgb());
series.FillFormat.Color = new Color((uint)item.Color.Value.ToArgb());
}
}

View File

@ -1,59 +0,0 @@
namespace TestCustomComponents.Forms
{
partial class Form3
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
button1 = new Button();
SuspendLayout();
//
// button1
//
button1.Location = new Point(103, 83);
button1.Name = "button1";
button1.Size = new Size(94, 29);
button1.TabIndex = 0;
button1.Text = "button1";
button1.UseVisualStyleBackColor = true;
button1.Click += button1_Click;
//
// Form3
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(button1);
Name = "Form3";
Text = "Form3";
ResumeLayout(false);
}
#endregion
private Button button1;
}
}

View File

@ -1,28 +0,0 @@
using Lab4.Plugins.Implementations;
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 TestCustomComponents.Forms
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var test = new PluginsConvention();
int a = 1;
}
}
}

View File

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -4,7 +4,7 @@
{
public int Id { get; set; }
public string Name { get; set; }
public string Name { get; set; } = string.Empty;
public int Age { get; set; }

View File

@ -13,7 +13,7 @@ namespace TestCustomComponents
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new Form3());
Application.Run(new Form2());
}
}
}

View File

@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Lab4.Plugins\Lab4.Plugins.csproj" />
<ProjectReference Include="..\Cop.Borovkov.Var3\Cop.Borovkov.Var3.csproj" />
</ItemGroup>
</Project>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,94 +0,0 @@
# Лабораторная работа №5.
# Применение структурных паттернов.
## Задание
1) Дать описание паттернов, указанных во вариантах, для каких целей они могут применяться,
какие участники там фигурируют.
2) На основе задания из 3 лабораторной работы, для каждого паттерна придумать сущности,
относящиеся к той же предметной области, что описаны в задании и реализация которых
бы в приложении потребовала применения паттерна.
### Ограничения:
- На каждый паттерн свои сущности
- В качестве источника сущностей использовать предметную область задания 3 лабораторной работы, а не элементы разработки (что-то типа «У меня паттерн Singleton, укажу ка я класс-подключение к БД через него», не принимается).
3) Создать диаграммы классов, отражающие взаимодействие новых
сущностей (а также используемый паттерн) с классами,
созданными в рамках 3 лабораторной работы. Отдельно отметить
классы, которые являются участниками паттерна
## Вариант 3: _Adapter, Composite, Proxy_
### Паттерн Adapter
Паттерн Адаптер используется для того,
чтобы объекты с несовместимыми интерфейсами могли работать вместе.
Он оборачивает один интерфейс в другой,
делая несовместимые классы совместимыми без изменения их исходного кода.
Задачи, которые решает паттерн Adapter:
- Интеграция стороннего кода или библиотек:
когда требуется использовать стороннюю библиотеку с вашим приложением,
но её интерфейс отличается от имеющегося интерфейса.
- Обратная совместимость: когда нужно подключить новый код к старому интерфейсу, не изменяя существующий.
- Упрощение взаимодействия: уменьшает сложность работы с несколькими несовместимыми компонентами.
Участники:
- Target: представляет объекты, которые используются клиентом.
- Client: использует объекты Target для реализации своих задач.
- Adaptee: представляет адаптируемый класс, который хотелось бы использовать у клиента вместо объектов Target.
- Adapter: сам адаптер, который позволяет работать с объектами Adaptee как с объектами Target.
**Пример реализации для рассматриваемой предметной области:**<br>
Классы, реализующие паттерн:
- IStudentTracker (Target) Интерфейс системы отслеживания успеваемости студентов
- StudentManager (Client) Использует данные о успеваемости, для определеня судьбы студентов
- AttendanceTracker (Adaptee) Реализализовывает систему отслеживания посещаемости студентов
- StudentTrackerAdapter (Adapter) "оборачивает" стороннюю систему и преобразует её в интерфейс, ожидаемый клиентом
![img_3.png](img_3.png)
### Паттерн Composite
Паттерн Компоновщик (Composite) объединяет группы объектов в древовидную структуру
по принципу "часть-целое и позволяет клиенту одинаково работать как с отдельными объектами,
так и с группой объектов.
Образно реализацию паттерна можно представить в виде меню,
которое имеет различные пункты. Эти пункты могут содержать подменю, в которых,
в свою очередь, также имеются пункты. То есть пункт меню служит с одной стороны частью меню,
а с другой стороны еще одним меню. В итоге мы однообразно можем работать как с пунктом меню,
так и со всем меню в целом.
Участники:
- Component определяет интерфейс для всех компонентов в древовидной структуре
- Composite представляет компонент, который может содержать другие компоненты
и реализует механизм для их добавления и удаления
- Leaf представляет отдельный компонент, который не может содержать другие компоненты
- Client клиент, который использует компоненты
Классы, реализующие паттерн:
- IStudent (Component) Студент обучающийся в вузе
- Group (Composite) Группировка студентов (групаа в потоке, поток, курс...)
- Student (Leaf) Конкретный студент
- University (Client) Обеспечивает обучение студентов
![img.png](img.png)
### Паттерн Proxy
Паттерн Заместитель (Proxy) предоставляет объект-заместитель, который управляет доступом к другому объекту.
То есть создается объект-суррогат, который может выступать в роли другого объекта и замещать его.
Участники:
- Subject определяет общий интерфейс для Proxy и RealSubject. Поэтому Proxy может использоваться вместо RealSubject
- RealSubject представляет реальный объект, для которого создается прокси
- Proxy заместитель реального объекта. Хранит ссылку на реальный объект, контролирует к нему доступ,
может управлять его созданием и удалением. При необходимости Proxy переадресует запросы объекту RealSubject
- Client использует объект Proxy для доступа к объекту RealSubject
Классы, реализующие паттерн:
- IStudent (Subject) Студент
- Student (RealSubject) Студент из группы
- Elder (Proxy) Староста отвечает на вопросы преподователя, при надомности спрашивает студентов группы
- Lecturer (Client) - Задаёт вопросы студентам через старосту
![img_2.png](img_2.png)

View File

@ -1,92 +0,0 @@
# Лабораторная работа №6.
# Применение структурных паттернов.
## Задание
1) Дать описание паттернов, указанных во вариантах, для каких целей они могут применяться,
какие участники там фигурируют.
2) На основе задания из 3 лабораторной работы, для каждого паттерна придумать сущности,
относящиеся к той же предметной области, что описаны в задании и реализация которых
бы в приложении потребовала применения паттерна.
### Ограничения
- На каждый паттерн свои сущности
- В качестве источника сущностей использовать предметную область задания 3 лабораторной работы,
а не элементы разработки (что-то типа «У меня паттерн Singleton,
укажу ка я класс-подключение к БД через него», не принимается).
3) Создать диаграммы классов, отражающие взаимодействие новых
сущностей (а также используемый паттерн) с классами,
созданными в рамках 3 лабораторной работы. Отдельно отметить
классы, которые являются участниками паттерна
## Вариант 3 _AbstractFactory, FactoryMethod, ObjectPool._
### Паттерн AbstractFactory
Паттерн "Абстрактная фабрика" (Abstract Factory) предоставляет интерфейс для создания семейств
взаимосвязанных объектов с определенными интерфейсами без указания конкретных типов данных объектов.
Участники
- AbstractProductA и AbstractProductB абстрактные классы, определяющие интерфейс для классов,
объекты которых будут создаваться в программе
- ProductA1 / ProductA2 и ProductB1 / ProductB2 конкретные классы,
представляющие конкретную реализацию абстрактных классов.
- AbstractFactory - Абстрактный класс фабрики определяет методы для создания объектов.
Причем методы возвращают абстрактные продукты, а не их конкретные реализации.
- Client класс клиента, использующий класс фабрики для создания объектов.
При этом он использует исключительно абстрактный класс фабрики AbstractFactory
и абстрактные классы продуктов AbstractProductA и AbstractProductB и никак не зависит от их конкретных реализаций.
Классы, реализующие паттерн:
- IReportFactory (Abstract Factory) интерфейс фабрики для создания отчетов.
- FivePointReportFactory (Concrete Factory) фабрика для 5-балльной системы.
- HundredPointReportFactory (Concrete Factory) фабрика для 100-балльной системы.
- IPerformanceReport (Abstract Product) интерфейс для отчета по успеваемости.
- FivePointPerformanceReport и HundredPointPerformanceReport (Concrete Products) конкретные реализации отчетов по успеваемости для 5- и 10-балльной систем.
- ILaggingStudentsReport (Abstract Product) интерфейс для отчета по отстающим студентам.
- FivePointLaggingStudentsReport и HundredPointLaggingStudentsReport (Concrete Products) отчеты по отстающим студентам для 5- и 10-балльной систем.
- ReportManager (Client) класс, который обрабатывает отчеты
![img_4.png](img_4.png)
### Паттерн FactoryMethod
Фабричный метод (Factory Method) - это паттерн, который определяет интерфейс для создания объектов некоторого класса,
но непосредственное решение о том, объект какого класса создавать происходит в подклассах.
То есть паттерн предполагает, что базовый класс делегирует создание объектов классам-наследникам.
Участники:
- Product интерфейс или абстрактный класс, определяющий структуру создаваемых объектов.
- ConcreteProductA и ConcreteProductB конкретные реализации интерфейса “Product”, представляющие первый и второй тип продукта.
- Creator абстрактный класс или интерфейс, который определяет фабричный метод для создания объектов типа “Product”.
- ConcreteCreatorA и ConcreteCreatorB конкретные реализации “Creator”, которая создаёт объекты типа “ConcreteProductA” и “ConcreteCreatorB” соответственно.
Классы, реализующие паттерн:
- Product IReport определяет интерфейс для всех отчетов.
- ConcreteProductA и ConcreteProductB GradeReport и AttendanceReport конкретные реализации интерфейса “IReport”.
- Creator ReportCreator определяет фабричный метод для создания объектов типа “IReport”.
- ConcreteCreatorA и ConcreteCreatorB GradeReportCreator и AttendanceReportCreator конкретные реализации “ReportCreator”.
![img_5.png](img_5.png)
### Паттерн ObjectPool
Object Pool (пул объектов) — это поведенческий паттерн, который используется для оптимизации управления ресурсами.
Он позволяет многократно использовать уже созданные объекты вместо их повторного создания и уничтожения.
Это особенно полезно, когда создание объектов является дорогой операцией с точки зрения времени или ресурсов.
Участники:
- Pool управляет коллекцией объектов. Отвечает за выдачу и возврат объектов из пула. Решает, когда создавать новый объект или использовать существующий.
- ReusableObject (повторно используемый объект) - объект, который находится в пуле и может быть многократно использован. Включает логику и состояние объекта.
- Client - получает объект из пула для использования. Возвращает объект обратно в пул, когда он больше не нужен.
Классы, реализующие паттерн:
- Pool FormatPool управляет доступностью объектов “Format”. Позволяет выдавать объекты формы обучения для студентов.
- ReusableObject Format содержит данные, связанные с конкретной формой обучения.
- Client Student представляет студента и содержит данные о нем.
![img_6.png](img_6.png)

View File

@ -1,74 +0,0 @@
# Лабораторная работа №7.
# Применение структурных паттернов.
## Задание
1) Дать описание паттернов, указанных во вариантах, для каких целей они могут применяться,
какие участники там фигурируют.
2) На основе задания из 3 лабораторной работы, для каждого паттерна придумать сущности,
относящиеся к той же предметной области, что описаны в задании и реализация которых
бы в приложении потребовала применения паттерна.
### Ограничения
- На каждый паттерн свои сущности
- В качестве источника сущностей использовать предметную область задания 3 лабораторной работы,
а не элементы разработки (что-то типа «У меня паттерн Singleton,
укажу ка я класс-подключение к БД через него», не принимается).
3) Создать диаграммы классов, отражающие взаимодействие новых
сущностей (а также используемый паттерн) с классами,
созданными в рамках 3 лабораторной работы. Отдельно отметить
классы, которые являются участниками паттерна
## Вариант 3 _Mediator, Mediator (2 различных реализации), Strategy._
### Паттерн Mediator
Паттерн "Посредник" (Mediator) представляет такой шаблон проектирования,
который обеспечивает взаимодействие множества объектов без необходимости ссылаться друг на друга.
Тем самым достигается слабосвязанность взаимодействующих объектов.
Участники
- Mediator - представляет интерфейс для взаимодействия с объектами Colleague.
- Colleague - представляет интерфейс для взаимодействия с объектом Mediator.
- ConcreteColleague1 и ConcreteColleague2 - конкретные классы коллег,
которые обмениваются друг с другом через объект Mediator.
- ConcreteMediator - конкретный посредник, реализующий интерфейс типа Mediator.
Классы, реализующие паттерн:
- Secretary Mediator - Секретарь
- Client Colleague - Участник вузовской системы
- Teacher ConcreteColleague1 - Преподователь
- Student ConcreteColleague2 - Студент
- Dean`s Office ConcreteMediator - Деканат
![img_8.png](img_8.png)
- ILms Mediator - Сайт лмс
- User Colleague - Пользователь лмс
- Teacher ConcreteColleague1 - Преподователь
- Student ConcreteColleague2 - Студент
- Lms ConcreteMediator - Логика сайта лмс
![img_7.png](img_7.png)
### Паттерн Strategy
Strategy (Стратегия) — шаблон проектирования, который определяет набор алгоритмов, инкапсулирует каждый из них
и обеспечивает их взаимозаменяемость.
В зависимости от ситуации мы можем легко заменить один используемый алгоритм другим.
При этом замена алгоритма происходит независимо от объекта, который использует данный алгоритм.
Участники:
- IStrategy: интерфейс, который определяет метод Algorithm(). Это общий интерфейс для всех реализующих его алгоритмов.
Вместо интерфейса здесь также можно было бы использовать абстрактный класс.
- ConcreteStrategy1 и ConcreteStrategy2: классы, которые реализуют интерфейс IStrategy,
предоставляя свою версию метода Algorithm(). Подобных классов-реализаций может быть множество.
- Context: класс, который хранит ссылку на объект IStrategy и связан с интерфейсом IStrategy отношением агрегации.
Классы, реализующие паттерн:
- IStrategy IStudentWorkChecker общий интерфейс для всех стратегий проверку индивидуальной работы студента.
- СourseWorkChecker, LabWorkChecker - классы, реализующие проверку ирс
- Context Teacher Преподаватель выбирает подходящцю стратегию для проверки работы
![img_10.png](img_10.png)

Some files were not shown because too many files have changed in this diff Show More