23 changed files with 494 additions and 0 deletions
@ -0,0 +1,25 @@ |
|||||
|
|
||||
|
Microsoft Visual Studio Solution File, Format Version 12.00 |
||||
|
# Visual Studio Version 17 |
||||
|
VisualStudioVersion = 17.2.32616.157 |
||||
|
MinimumVisualStudioVersion = 10.0.40219.1 |
||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "oop20250222", "oop20250222\oop20250222.csproj", "{C11D78EB-758D-4819-BA1D-5F986393304C}" |
||||
|
EndProject |
||||
|
Global |
||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
||||
|
Debug|Any CPU = Debug|Any CPU |
||||
|
Release|Any CPU = Release|Any CPU |
||||
|
EndGlobalSection |
||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
||||
|
{C11D78EB-758D-4819-BA1D-5F986393304C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{C11D78EB-758D-4819-BA1D-5F986393304C}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{C11D78EB-758D-4819-BA1D-5F986393304C}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{C11D78EB-758D-4819-BA1D-5F986393304C}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
EndGlobalSection |
||||
|
GlobalSection(SolutionProperties) = preSolution |
||||
|
HideSolutionNode = FALSE |
||||
|
EndGlobalSection |
||||
|
GlobalSection(ExtensibilityGlobals) = postSolution |
||||
|
SolutionGuid = {7B529A88-3579-4852-9E56-D49B5A2F1F48} |
||||
|
EndGlobalSection |
||||
|
EndGlobal |
||||
@ -0,0 +1,52 @@ |
|||||
|
using ConsoleApp1.intf; |
||||
|
using ConsoleApp1.pubsub; |
||||
|
using ConsoleApp1.pubsub.generics; |
||||
|
|
||||
|
namespace ConsoleApp1 |
||||
|
{ |
||||
|
internal class Program |
||||
|
{ |
||||
|
static void Main(string[] args) |
||||
|
{ |
||||
|
IPublisher<IMessage> pub1 = h_generics(); |
||||
|
IPublisher<IMessage> pub2 = h_fixedClasses(); |
||||
|
|
||||
|
string[] arss = new string[] { "EXCEPTION", "INFO", "DEBUG" }; |
||||
|
for (int ii = 0; ii < 10; ii++) |
||||
|
{ |
||||
|
Thread.Sleep(1000); |
||||
|
IMessage msg = new Message() |
||||
|
{ |
||||
|
Category = arss[Random.Shared.Next(arss.Length)], |
||||
|
Text = $"{ii}" |
||||
|
}; |
||||
|
pub1.Publish(msg); |
||||
|
pub2.Publish(msg); |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
private static IPublisher<IMessage> h_generics() |
||||
|
{ |
||||
|
IPublisher<IMessage> pub = new Publisher<IMessage>(); |
||||
|
ISubscriber<IMessage> sub1 = new ConsoleSubscriber<IMessage>(); |
||||
|
ISubscriber<IMessage> sub2 = new ColoredConsoleSubscriber<IMessage>(); |
||||
|
pub.Subscribe(sub1); |
||||
|
pub.Subscribe(sub2); |
||||
|
return pub; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private static IPublisher<IMessage> h_fixedClasses() |
||||
|
{ |
||||
|
IPublisher<IMessage> pub = new MsgPublisher(); |
||||
|
ISubscriber<IMessage> sub1 = new MsgConsoleSubscriber(); |
||||
|
ISubscriber<IMessage> sub2 = new MsgColoredConsoleSubscriber(); |
||||
|
pub.Subscribe(sub1); |
||||
|
pub.Subscribe(sub2); |
||||
|
return pub; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
@ -0,0 +1,9 @@ |
|||||
|
namespace ConsoleApp1.intf |
||||
|
{ |
||||
|
public interface IMessage |
||||
|
{ |
||||
|
DateTime EventDate { get; set; } |
||||
|
string Category { get; set; } |
||||
|
string Text { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
using ConsoleApp1.pubsub; |
||||
|
|
||||
|
namespace ConsoleApp1.intf |
||||
|
{ |
||||
|
|
||||
|
public interface IPublisher<TMsgType> |
||||
|
where TMsgType : IMessage |
||||
|
{ |
||||
|
void Publish(TMsgType message); |
||||
|
void Subscribe(ISubscriber<TMsgType> subscriber); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
namespace ConsoleApp1.intf |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
public interface ISubscriber<TMsgType> |
||||
|
where TMsgType : IMessage |
||||
|
{ |
||||
|
void FireEvent(TMsgType message); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<OutputType>Exe</OutputType> |
||||
|
<TargetFramework>net6.0</TargetFramework> |
||||
|
<ImplicitUsings>enable</ImplicitUsings> |
||||
|
<Nullable>enable</Nullable> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,16 @@ |
|||||
|
using ConsoleApp1.intf; |
||||
|
|
||||
|
namespace ConsoleApp1.pubsub |
||||
|
{ |
||||
|
public class Message : IMessage |
||||
|
{ |
||||
|
public DateTime EventDate { get; set; } |
||||
|
|
||||
|
public string Category { get; set; } |
||||
|
public string Text { get; set; } |
||||
|
public override string ToString() |
||||
|
{ |
||||
|
return $"[{EventDate:D}] [{Category}] {Text}"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
using ConsoleApp1.intf; |
||||
|
using ConsoleApp1.pubsub.generics; |
||||
|
|
||||
|
namespace ConsoleApp1.pubsub |
||||
|
{ |
||||
|
public class MsgColoredConsoleSubscriber : Subscriber<IMessage> |
||||
|
{ |
||||
|
protected override void ObjFire(IMessage sMsg) |
||||
|
{ |
||||
|
var cc = Console.ForegroundColor; |
||||
|
var newcc = cc; |
||||
|
|
||||
|
if (sMsg.Category.Contains("EXCEPTION", StringComparison.CurrentCultureIgnoreCase)) |
||||
|
{ |
||||
|
newcc = ConsoleColor.Red; |
||||
|
} |
||||
|
else |
||||
|
if (sMsg.Category.Contains("INFO", StringComparison.CurrentCultureIgnoreCase)) |
||||
|
{ |
||||
|
newcc = ConsoleColor.Green; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
Console.ForegroundColor = newcc; |
||||
|
Console.WriteLine(sMsg); |
||||
|
Console.ForegroundColor = cc; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
using ConsoleApp1.intf; |
||||
|
using ConsoleApp1.pubsub.generics; |
||||
|
|
||||
|
namespace ConsoleApp1.pubsub |
||||
|
{ |
||||
|
public class MsgConsoleSubscriber: Subscriber<IMessage> |
||||
|
{ |
||||
|
protected override void ObjFire(IMessage sMsg) |
||||
|
{ |
||||
|
Console.WriteLine(sMsg?.Text); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,37 @@ |
|||||
|
using ConsoleApp1.intf; |
||||
|
|
||||
|
namespace ConsoleApp1.pubsub.generics |
||||
|
{ |
||||
|
internal class MsgPublisher : IPublisher<IMessage> |
||||
|
{ |
||||
|
public List<ISubscriber<IMessage>> _subscribers = new List<ISubscriber<IMessage>>(); |
||||
|
|
||||
|
public void Publish(IMessage message) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(message?.Text)) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
if (_subscribers.Count == 0) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
// ...
|
||||
|
// ...
|
||||
|
// ...
|
||||
|
foreach (ISubscriber<IMessage>? subscriber in _subscribers) |
||||
|
{ |
||||
|
if (subscriber == null) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
subscriber?.FireEvent(message); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void Subscribe(ISubscriber<IMessage> subscriber) |
||||
|
{ |
||||
|
_subscribers.Add(subscriber); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
using ConsoleApp1.intf; |
||||
|
|
||||
|
namespace ConsoleApp1.pubsub |
||||
|
{ |
||||
|
public abstract class MsgSubscriber : ISubscriber<IMessage> |
||||
|
{ |
||||
|
public void FireEvent(IMessage message) |
||||
|
{ |
||||
|
if (message == null) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
if (String.IsNullOrEmpty(message.Text)) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
string sMsg = $"{DateTime.Now:D} {message.ToString()}"; |
||||
|
message.Text = sMsg; |
||||
|
ObjFire(message); |
||||
|
} |
||||
|
|
||||
|
protected abstract void ObjFire(IMessage sMsg); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
using ConsoleApp1.intf; |
||||
|
|
||||
|
namespace ConsoleApp1.pubsub.generics |
||||
|
{ |
||||
|
public class ColoredConsoleSubscriber<T> : Subscriber<T> |
||||
|
where T : IMessage |
||||
|
{ |
||||
|
protected override void ObjFire(T sMsg) |
||||
|
{ |
||||
|
var cc = Console.ForegroundColor; |
||||
|
var newcc = cc; |
||||
|
|
||||
|
if (sMsg.Category.Contains("EXCEPTION", StringComparison.CurrentCultureIgnoreCase)) |
||||
|
{ |
||||
|
newcc = ConsoleColor.Red; |
||||
|
} |
||||
|
else |
||||
|
if (sMsg.Category.Contains("INFO", StringComparison.CurrentCultureIgnoreCase)) |
||||
|
{ |
||||
|
newcc = ConsoleColor.Green; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
Console.ForegroundColor = newcc; |
||||
|
Console.WriteLine(sMsg); |
||||
|
Console.ForegroundColor = cc; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
using ConsoleApp1.intf; |
||||
|
|
||||
|
namespace ConsoleApp1.pubsub.generics |
||||
|
{ |
||||
|
|
||||
|
public class ConsoleSubscriber<T> : Subscriber<T>, ISubscriber<T> |
||||
|
where T : IMessage |
||||
|
{ |
||||
|
|
||||
|
protected override void ObjFire(T sMsg) |
||||
|
{ |
||||
|
Console.WriteLine(sMsg?.Text); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
using ConsoleApp1.intf; |
||||
|
|
||||
|
namespace ConsoleApp1.pubsub.generics |
||||
|
{ |
||||
|
internal class Publisher<T> : IPublisher<T> |
||||
|
where T : IMessage |
||||
|
{ |
||||
|
public List<ISubscriber<T>> _subscribers = new List<ISubscriber<T>>(); |
||||
|
|
||||
|
public void Publish(T message) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(message?.Text)) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
if (_subscribers.Count == 0) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
// ...
|
||||
|
// ...
|
||||
|
// ...
|
||||
|
foreach (ISubscriber<T>? subscriber in _subscribers) |
||||
|
{ |
||||
|
if (subscriber == null) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
subscriber?.FireEvent(message); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void Subscribe(ISubscriber<T> subscriber) |
||||
|
{ |
||||
|
_subscribers.Add(subscriber); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
using ConsoleApp1.intf; |
||||
|
|
||||
|
namespace ConsoleApp1.pubsub.generics |
||||
|
{ |
||||
|
|
||||
|
public abstract class Subscriber<T> : ISubscriber<T> |
||||
|
where T : IMessage |
||||
|
{ |
||||
|
public void FireEvent(T message) |
||||
|
{ |
||||
|
if (message == null) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
if (string.IsNullOrEmpty(message.Text)) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
ObjFire(message); |
||||
|
} |
||||
|
|
||||
|
protected abstract void ObjFire(T sMsg); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,37 @@ |
|||||
|
using System.Text; |
||||
|
|
||||
|
namespace ConsoleApp1.report |
||||
|
{ |
||||
|
public class HtmlReportFormatter : IReportFormatter |
||||
|
{ |
||||
|
public byte[] PrepareReport(IReportContent report) |
||||
|
{ |
||||
|
StringBuilder sb = new StringBuilder(); |
||||
|
sb.AppendLine("<HTML><BODY>"); |
||||
|
sb.AppendLine($"<H1>{report.ReportDate}</H1"); |
||||
|
sb.AppendLine("<TABLE>"); |
||||
|
foreach (var row in report.ReportRows) |
||||
|
{ |
||||
|
sb.AppendLine("<TR>"); |
||||
|
foreach (var cell in row.cells) |
||||
|
{ |
||||
|
sb.AppendLine("<TD>"); |
||||
|
h_Format(sb, cell); |
||||
|
sb.AppendLine("</TD>"); |
||||
|
|
||||
|
} |
||||
|
sb.AppendLine("</TR>"); |
||||
|
} |
||||
|
sb.AppendLine("</TABLE>"); |
||||
|
sb.AppendLine("</BODY></HTML>"); |
||||
|
return Encoding.UTF8.GetBytes(sb.ToString()); |
||||
|
} |
||||
|
|
||||
|
private void h_Format(StringBuilder sb, string cell) |
||||
|
{ |
||||
|
sb.AppendLine(cell); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
namespace ConsoleApp1.report |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
public interface IReportContent |
||||
|
{ |
||||
|
string ReportDate { get; set; } |
||||
|
Dictionary<string, string> Data { get; set; } |
||||
|
List<ReportRow> ReportRows { get; set; } |
||||
|
|
||||
|
void Print(HtmlReportFormatter formatter); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
namespace ConsoleApp1.report |
||||
|
{ |
||||
|
public interface IReportFormatter |
||||
|
{ |
||||
|
byte[] PrepareReport(IReportContent report); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
namespace ConsoleApp1.report |
||||
|
{ |
||||
|
|
||||
|
public interface IUserViewerReportFacade |
||||
|
{ |
||||
|
public IReportContent FillReportFromReader( |
||||
|
IReportReader reader); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
public interface IUserExporterReportFacade |
||||
|
{ |
||||
|
public byte[] PrepareReport( |
||||
|
IReportFormatter formatter, |
||||
|
IReportContent report); |
||||
|
} |
||||
|
|
||||
|
public interface IReportReader |
||||
|
{ |
||||
|
void FillReport(IReportContent report); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
namespace ConsoleApp1.report |
||||
|
{ |
||||
|
|
||||
|
public class ReportContent : IReportContent |
||||
|
{ |
||||
|
public string ReportDate { get; set; } |
||||
|
public Dictionary<string, string> Data { get; set; } = new Dictionary<string, string>(); |
||||
|
public List<ReportRow> ReportRows { get; set; } = new List<ReportRow>(); |
||||
|
|
||||
|
public void Print(HtmlReportFormatter formatter) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
namespace ConsoleApp1.report |
||||
|
{ |
||||
|
public class ReportFormatter : IReportFormatter |
||||
|
{ |
||||
|
public byte[] PrepareReport(IReportContent report) |
||||
|
{ |
||||
|
// TODO
|
||||
|
return new byte[0]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
namespace ConsoleApp1.report |
||||
|
{ |
||||
|
public class ReportReaderMongo : IReportReader |
||||
|
{ |
||||
|
public void FillReport(IReportContent report) |
||||
|
{ |
||||
|
// TODO
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class ReportReaderPgsql : IReportReader |
||||
|
{ |
||||
|
public void FillReport(IReportContent report) |
||||
|
{ |
||||
|
// TODO
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
namespace ConsoleApp1.report |
||||
|
{ |
||||
|
public class ReportRow |
||||
|
{ |
||||
|
public List<string> cells = new List<string>(); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue