-
Автор темы
- #1
Всем любителям C# привет! В сегодняшнем гайде я бы хотел показать, как реализовать события, которые будут реализовываться в своем собственном классе, но при этом ни одна часть программы не будет вызывать этот класс, тем самым он станет автоматически вызываемым при соблюдении своих условий.
Для этого я создал интерфейс IEventController
Реализуем данный интерфейс
После реализации данных классов нам нужно сделать класс-обработчик событий
Данный класс находит все типы, в которых присутствует реализация IEventController. После реализации данного класса мы переходим в наш метод Main, в котором мы и будем запускать ядро обработчика событий.
После всех выше изложенных действий, мы можем запустить код и получить на выходе вот это
Я считаю, что данный пример обработчика событий поможет разделить модель проекта на основной код и класс событий, которые работают самостоятельно без вмешательства в основные строчки кода проекта, а так же способствуют более чистому написанию кода без всяких излишек сишарповских Event'ов
Для этого я создал интерфейс IEventController
C#:
public interface IEventController
{
bool CanExecute();
void Execute();
}
C#:
class Event1 : IEventController
{
public virtual bool CanExecute()
{
var t = Console.In.ReadLine();
if (t == "Привет!")
{
return true;
}
return false;
}
public void Execute()
{
Console.WriteLine("Здарова! Я событие под номером 1");
}
}
class Event2 : IEventController
{
public virtual bool CanExecute()
{
var t = Console.In.ReadLine();
if (t == "Привет, а ты кто?")
{
return true;
}
return false;
}
public void Execute()
{
Console.WriteLine("Привет! А я событие номер 2");
}
}
C#:
internal class ClassEventInfo
{
public object SelectedClass { get; set; }
public Task EventTask { get; set; }
public Action EventAction { get; set; }
}
public static class EventExecutor
{
private static bool IsRuned = false;
private static Thread m_EventTask = new Thread(ExecuteEvent);
private static Dictionary<Type, ClassEventInfo> m_ClassesInstance;
public static void StartCore()
{
if (IsRuned)
{
return;
}
m_EventTask.Start();
}
public static void StopCore()
{
IsRuned = false;
m_EventTask.Abort();
}
private static void ExecuteEvent()
{
IEnumerable<Type> types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly => assembly.GetTypes().Where(type => type.GetInterface(nameof(IEventController)) != null));
if(types is null)
{
return;
}
m_ClassesInstance = new Dictionary<Type, ClassEventInfo>();
while (true)
{
foreach (Type currentClass in types)
{
if (!m_ClassesInstance.TryGetValue(currentClass, out ClassEventInfo selectedClass))
{
object newInstance = Activator.CreateInstance(currentClass);
ClassEventInfo newEventInfo = new ClassEventInfo()
{
SelectedClass = newInstance,
EventAction = () =>
{
if ((bool)currentClass.GetMethod("CanExecute").Invoke(newInstance, null))
{
currentClass.GetMethod("Execute").Invoke(newInstance, null);
}
}
};
m_ClassesInstance.Add(currentClass, newEventInfo);
selectedClass = newEventInfo;
}
if(selectedClass.EventTask is null || selectedClass.EventTask.Status != TaskStatus.Running)
{
selectedClass.EventTask = Task.Factory.StartNew(selectedClass.EventAction);
}
}
}
}
}
C#:
static void Main(string[] args)
{
Console.WriteLine("Тестовое приложение!");
EventExecutor.StartCore();
}
Я считаю, что данный пример обработчика событий поможет разделить модель проекта на основной код и класс событий, которые работают самостоятельно без вмешательства в основные строчки кода проекта, а так же способствуют более чистому написанию кода без всяких излишек сишарповских Event'ов