From 3237dc51e9ab181f4cb0512e38f5e0c3d410b6dc Mon Sep 17 00:00:00 2001 From: "Frank R. Haugen" Date: Fri, 5 Jan 2024 10:48:07 +0100 Subject: [PATCH] Update codebase and remove files Several changes have included updating test project and pulse logger class, also deleting several scripts, 'Frank.PulseFlow.Sample' project, '.gitignore', and 'Directory.Build.props'. These changes streamline the project, increase code readability and improve logging mechanism. The removal of unnecessary files and scripts reduces clutter, enhancing maintainability. --- Frank.PulseFlow.Logging/LogPulse.cs | 66 ++- Frank.PulseFlow.Logging/PulseFlowLogger.cs | 35 +- .../PulseFlowLoggerProvider.cs | 30 ++ .../PulseFlowLoggerScope.cs | 16 + .../ServiceCollectionExtensions.cs | 1 + Frank.PulseFlow.Sample/.gitignore | 454 ------------------ Frank.PulseFlow.Sample/Directory.Build.props | 6 - .../Frank.PulseFlow.Sample.sln | 54 --- .../Frank.PulseFlow.Tests.csproj | 2 + Frank.PulseFlow.Tests/PulseFlowTests.cs | 21 +- Frank.PulseFlow/BasePulse.cs | 3 + Frank.PulseFlow/Internal/Channel.cs | 10 + Frank.PulseFlow/Internal/Conduit.cs | 19 +- Frank.PulseFlow/Internal/FlowBuilder.cs | 7 + Frank.PulseFlow/Internal/IChannel.cs | 11 + Frank.PulseFlow/Internal/PulseNexus.cs | 11 + build.ps1 | 17 - pack.ps1 | 30 -- publish.ps1 | 24 - restore.ps1 | 12 - test.ps1 | 12 - 21 files changed, 213 insertions(+), 628 deletions(-) delete mode 100644 Frank.PulseFlow.Sample/.gitignore delete mode 100644 Frank.PulseFlow.Sample/Directory.Build.props delete mode 100644 Frank.PulseFlow.Sample/Frank.PulseFlow.Sample.sln delete mode 100644 build.ps1 delete mode 100644 pack.ps1 delete mode 100644 publish.ps1 delete mode 100644 restore.ps1 delete mode 100644 test.ps1 diff --git a/Frank.PulseFlow.Logging/LogPulse.cs b/Frank.PulseFlow.Logging/LogPulse.cs index 7a1c6f0..118a3c4 100644 --- a/Frank.PulseFlow.Logging/LogPulse.cs +++ b/Frank.PulseFlow.Logging/LogPulse.cs @@ -2,24 +2,76 @@ namespace Frank.PulseFlow.Logging; -public class LogPulse : BasePulse +/// +/// Represents a log pulse. +/// +public class LogPulse : BasePulse { + /// + /// Gets the log level of the application. + /// + /// The log level. public LogLevel LogLevel { get; } + + /// + /// Gets the unique identifier of an event. + /// public EventId EventId { get; } + + /// + /// Gets the exception associated with the property. + /// + /// + /// The exception associated with the property, or null if no exception occurred. + /// public Exception? Exception { get; } + + /// + /// Gets the name of the category. + /// + /// The name of the category. public string CategoryName { get; } - public TState State { get; } - public Func Formatter { get; } - public LogPulse(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter, string categoryName) + /// + /// Gets the message associated with this property. + /// + public string Message { get; } + + /// + /// Gets the state of the object. + /// + /// + /// The state is represented as a collection of key-value pairs, where the key is a string and the value is an object. + /// The state is read-only and can be null if there is no state available. + /// + /// A read-only list of key-value pairs representing the state of the object. + public IReadOnlyList>? State { get; } + + /// + /// Represents a log pulse, which encapsulates information about a log event. + /// + /// The level of the log event. + /// The identifier of the log event. + /// The exception associated with the log event, if any. + /// The name of the log category. + /// The log message. + public LogPulse(LogLevel logLevel, EventId eventId, Exception? exception, string categoryName, string message) { LogLevel = logLevel; EventId = eventId; - State = state; Exception = exception; - Formatter = formatter; CategoryName = categoryName; + Message = message; } - public override string ToString() => Formatter(State, Exception); + /// + /// Returns a string representation of the object. + /// + /// + /// A string representing the object. The string consists of the log level, + /// event ID, category name, message, and exception, formatted in the following way: + /// [LogLevel] (EventId) CategoryName: 'Message' + /// Exception + /// + public override string ToString() => $"[{LogLevel}] ({EventId}) {CategoryName}: '{Message}'\n\t{Exception}"; } diff --git a/Frank.PulseFlow.Logging/PulseFlowLogger.cs b/Frank.PulseFlow.Logging/PulseFlowLogger.cs index 1482d15..98be93f 100644 --- a/Frank.PulseFlow.Logging/PulseFlowLogger.cs +++ b/Frank.PulseFlow.Logging/PulseFlowLogger.cs @@ -3,12 +3,21 @@ namespace Frank.PulseFlow.Logging; +/// +/// Implementation of ILogger interface that logs messages using pulse flow. +/// public class PulseFlowLogger : ILogger { private readonly string _categoryName; private readonly IConduit _conduit; private readonly IOptionsMonitor _filterOptions; + /// + /// Initializes a new instance of the PulseFlowLogger class with the specified category name, conduit, and filter options. + /// + /// The category name of the logger. + /// The conduit used for logging. + /// The options monitor for logger filter options. public PulseFlowLogger(string categoryName, IConduit conduit, IOptionsMonitor filterOptions) { _categoryName = categoryName; @@ -16,9 +25,23 @@ public PulseFlowLogger(string categoryName, IConduit conduit, IOptionsMonitor + /// Logs a message with the specified log level, event ID, state, exception, and formatter. + /// + /// The type of the state object. + /// The log level. + /// The event ID associated with the log entry. + /// The state object. + /// The exception associated with the log entry. + /// A function that formats the log message. public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) - => _conduit.SendAsync(new LogPulse(logLevel, eventId, state, exception, formatter, _categoryName)).GetAwaiter().GetResult(); + => _conduit.SendAsync(new LogPulse(logLevel, eventId, exception, _categoryName, formatter.Invoke(state, exception))).GetAwaiter().GetResult(); + /// + /// Checks if logging is enabled for the specified log level. + /// + /// The log level to check. + /// Returns true if logging is enabled for the specified log level, otherwise false. public bool IsEnabled(LogLevel logLevel) { // If LogLevel is None, logging is disabled. @@ -39,5 +62,15 @@ public bool IsEnabled(LogLevel logLevel) return logLevel >= filterOptions.MinLevel; } + /// + /// Begins a new log scope with the specified state. + /// + /// The type of the state. + /// The state object for the log scope. + /// An object that represents the log scope. Dispose this object to end the log scope. + /// + /// The log scope allows grouping related log entries together. + /// + /// public IDisposable? BeginScope(TState state) where TState : notnull => new PulseFlowLoggerScope(state); } \ No newline at end of file diff --git a/Frank.PulseFlow.Logging/PulseFlowLoggerProvider.cs b/Frank.PulseFlow.Logging/PulseFlowLoggerProvider.cs index cc25f10..1dae608 100644 --- a/Frank.PulseFlow.Logging/PulseFlowLoggerProvider.cs +++ b/Frank.PulseFlow.Logging/PulseFlowLoggerProvider.cs @@ -5,20 +5,50 @@ namespace Frank.PulseFlow.Logging; +/// +/// Provides instances of PulseFlowLogger. +/// public class PulseFlowLoggerProvider : ILoggerProvider { private readonly IConduit _conduit; private readonly IOptionsMonitor _filterOptions; private readonly ConcurrentDictionary _loggers = new(); + /// + /// Represents a PulseFlowLoggerProvider object that provides logging services for PulseFlow application. + /// + /// + /// This class is responsible for initializing and configuring the PulseFlow logger provider. It takes an IConduit object and an IOptionsMonitor{LoggerFilterOptions} object as input + /// parameters. + /// + /// An IConduit object that represents the conduit for transmitting logs. + /// An IOptionsMonitor{LoggerFilterOptions} object that represents the various options for filtering logs. + /// Thrown when either conduit or filterOptions is null. + /// + /// + /// IConduit conduit = new MyConduit(); + /// IOptionsMonitor{LoggerFilterOptions} filterOptions = new MyFilterOptions(); + /// PulseFlowLoggerProvider loggerProvider = new PulseFlowLoggerProvider(conduit, filterOptions); + /// + /// public PulseFlowLoggerProvider(IConduit conduit, IOptionsMonitor filterOptions) { _conduit = conduit; _filterOptions = filterOptions; } + /// + /// Disposes the resources used by the object and clears all the loggers. + /// public void Dispose() => _loggers.Clear(); + /// + /// Creates a new instance of ILogger for the specified category name. + /// + /// The name of the category to create the logger for. + /// + /// The ILogger instance for the specified category name. + /// public ILogger CreateLogger(string categoryName) => // ReSharper disable once HeapView.CanAvoidClosure _loggers.GetOrAdd(categoryName, name => new PulseFlowLogger(name, _conduit, _filterOptions)); diff --git a/Frank.PulseFlow.Logging/PulseFlowLoggerScope.cs b/Frank.PulseFlow.Logging/PulseFlowLoggerScope.cs index c67d400..4e7d615 100644 --- a/Frank.PulseFlow.Logging/PulseFlowLoggerScope.cs +++ b/Frank.PulseFlow.Logging/PulseFlowLoggerScope.cs @@ -1,10 +1,26 @@ namespace Frank.PulseFlow.Logging; +/// +/// Represents a logger scope that can pulse flow and logs a state of type . +/// +/// The type of the state to be logged. public class PulseFlowLoggerScope : IDisposable { + /// + /// Gets or sets the state of the object. + /// + /// The type of the state. + /// The current state of the object. public TState? State { get; private set; } + /// + /// Initializes a new instance of the class with the specified state. + /// + /// The state to assign to the logger scope. public PulseFlowLoggerScope(TState state) => State = state; + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting resources. + /// public void Dispose() => State = default; } \ No newline at end of file diff --git a/Frank.PulseFlow.Logging/ServiceCollectionExtensions.cs b/Frank.PulseFlow.Logging/ServiceCollectionExtensions.cs index 7435767..0ea9f14 100644 --- a/Frank.PulseFlow.Logging/ServiceCollectionExtensions.cs +++ b/Frank.PulseFlow.Logging/ServiceCollectionExtensions.cs @@ -13,6 +13,7 @@ public static class LoggingBuilderExtensions public static ILoggingBuilder AddPulseFlow(this ILoggingBuilder builder) { builder.Services.AddSingleton(); + return builder; } } \ No newline at end of file diff --git a/Frank.PulseFlow.Sample/.gitignore b/Frank.PulseFlow.Sample/.gitignore deleted file mode 100644 index 8afdcb6..0000000 --- a/Frank.PulseFlow.Sample/.gitignore +++ /dev/null @@ -1,454 +0,0 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Mono auto generated files -mono_crash.* - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Ww][Ii][Nn]32/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ -[Ll]ogs/ - -# Visual Studio 2015/2017 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# Visual Studio 2017 auto generated files -Generated\ Files/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUnit -*.VisualState.xml -TestResult.xml -nunit-*.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ - -# Tye -.tye/ - -# ASP.NET Scaffolding -ScaffoldingReadMe.txt - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Coverlet is a free, cross platform Code Coverage Tool -coverage*.json -coverage*.xml -coverage*.info - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# NuGet Symbol Packages -*.snupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx -*.appxbundle -*.appxupload - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- [Bb]ackup.rdl -*- [Bb]ackup ([0-9]).rdl -*- [Bb]ackup ([0-9][0-9]).rdl - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat -node_modules/ - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# CodeRush personal settings -.cr/personal - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Tabs Studio -*.tss - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs - -# OpenCover UI analysis results -OpenCover/ - -# Azure Stream Analytics local run output -ASALocalRun/ - -# MSBuild Binary and Structured Log -*.binlog - -# NVidia Nsight GPU debugger configuration file -*.nvuser - -# MFractors (Xamarin productivity tool) working folder -.mfractor/ - -# Local History for Visual Studio -.localhistory/ - -# BeatPulse healthcheck temp database -healthchecksdb - -# Backup folder for Package Reference Convert tool in Visual Studio 2017 -MigrationBackup/ - -# Ionide (cross platform F# VS Code tools) working folder -.ionide/ - -# Fody - auto-generated XML schema -FodyWeavers.xsd - -## -## Visual studio for Mac -## - - -# globs -Makefile.in -*.userprefs -*.usertasks -config.make -config.status -aclocal.m4 -install-sh -autom4te.cache/ -*.tar.gz -tarballs/ -test-results/ - -# Mac bundle stuff -*.dmg -*.app - -# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore -# General -.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore -# Windows thumbnail cache files -Thumbs.db -ehthumbs.db -ehthumbs_vista.db - -# Dump file -*.stackdump - -# Folder config file -[Dd]esktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msix -*.msm -*.msp - -# Windows shortcuts -*.lnk - -# JetBrains Rider -.idea/ -*.sln.iml - -## -## Visual Studio Code -## -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json diff --git a/Frank.PulseFlow.Sample/Directory.Build.props b/Frank.PulseFlow.Sample/Directory.Build.props deleted file mode 100644 index b7d1f09..0000000 --- a/Frank.PulseFlow.Sample/Directory.Build.props +++ /dev/null @@ -1,6 +0,0 @@ - - - enable - 11.0.6 - - diff --git a/Frank.PulseFlow.Sample/Frank.PulseFlow.Sample.sln b/Frank.PulseFlow.Sample/Frank.PulseFlow.Sample.sln deleted file mode 100644 index b96b9e6..0000000 --- a/Frank.PulseFlow.Sample/Frank.PulseFlow.Sample.sln +++ /dev/null @@ -1,54 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.3.32811.315 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Frank.PulseFlow.Sample", "Frank.PulseFlow.Sample\Frank.PulseFlow.Sample.csproj", "{EBFA8512-1EA5-4D8C-B4AC-AB5B48A6D568}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Frank.PulseFlow.Sample.Desktop", "Frank.PulseFlow.Sample.Desktop\Frank.PulseFlow.Sample.Desktop.csproj", "{ABC31E74-02FF-46EB-B3B2-4E6AE43B456C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Frank.PulseFlow.Sample.Browser", "Frank.PulseFlow.Sample.Browser\Frank.PulseFlow.Sample.Browser.csproj", "{1C1A049E-235C-4CD0-B6FA-D53AC418F4DA}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Frank.PulseFlow.Sample.iOS", "Frank.PulseFlow.Sample.iOS\Frank.PulseFlow.Sample.iOS.csproj", "{EBD9022F-BC83-4846-9A11-6F7F3772DC64}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Frank.PulseFlow.Sample.Android", "Frank.PulseFlow.Sample.Android\Frank.PulseFlow.Sample.Android.csproj", "{7AD1DAC8-7FBE-49D5-8614-7321233DB82E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3DA99C4E-89E3-4049-9C22-0A7EC60D83D8}" - ProjectSection(SolutionItems) = preProject - Directory.Build.props = Directory.Build.props - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {EBFA8512-1EA5-4D8C-B4AC-AB5B48A6D568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EBFA8512-1EA5-4D8C-B4AC-AB5B48A6D568}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EBFA8512-1EA5-4D8C-B4AC-AB5B48A6D568}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EBFA8512-1EA5-4D8C-B4AC-AB5B48A6D568}.Release|Any CPU.Build.0 = Release|Any CPU - {ABC31E74-02FF-46EB-B3B2-4E6AE43B456C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ABC31E74-02FF-46EB-B3B2-4E6AE43B456C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {ABC31E74-02FF-46EB-B3B2-4E6AE43B456C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {ABC31E74-02FF-46EB-B3B2-4E6AE43B456C}.Release|Any CPU.Build.0 = Release|Any CPU - {1C1A049E-235C-4CD0-B6FA-D53AC418F4DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1C1A049E-235C-4CD0-B6FA-D53AC418F4DA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1C1A049E-235C-4CD0-B6FA-D53AC418F4DA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1C1A049E-235C-4CD0-B6FA-D53AC418F4DA}.Release|Any CPU.Build.0 = Release|Any CPU - {EBD9022F-BC83-4846-9A11-6F7F3772DC64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EBD9022F-BC83-4846-9A11-6F7F3772DC64}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EBD9022F-BC83-4846-9A11-6F7F3772DC64}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EBD9022F-BC83-4846-9A11-6F7F3772DC64}.Release|Any CPU.Build.0 = Release|Any CPU - {7AD1DAC8-7FBE-49D5-8614-7321233DB82E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7AD1DAC8-7FBE-49D5-8614-7321233DB82E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7AD1DAC8-7FBE-49D5-8614-7321233DB82E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7AD1DAC8-7FBE-49D5-8614-7321233DB82E}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {83CB65B8-011F-4ED7-BCD3-A6CFA935EF7E} - EndGlobalSection -EndGlobal diff --git a/Frank.PulseFlow.Tests/Frank.PulseFlow.Tests.csproj b/Frank.PulseFlow.Tests/Frank.PulseFlow.Tests.csproj index 0bc059d..0f8273c 100644 --- a/Frank.PulseFlow.Tests/Frank.PulseFlow.Tests.csproj +++ b/Frank.PulseFlow.Tests/Frank.PulseFlow.Tests.csproj @@ -1,11 +1,13 @@ + net8.0 true false + diff --git a/Frank.PulseFlow.Tests/PulseFlowTests.cs b/Frank.PulseFlow.Tests/PulseFlowTests.cs index e2453ca..dca98cd 100644 --- a/Frank.PulseFlow.Tests/PulseFlowTests.cs +++ b/Frank.PulseFlow.Tests/PulseFlowTests.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging; using Xunit.Abstractions; +using Frank.Reflection; namespace Frank.PulseFlow.Tests; @@ -33,7 +34,15 @@ private class MyService : BackgroundService protected override async Task ExecuteAsync(CancellationToken stoppingToken) { - _logger.LogInformation("Hello from MyService"); + _logger.LogInformation("Hello from {ServiceName}", nameof(MyService)); + try + { + throw new Exception("This is an exception"); + } + catch (Exception e) + { + _logger.LogError(e, "This is an exception in {ServiceName}", nameof(MyService)); + } await Task.Delay(1000, stoppingToken); } } @@ -69,10 +78,16 @@ public TestOutputFlow(ITestOutputHelper outputHelper) public async Task HandleAsync(IPulse pulse, CancellationToken cancellationToken) { - var message = pulse.ToString(); + var thing = pulse as LogPulse; + var message = thing!.ToString(); _outputHelper.WriteLine(message); + await Task.CompletedTask; } - public bool CanHandle(Type pulseType) => true; + public bool CanHandle(Type pulseType) + { + _outputHelper.WriteLine($"CanHandle: {pulseType.GetFriendlyName()}"); + return pulseType.BaseType == typeof(LogPulse); + } } } \ No newline at end of file diff --git a/Frank.PulseFlow/BasePulse.cs b/Frank.PulseFlow/BasePulse.cs index fe831df..06da755 100644 --- a/Frank.PulseFlow/BasePulse.cs +++ b/Frank.PulseFlow/BasePulse.cs @@ -1,5 +1,8 @@ namespace Frank.PulseFlow; +/// +/// Represents a base pulse. +/// public abstract class BasePulse : IPulse { /// diff --git a/Frank.PulseFlow/Internal/Channel.cs b/Frank.PulseFlow/Internal/Channel.cs index 4278e74..4a8a904 100644 --- a/Frank.PulseFlow/Internal/Channel.cs +++ b/Frank.PulseFlow/Internal/Channel.cs @@ -9,7 +9,17 @@ internal class Channel : IChannel { private readonly Channel _channel = System.Threading.Channels.Channel.CreateUnbounded(); + /// + /// Sends the provided IPulse message asynchronously. + /// + /// The IPulse message to send. + /// A Task representing the asynchronous operation. public async Task SendAsync(IPulse message) => await _channel.Writer.WriteAsync(message); + /// + /// Reads all available pulses asynchronously from the channel. + /// + /// The cancellation token to cancel the operation. + /// An asynchronous enumerable of IPulse objects. public IAsyncEnumerable ReadAllAsync(CancellationToken cancellationToken) => _channel.Reader.ReadAllAsync(cancellationToken); } \ No newline at end of file diff --git a/Frank.PulseFlow/Internal/Conduit.cs b/Frank.PulseFlow/Internal/Conduit.cs index 1ecce12..476dfa3 100644 --- a/Frank.PulseFlow/Internal/Conduit.cs +++ b/Frank.PulseFlow/Internal/Conduit.cs @@ -7,13 +7,16 @@ internal class Conduit : IConduit { private readonly IChannel _messageChannel; - public Conduit(IChannel messageChannel) - { - _messageChannel = messageChannel; - } + /// + /// Represents a conduit for message communication between channels. + /// + /// The channel used for message communication. + public Conduit(IChannel messageChannel) => _messageChannel = messageChannel; - public Task SendAsync(IPulse message) - { - return _messageChannel.SendAsync(message); - } + /// + /// Sends a pulse message asynchronously. + /// + /// The pulse message to be sent. + /// A task representing the asynchronous operation. + public Task SendAsync(IPulse message) => _messageChannel.SendAsync(message); } \ No newline at end of file diff --git a/Frank.PulseFlow/Internal/FlowBuilder.cs b/Frank.PulseFlow/Internal/FlowBuilder.cs index 6d2c56e..7d161bb 100644 --- a/Frank.PulseFlow/Internal/FlowBuilder.cs +++ b/Frank.PulseFlow/Internal/FlowBuilder.cs @@ -2,10 +2,17 @@ namespace Frank.PulseFlow.Internal; +/// +/// Represents a builder for configuring the pulse flow. +/// internal class FlowBuilder : IFlowBuilder { private readonly IServiceCollection _services; + /// + /// Creates a new instance of the FlowBuilder class with the specified services. + /// + /// The services collection used for dependency injection. public FlowBuilder(IServiceCollection services) => _services = services; /// diff --git a/Frank.PulseFlow/Internal/IChannel.cs b/Frank.PulseFlow/Internal/IChannel.cs index f7fb445..68e78a8 100644 --- a/Frank.PulseFlow/Internal/IChannel.cs +++ b/Frank.PulseFlow/Internal/IChannel.cs @@ -5,6 +5,17 @@ namespace Frank.PulseFlow.Internal; /// internal interface IChannel { + /// + /// Sends an asynchronous pulse message. + /// + /// The pulse message to send. + /// A task representing the asynchronous operation. Task SendAsync(IPulse message); + + /// + /// Reads all available pulses asynchronously. + /// + /// A cancellation token used to cancel the operation. + /// An asynchronous enumerable of IPulse objects. IAsyncEnumerable ReadAllAsync(CancellationToken cancellationToken); } \ No newline at end of file diff --git a/Frank.PulseFlow/Internal/PulseNexus.cs b/Frank.PulseFlow/Internal/PulseNexus.cs index 8585761..01bd93e 100644 --- a/Frank.PulseFlow/Internal/PulseNexus.cs +++ b/Frank.PulseFlow/Internal/PulseNexus.cs @@ -2,17 +2,28 @@ namespace Frank.PulseFlow.Internal; +/// +/// Internal class representing the PulseNexus. +/// internal class PulseNexus : BackgroundService { private readonly IChannel _channel; private readonly IEnumerable _pulseFlows; + /// + /// Represents a class that provides a nexus for pulse flows. + /// public PulseNexus(IChannel channel, IEnumerable pulseFlows) { _channel = channel; _pulseFlows = pulseFlows; } + /// + /// Executes asynchronous tasks for handling pulses. + /// + /// The cancellation token that can be used to stop the execution. + /// A task representing the asynchronous execution. protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await foreach (IPulse pulse in _channel.ReadAllAsync(stoppingToken)) diff --git a/build.ps1 b/build.ps1 deleted file mode 100644 index f54c319..0000000 --- a/build.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -param ( - [Parameter(Mandatory=$false)] - [string]$version = (Get-Date -Format 'yyyy.MM.dd') -) - -# Get directory of the script -$scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Definition - -# Get path to the project file -$projectFile = "$scriptDirectory/Frank.PulseFlow/Frank.PulseFlow.csproj" - -# Build the solution in the specified mode -Write-Host "Building solution in Release mode..." -ForegroundColor DarkCyan -dotnet build $projectFile --configuration Release --no-restore /p:Version=$version | Out-Null - -# Exit with a success code -exit 0 \ No newline at end of file diff --git a/pack.ps1 b/pack.ps1 deleted file mode 100644 index 5a5c859..0000000 --- a/pack.ps1 +++ /dev/null @@ -1,30 +0,0 @@ -param ( - [Parameter(Mandatory=$false)] - [string]$version = (Get-Date -Format 'yyyy.MM.dd') -) - -# Get directory of the script -$scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Definition - -# Get path to the output directory -$outputDirectory = "$scriptDirectory/.artifacts" - -# Get path to the publish directory -$publishDirectory = "$outputDirectory/publish" - -# Get path to the package directory -$packageDirectory = "$outputDirectory/packages" - -# Get path to the project file -$projectFile = "$scriptDirectory/Frank.PulseFlow/Frank.PulseFlow.csproj" - -# Clean output directories -if (Test-Path $publishDirectory) { Remove-Item "$publishDirectory/*" -Recurse } -if (Test-Path $packageDirectory) { Remove-Item "$packageDirectory/*" -Recurse } - -# Pack NuGet packages -Write-Host "Packing NuGet packages..." -ForegroundColor DarkCyan -dotnet pack $projectFile --configuration Release --output $packageDirectory --no-build /p:Version=$version /p:PackageVersion=$version | Out-Null - -# Exit with a success code -exit 0 diff --git a/publish.ps1 b/publish.ps1 deleted file mode 100644 index 1407c1d..0000000 --- a/publish.ps1 +++ /dev/null @@ -1,24 +0,0 @@ -param ( - [Parameter(Mandatory=$false)] - [string]$version = (Get-Date -Format 'yyyy.MM.dd') -) - -# Get directory of the script -$scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Definition - -# Get path to the output directory -$outputDirectory = "$scriptDirectory/.artifacts" - -# Get path to the publish directory -$publishDirectory = "$outputDirectory/publish" - -# Get path to the project file -$projectFile = "$scriptDirectory/Frank.PulseFlow/Frank.PulseFlow.csproj" - -# Publish the solution and pack NuGet packages -Write-Host "Publishing the project..." -ForegroundColor DarkCyan -dotnet publish $projectFile --configuration Release --output $publishDirectory --no-build /p:Version=$version /p:PackageVersion=$version | Out-Null -Write-Host "Project has been published." -ForegroundColor Green - -# Exit with a success code -exit 0 \ No newline at end of file diff --git a/restore.ps1 b/restore.ps1 deleted file mode 100644 index 873b149..0000000 --- a/restore.ps1 +++ /dev/null @@ -1,12 +0,0 @@ -# Get directory of the script -$scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Definition - -# Get path to the project file -$projectFile = "$scriptDirectory/Frank.PulseFlow/Frank.PulseFlow.csproj" - -# Restore NuGet packages -Write-Host "Restoring NuGet packages..." -ForegroundColor Cyan -dotnet restore $projectFile | Out-Null - -# Exit with a success code -exit 0 \ No newline at end of file diff --git a/test.ps1 b/test.ps1 deleted file mode 100644 index 4d2eb0f..0000000 --- a/test.ps1 +++ /dev/null @@ -1,12 +0,0 @@ -# Get the script directory -$scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Definition - -# Get the project file for the test project -$projectFile = "$scriptDirectory/Frank.PulseFlow.Tests/Frank.PulseFlow.Tests.csproj" - -# Test the project -Write-Host "Running unit tests..." -ForegroundColor DarkCyan -dotnet test $projectFile --configuration Release - -# Exit with a success code -exit 0 \ No newline at end of file