Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CSharpEducation.sln
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Task2", "Task2\Task2.csproj
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Practice", "Practice\Practice.csproj", "{F5E2E1BD-7248-4069-B991-520505CFDDC1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Task3", "Task3\Task3.csproj", "{70A7F1E7-2B00-4244-A0E2-55D56FDD0DB1}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Task3", "Task3\Task3.csproj", "{70A7F1E7-2B00-4244-A0E2-55D56FDD0DB1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Task4", "Task4\Task4.csproj", "{9029EB45-ABCC-4879-9802-06FB2702E70F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -33,6 +35,10 @@ Global
{70A7F1E7-2B00-4244-A0E2-55D56FDD0DB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{70A7F1E7-2B00-4244-A0E2-55D56FDD0DB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{70A7F1E7-2B00-4244-A0E2-55D56FDD0DB1}.Release|Any CPU.Build.0 = Release|Any CPU
{9029EB45-ABCC-4879-9802-06FB2702E70F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9029EB45-ABCC-4879-9802-06FB2702E70F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9029EB45-ABCC-4879-9802-06FB2702E70F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9029EB45-ABCC-4879-9802-06FB2702E70F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,43 @@
## Task1
Создать проект консольногно приложения и вывести на экран "Hello, World!".


## Task2
### Игра "Крестики-нолики"
- Реализовано на классах
- Можно менять размер поля
- Навигация по полю кнопками со стрелками


## Task3
### PhoneBook
Текст задания:
* Должна быть реализована CRUD функциональность:
+ Должен уметь принимать от пользователя номер и имя телефона.
+ Сохранять номер в файле phonebook.txt. (При завершении программы либо при добавлении).
+ Вычитывать из файла сохранённые номера. (При старте программы).
+ Удалять номера.
+ Получать абонента по номеру телефона.
+ Получать номер телефона по имени абонента.
* Обращение к Phonebook должно быть как к классу-одиночке.
* Внутри должна быть коллекция с абонентами.
* Для обращения с абонентами нужно завести класс Abonent. С полями «номер телефона», «имя».
* Не дать заносить уже записанного абонента.


## Task4
### Репозиторий сущностей
Текст задания:
1. Создайте интерфейс IRepository<T> для базовых операций с сущностями (CRUD)
2. Добавьте ограничение типа T интерфейсом IEntity
3. Создайте три реализации репозитория: для работы со списком сущностей в памяти, для работы с БД (саму БД можно не реализовывать), и для работы с файлами


## Task5
### Приложение для асинхронной загрузки файлов
Текст задания: приложение, которое загружает файлы из интернета и сохраняет их на локальном компьютере. Пользователь должен иметь возможность ввести URL-адрес файла и выбрать путь для сохранения. Решение должно использовать асинхронный код для выполнения загрузки и сохранения файлов.


## Task6
### Тесты для Phonebook
Текст задания: Написать unit-тесты для проекта Phonebook
95 changes: 95 additions & 0 deletions Task4/DataBaseRepo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace Task4
{
internal class DataBaseRepo<T> : IRepository<T> where T : IEntity, new()
{
#region Поля
private readonly string connectionString;
#endregion

#region Методы
public void Create(T entity)
{
using (SqlConnection connection = new SqlConnection(this.connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand();
command.CommandText = $"INSERT INTO {connection.Database}(Id, Name, Age) VALUES({entity.Id}, {entity.Name}, {entity.Age})";
command.Connection = connection;
command.ExecuteNonQuery();
}
}

public T Read(string id)
{
T entity = new T();

using (SqlConnection connection = new SqlConnection(this.connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand();
command.CommandText = $"SELECT Id, Name, Age FROM {connection.Database} WHERE Id='{id}'";
command.Connection = connection;

using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
var Id = reader.GetString(0);
var name = reader.GetString(1);
var age = reader.GetInt32(2);

entity.Id = Id;
entity.Name = name;
entity.Age = age;
}
}
}
}
return entity;

}

public void Update(T entity)
{
using (SqlConnection connection = new SqlConnection(this.connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand();
command.CommandText = $"UPDATE {connection.Database} SET Age={entity.Age}, Name='{entity.Name}' WHERE Id='{entity.Id}'";
command.Connection = connection;
command.ExecuteNonQuery();
}
}

public void Delete(string id)
{
using (SqlConnection connection = new SqlConnection(this.connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand();
command.CommandText = $"DELETE FROM {connection.Database} WHERE Id='{id}'";
command.Connection = connection;
command.ExecuteNonQuery();
}
}
#endregion

#region Конструкторы
public DataBaseRepo(string connectionString)
{
this.connectionString = connectionString;
}
#endregion
}
}
49 changes: 49 additions & 0 deletions Task4/EntityListRepo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace Task4
{
internal class EntityListRepo<T> : IRepository<T> where T : IEntity
{
#region Свойства
public List<T> Storage { get; set; }
#endregion

#region Методы
public void Create(T entity)
{
this.Storage.Add(entity);
}

public T Read(string id)
{
return this.Storage.Find(e => e.Id == id);
}

public void Update(T entity)
{
Storage[Storage.FindIndex(e => e.Id == entity.Id)] = entity;
}

public void Delete(string id)
{
if (!Storage.Remove(Storage.Find(e => e.Id == id)))
{
throw new Exception("Удаление не произошло: сущность не обнаружена в памяти");
return;
}
}
#endregion

#region Конструкторы
public EntityListRepo(List<T> storage)
{
this.Storage = storage;
}
#endregion
}
}
98 changes: 98 additions & 0 deletions Task4/FileRepo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using System.IO;
using System.Text.Json;

namespace Task4
{
public class FileRepo<T> : IRepository<T> where T : IEntity, IDisposable
{
#region Поля
private readonly string filepath;
private EntityListRepo<T> fileData;
private bool disposed = false;
private DateTime lastWriteTime;
#endregion

#region Методы
#region CRUD
public void Create(T entity)
{
UpdateFileDataWhenChanged();

this.fileData.Create(entity);
}

public T Read(string id)
{
UpdateFileDataWhenChanged();

return this.fileData.Read(id);
}

public void Update(T entity)
{
UpdateFileDataWhenChanged();

this.fileData.Update(entity);
}

public void Delete(string id)
{
UpdateFileDataWhenChanged();

this.fileData.Delete(id);
}
#endregion

private void UpdateFileDataWhenChanged()
{
if (IsFileChanged())
SetFileData();
}

private void SetFileData()
{
var data = JsonSerializer.Deserialize<List<T>>(File.ReadAllText(this.filepath));
this.fileData = new EntityListRepo<T>(data);
}

private bool IsFileChanged()
{

var fileInfo = new FileInfo(this.filepath);
return fileInfo.LastWriteTime != this.lastWriteTime;
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (disposed) return;
if (disposing)
{
File.WriteAllText(this.filepath, JsonSerializer.Serialize(this.fileData));
this.lastWriteTime = DateTime.Now;
}
disposed = true;
}
#endregion

#region Конструкторы
public FileRepo(string filepath)
{
this.filepath = filepath;
SetFileData();
}
#endregion

#region Деструкторы
~FileRepo()
{
Dispose(false);
}
#endregion
}
}
16 changes: 16 additions & 0 deletions Task4/IEntity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Task4
{
public interface IEntity
{
// Например зададим следующие свойства.
string Id { get; set; }
string Name { get; set; }
int Age { get; set; }
}
}
16 changes: 16 additions & 0 deletions Task4/IRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Task4
{
public interface IRepository<T> where T : IEntity
{
void Create(T entity);
T Read(string id);
void Update(T entity);
void Delete(string id);
}
}
13 changes: 13 additions & 0 deletions Task4/Task4.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
</ItemGroup>

</Project>