Merge branch 'release/1.2'

This commit is contained in:
Mark van Renswoude 2022-01-12 08:54:26 +01:00
commit 2c07c49a1a
57 changed files with 2496 additions and 207 deletions

BIN
Docs/Publish.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
Docs/Subscribe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
Docs/TapetiPublish.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
namespace PettingZoo.Core.Connection
{
@ -10,6 +11,7 @@ namespace PettingZoo.Core.Connection
event EventHandler<MessageReceivedEventArgs>? MessageReceived;
IEnumerable<ReceivedMessageInfo> GetInitialMessages();
void Start();
}

View File

@ -0,0 +1,33 @@
using System;
namespace PettingZoo.Core.ExportImport
{
public abstract class BaseProgressDecorator
{
private static readonly TimeSpan DefaultReportInterval = TimeSpan.FromMilliseconds(100);
private readonly IProgress<int> progress;
private readonly long reportInterval;
private long lastReport;
protected BaseProgressDecorator(IProgress<int> progress, TimeSpan? reportInterval = null)
{
this.progress = progress;
this.reportInterval = (int)(reportInterval ?? DefaultReportInterval).TotalMilliseconds;
}
protected abstract int GetProgress();
protected void UpdateProgress()
{
// Because this method is called pretty frequently, not having DateTime's small overhead is worth it
var now = Environment.TickCount64;
if (now - lastReport < reportInterval)
return;
progress.Report(GetProgress());
lastReport = now;
}
}
}

View File

@ -0,0 +1,22 @@
using System.Collections.Generic;
using System.Linq;
namespace PettingZoo.Core.ExportImport
{
public class ExportImportFormatProvider : IExportImportFormatProvider
{
private readonly List<IExportFormat> exportFormats;
private readonly List<IImportFormat> importFormats;
public IEnumerable<IExportFormat> ExportFormats => exportFormats;
public IEnumerable<IImportFormat> ImportFormats => importFormats;
public ExportImportFormatProvider(params IExportImportFormat[] formats)
{
exportFormats = new List<IExportFormat>(formats.Where(f => f is IExportFormat).Cast<IExportFormat>());
importFormats = new List<IImportFormat>(formats.Where(f => f is IImportFormat).Cast<IImportFormat>());
}
}
}

View File

@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using PettingZoo.Core.Connection;
namespace PettingZoo.Core.ExportImport
{
public interface IExportImportFormat
{
string Filter { get; }
}
public interface IExportFormat : IExportImportFormat
{
Task Export(Stream stream, IEnumerable<ReceivedMessageInfo> messages, CancellationToken cancellationToken);
}
public interface IImportFormat : IExportImportFormat
{
Task<IReadOnlyList<ReceivedMessageInfo>> Import(Stream stream, CancellationToken cancellationToken);
}
}

View File

@ -0,0 +1,10 @@
using System.Collections.Generic;
namespace PettingZoo.Core.ExportImport
{
public interface IExportImportFormatProvider
{
public IEnumerable<IExportFormat> ExportFormats { get; }
public IEnumerable<IImportFormat> ImportFormats { get; }
}
}

View File

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using PettingZoo.Core.Connection;
namespace PettingZoo.Core.ExportImport
{
public class ImportSubscriber : ISubscriber
{
private readonly IReadOnlyList<ReceivedMessageInfo> messages;
public string? QueueName { get; }
public string? Exchange => null;
public string? RoutingKey => null;
public event EventHandler<MessageReceivedEventArgs>? MessageReceived;
public ImportSubscriber(string filename, IReadOnlyList<ReceivedMessageInfo> messages)
{
QueueName = Path.GetFileName(filename);
this.messages = messages;
}
public ValueTask DisposeAsync()
{
GC.SuppressFinalize(this);
return default;
}
public IEnumerable<ReceivedMessageInfo> GetInitialMessages()
{
return messages;
}
public void Start()
{
}
}
}

View File

@ -0,0 +1,100 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace PettingZoo.Core.ExportImport
{
public class ListEnumerableProgressDecorator<T> : BaseProgressDecorator, IEnumerable<T>
{
private readonly IReadOnlyList<T> decoratedList;
private int position;
/// <summary>
/// Wraps an IReadOnlyList and provides reports to the IProgress when it is enumerated.
/// </summary>
/// <param name="decoratedList">The IReadOnlyList to decorate.</param>
/// <param name="progress">Receives progress reports. The value will be a percentage (0 - 100).</param>
/// <param name="reportInterval">The minimum time between reports.</param>
public ListEnumerableProgressDecorator(IReadOnlyList<T> decoratedList, IProgress<int> progress, TimeSpan? reportInterval = null)
: base(progress, reportInterval)
{
this.decoratedList = decoratedList;
}
protected override int GetProgress()
{
return decoratedList.Count > 0
? (int)Math.Truncate((double)position / decoratedList.Count * 100)
: 0;
}
protected void AfterNext()
{
position++;
UpdateProgress();
}
protected void Reset()
{
position = 0;
UpdateProgress();
}
public IEnumerator<T> GetEnumerator()
{
return new EnumerableWrapper(this, decoratedList.GetEnumerator());
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
private class EnumerableWrapper : IEnumerator<T>
{
private readonly ListEnumerableProgressDecorator<T> owner;
private readonly IEnumerator<T> decoratedEnumerator;
public EnumerableWrapper(ListEnumerableProgressDecorator<T> owner, IEnumerator<T> decoratedEnumerator)
{
this.owner = owner;
this.decoratedEnumerator = decoratedEnumerator;
}
public bool MoveNext()
{
var result = decoratedEnumerator.MoveNext();
if (result)
owner.AfterNext();
return result;
}
public void Reset()
{
decoratedEnumerator.Reset();
owner.Reset();
}
public T Current => decoratedEnumerator.Current;
object IEnumerator.Current => decoratedEnumerator.Current!;
public void Dispose()
{
GC.SuppressFinalize(this);
decoratedEnumerator.Dispose();
}
}
}
}

View File

@ -0,0 +1,157 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace PettingZoo.Core.ExportImport
{
public class StreamProgressDecorator : BaseProgressDecorator
{
private readonly StreamWrapper streamWrapper;
public Stream Stream => streamWrapper;
/// <summary>
/// Wraps a Stream and provides reports to the IProgress.
/// </summary>
/// <remarks>
/// Use the Stream property to pass along to the method you want to monitor the progress on.
/// If the consumer seeks around in the stream a lot the progress will not be linear, but that
/// seems to be a trend anyways with progress bars, so enjoy your modern experience!
/// </remarks>
/// <param name="decoratedStream">The stream to decorate.</param>
/// <param name="progress">Receives progress reports. The value will be a percentage (0 - 100).</param>
/// <param name="reportInterval">The minimum time between reports.</param>
public StreamProgressDecorator(Stream decoratedStream, IProgress<int> progress, TimeSpan? reportInterval = null)
: base(progress, reportInterval)
{
streamWrapper = new StreamWrapper(this, decoratedStream);
}
protected override int GetProgress()
{
return streamWrapper.DecoratedStream.Length > 0
? (int)Math.Truncate((double)streamWrapper.DecoratedStream.Position / streamWrapper.DecoratedStream.Length * 100)
: 0;
}
private class StreamWrapper : Stream
{
private readonly StreamProgressDecorator owner;
public readonly Stream DecoratedStream;
public override bool CanRead => DecoratedStream.CanRead;
public override bool CanSeek => DecoratedStream.CanSeek;
public override bool CanWrite => DecoratedStream.CanWrite;
public override long Length => DecoratedStream.Length;
public override long Position
{
get => DecoratedStream.Position;
set => DecoratedStream.Position = value;
}
public StreamWrapper(StreamProgressDecorator owner, Stream decoratedStream)
{
this.owner = owner;
this.DecoratedStream = decoratedStream;
}
public override void Flush()
{
DecoratedStream.Flush();
}
public override Task FlushAsync(CancellationToken cancellationToken)
{
return DecoratedStream.FlushAsync(cancellationToken);
}
public override int Read(byte[] buffer, int offset, int count)
{
var result = DecoratedStream.Read(buffer, offset, count);
owner.UpdateProgress();
return result;
}
public override int Read(Span<byte> buffer)
{
var result = DecoratedStream.Read(buffer);
owner.UpdateProgress();
return result;
}
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
#pragma warning disable CA1835 // Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'
var result = await DecoratedStream.ReadAsync(buffer, offset, count, cancellationToken);
#pragma warning restore CA1835
owner.UpdateProgress();
return result;
}
public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = new())
{
var result = DecoratedStream.ReadAsync(buffer, cancellationToken);
owner.UpdateProgress();
return result;
}
public override long Seek(long offset, SeekOrigin origin)
{
var result = DecoratedStream.Seek(offset, origin);
owner.UpdateProgress();
return result;
}
public override void SetLength(long value)
{
DecoratedStream.SetLength(value);
owner.UpdateProgress();
}
public override void Write(byte[] buffer, int offset, int count)
{
DecoratedStream.Write(buffer, offset, count);
owner.UpdateProgress();
}
public override void Write(ReadOnlySpan<byte> buffer)
{
DecoratedStream.Write(buffer);
owner.UpdateProgress();
}
public override async Task WriteAsync(byte[] buffer, int offset, int count,
CancellationToken cancellationToken)
{
#pragma warning disable CA1835 // Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'
await DecoratedStream.WriteAsync(buffer, offset, count, cancellationToken);
#pragma warning restore CA1835
owner.UpdateProgress();
}
public override async ValueTask WriteAsync(ReadOnlyMemory<byte> buffer,
CancellationToken cancellationToken = new())
{
await DecoratedStream.WriteAsync(buffer, cancellationToken);
owner.UpdateProgress();
}
}
}
}

View File

@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using PettingZoo.Core.Connection;
using RabbitMQ.Client;
@ -38,6 +40,12 @@ namespace PettingZoo.RabbitMQ
}
public IEnumerable<ReceivedMessageInfo> GetInitialMessages()
{
return Enumerable.Empty<ReceivedMessageInfo>();
}
public void Start()
{
started = true;

View File

@ -0,0 +1,47 @@
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using PettingZoo.Core.ExportImport;
namespace PettingZoo.Tapeti.Export
{
public abstract class BaseTapetiCmdExportImportFormat : IExportImportFormat
{
public string Filter => TapetiCmdImportExportStrings.TapetiCmdFilter;
}
// It would be nicer if Tapeti.Cmd exposed it's file format in a NuGet package... if only I knew the author ¯\_(ツ)_/¯
public class SerializableMessage
{
//public ulong DeliveryTag;
//public bool Redelivered;
public string? Exchange;
public string? RoutingKey;
//public string? Queue;
// ReSharper disable once FieldCanBeMadeReadOnly.Local - must be settable by JSON deserialization
public SerializableMessageProperties? Properties;
public JObject? Body;
public byte[]? RawBody;
}
public class SerializableMessageProperties
{
public string? AppId;
//public string? ClusterId;
public string? ContentEncoding;
public string? ContentType;
public string? CorrelationId;
public byte? DeliveryMode;
public string? Expiration;
public IDictionary<string, string>? Headers;
public string? MessageId;
public byte? Priority;
public string? ReplyTo;
public long? Timestamp;
public string? Type;
public string? UserId;
}
}

View File

@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PettingZoo.Core.Connection;
using PettingZoo.Core.ExportImport;
namespace PettingZoo.Tapeti.Export
{
public class TapetiCmdExportFormat : BaseTapetiCmdExportImportFormat, IExportFormat
{
private static readonly JsonSerializerSettings SerializerSettings = new()
{
NullValueHandling = NullValueHandling.Ignore
};
public async Task Export(Stream stream, IEnumerable<ReceivedMessageInfo> messages, CancellationToken cancellationToken)
{
await using var exportFile = new StreamWriter(stream, Encoding.UTF8);
foreach (var message in messages)
{
if (cancellationToken.IsCancellationRequested)
break;
var serializableMessage = new SerializableMessage
{
Exchange = message.Exchange,
RoutingKey = message.RoutingKey,
Properties = new SerializableMessageProperties
{
AppId = message.Properties.AppId,
ContentEncoding = message.Properties.ContentEncoding,
ContentType = message.Properties.ContentType,
CorrelationId = message.Properties.CorrelationId,
DeliveryMode = message.Properties.DeliveryMode switch
{
MessageDeliveryMode.Persistent => 2,
_ => 1
},
Expiration = message.Properties.Expiration,
Headers = message.Properties.Headers.Count > 0 ? message.Properties.Headers.ToDictionary(p => p.Key, p => p.Value) : null,
MessageId = message.Properties.MessageId,
Priority = message.Properties.Priority,
ReplyTo = message.Properties.ReplyTo,
Timestamp = message.Properties.Timestamp.HasValue ? new DateTimeOffset(message.Properties.Timestamp.Value).ToUnixTimeSeconds() : null,
Type = message.Properties.Type,
UserId = message.Properties.UserId
}
};
var useRawBody = true;
if (message.Properties.ContentType == @"application/json")
{
try
{
if (JToken.Parse(Encoding.UTF8.GetString(message.Body)) is JObject jsonBody)
{
serializableMessage.Body = jsonBody;
useRawBody = false;
}
}
catch
{
// Use raw body
}
}
if (useRawBody)
serializableMessage.RawBody = message.Body;
var serialized = JsonConvert.SerializeObject(serializableMessage, SerializerSettings);
await exportFile.WriteLineAsync(serialized);
}
}
}
}

View File

@ -0,0 +1,72 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace PettingZoo.Tapeti.Export {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class TapetiCmdImportExportStrings {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal TapetiCmdImportExportStrings() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PettingZoo.Tapeti.Export.TapetiCmdImportExportStrings", typeof(TapetiCmdImportExportStrings).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Tapeti.Cmd single-file JSON (*.json)|*.json.
/// </summary>
internal static string TapetiCmdFilter {
get {
return ResourceManager.GetString("TapetiCmdFilter", resourceCulture);
}
}
}
}

View File

@ -0,0 +1,123 @@
<?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=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="TapetiCmdFilter" xml:space="preserve">
<value>Tapeti.Cmd single-file JSON (*.json)|*.json</value>
</data>
</root>

View File

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using PettingZoo.Core.Connection;
using PettingZoo.Core.ExportImport;
namespace PettingZoo.Tapeti.Export
{
public class TapetiCmdImportFormat : BaseTapetiCmdExportImportFormat, IImportFormat
{
private const int DefaultBufferSize = 1024;
public async Task<IReadOnlyList<ReceivedMessageInfo>> Import(Stream stream, CancellationToken cancellationToken)
{
var now = DateTime.Now;
using var reader = new StreamReader(stream, Encoding.UTF8, true, DefaultBufferSize, true);
var messages = new List<ReceivedMessageInfo>();
while (!reader.EndOfStream && !cancellationToken.IsCancellationRequested)
{
var serialized = await reader.ReadLineAsync();
if (string.IsNullOrEmpty(serialized))
continue;
var serializableMessage = JsonConvert.DeserializeObject<SerializableMessage>(serialized);
if (serializableMessage == null)
continue;
var body = serializableMessage.Body != null
? Encoding.UTF8.GetBytes(serializableMessage.Body.ToString(Formatting.Indented))
: serializableMessage.RawBody;
var messageTimestamp = serializableMessage.Properties?.Timestamp != null
? DateTimeOffset.FromUnixTimeSeconds(serializableMessage.Properties.Timestamp.Value).LocalDateTime
: now;
messages.Add(new ReceivedMessageInfo(
serializableMessage.Exchange ?? "",
serializableMessage.RoutingKey ?? "",
body ?? Array.Empty<byte>(),
// IReadOnlyDictionary is not compatible with IDictionary? wow.
new MessageProperties(serializableMessage.Properties?.Headers?.ToDictionary(p => p.Key, p => p.Value))
{
AppId = serializableMessage.Properties?.AppId,
ContentEncoding = serializableMessage.Properties?.ContentEncoding,
ContentType = serializableMessage.Properties?.ContentType,
CorrelationId = serializableMessage.Properties?.CorrelationId,
DeliveryMode = serializableMessage.Properties?.DeliveryMode switch
{
2 => MessageDeliveryMode.Persistent,
_ => MessageDeliveryMode.NonPersistent
},
Expiration = serializableMessage.Properties?.Expiration,
MessageId = serializableMessage.Properties?.MessageId,
Priority = serializableMessage.Properties?.Priority,
ReplyTo = serializableMessage.Properties?.ReplyTo,
Timestamp = messageTimestamp,
Type = serializableMessage.Properties?.Type,
UserId = serializableMessage.Properties?.UserId
},
messageTimestamp));
}
return messages;
}
}
}

View File

@ -32,19 +32,21 @@
<AutoGen>True</AutoGen>
<DependentUpon>AssemblyParserStrings.resx</DependentUpon>
</Compile>
<Compile Update="Export\TapetiCmdImportExportStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>TapetiCmdImportExportStrings.resx</DependentUpon>
</Compile>
<Compile Update="TapetiClassLibraryExampleGeneratorStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>TapetiClassLibraryExampleGeneratorStrings.resx</DependentUpon>
</Compile>
<Compile Update="UI\ClassSelection\ClassSelectionStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>ClassSelectionStrings.resx</DependentUpon>
</Compile>
<Compile Update="UI\PackageProgress\PackageProgressStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>PackageProgressStrings.resx</DependentUpon>
</Compile>
<Compile Update="UI\PackageProgress\PackageProgressWindow.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="UI\PackageSelection\PackageSelectionStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
@ -57,25 +59,22 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>AssemblyParserStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Export\TapetiCmdImportExportStrings.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>TapetiCmdImportExportStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="TapetiClassLibraryExampleGeneratorStrings.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>TapetiClassLibraryExampleGeneratorStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="UI\ClassSelection\ClassSelectionStrings.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>ClassSelectionStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="UI\PackageProgress\PackageProgressStrings.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>PackageProgressStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="UI\PackageSelection\PackageSelectionStrings.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>PackageSelectionStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Page Update="UI\PackageProgress\PackageProgressWindow.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
</Project>

View File

@ -0,0 +1,325 @@
<Project>
<PropertyGroup>
<AssemblyName>PettingZoo.Tapeti</AssemblyName>
<IntermediateOutputPath>obj\Debug\</IntermediateOutputPath>
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
<MSBuildProjectExtensionsPath>P:\Development\PettingZoo\PettingZoo.Tapeti\obj\</MSBuildProjectExtensionsPath>
<_TargetAssemblyProjectName>PettingZoo.Tapeti</_TargetAssemblyProjectName>
</PropertyGroup>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<Version>0.1</Version>
<UseWpf>true</UseWpf>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NuGet.PackageManagement" Version="6.0.0" />
<PackageReference Include="NuGet.Packaging" Version="6.0.0" />
<PackageReference Include="NuGet.Protocol" Version="6.0.0" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="SharpVectors" Version="1.7.7" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
<PackageReference Include="System.Reflection.MetadataLoadContext" Version="6.0.0" />
<PackageReference Include="Tapeti.Annotations" Version="3.0.0" />
<PackageReference Include="Tapeti.DataAnnotations.Extensions" Version="3.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PettingZoo.Core\PettingZoo.Core.csproj" />
<ProjectReference Include="..\PettingZoo.WPF\PettingZoo.WPF.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="AssemblyParser\AssemblyParserStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>AssemblyParserStrings.resx</DependentUpon>
</Compile>
<Compile Update="Export\TapetiCmdImportExportStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>TapetiCmdImportExportStrings.resx</DependentUpon>
</Compile>
<Compile Update="TapetiClassLibraryExampleGeneratorStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>TapetiClassLibraryExampleGeneratorStrings.resx</DependentUpon>
</Compile>
<Compile Update="UI\ClassSelection\ClassSelectionStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>ClassSelectionStrings.resx</DependentUpon>
</Compile>
<Compile Update="UI\PackageSelection\PackageSelectionStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>PackageSelectionStrings.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="AssemblyParser\AssemblyParserStrings.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>AssemblyParserStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Export\TapetiCmdImportExportStrings.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>TapetiCmdImportExportStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="TapetiClassLibraryExampleGeneratorStrings.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>TapetiClassLibraryExampleGeneratorStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="UI\ClassSelection\ClassSelectionStrings.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>ClassSelectionStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="UI\PackageSelection\PackageSelectionStrings.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>PackageSelectionStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\Accessibility.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\avalonedit\6.1.3.50\lib\net6.0-windows7.0\ICSharpCode.AvalonEdit.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\Microsoft.CSharp.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\Microsoft.VisualBasic.Core.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\Microsoft.VisualBasic.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\Microsoft.VisualBasic.Forms.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\microsoft.web.xdt\3.0.0\lib\netstandard2.0\Microsoft.Web.XmlTransform.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\Microsoft.Win32.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\Microsoft.Win32.Registry.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\Microsoft.Win32.Registry.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\Microsoft.Win32.SystemEvents.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\mscorlib.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\netstandard.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\newtonsoft.json\13.0.1\lib\netstandard2.0\Newtonsoft.Json.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.commands\6.0.0\lib\net5.0\NuGet.Commands.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.common\6.0.0\lib\netstandard2.0\NuGet.Common.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.configuration\6.0.0\lib\netstandard2.0\NuGet.Configuration.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.credentials\6.0.0\lib\net5.0\NuGet.Credentials.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.dependencyresolver.core\6.0.0\lib\net5.0\NuGet.DependencyResolver.Core.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.frameworks\6.0.0\lib\netstandard2.0\NuGet.Frameworks.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.librarymodel\6.0.0\lib\netstandard2.0\NuGet.LibraryModel.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.packagemanagement\6.0.0\lib\netstandard2.0\NuGet.PackageManagement.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.packaging\6.0.0\lib\net5.0\NuGet.Packaging.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.projectmodel\6.0.0\lib\net5.0\NuGet.ProjectModel.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.protocol\6.0.0\lib\net5.0\NuGet.Protocol.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.resolver\6.0.0\lib\net5.0\NuGet.Resolver.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.versioning\6.0.0\lib\netstandard2.0\NuGet.Versioning.dll" />
<ReferencePath Include="P:\Development\PettingZoo\PettingZoo.Core\bin\Debug\net6.0\PettingZoo.Core.dll" />
<ReferencePath Include="P:\Development\PettingZoo\PettingZoo.WPF\bin\Debug\net6.0-windows\PettingZoo.WPF.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationCore.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.Aero.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.Aero2.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.AeroLite.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.Classic.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.Luna.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.Royale.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationUI.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\ReachFramework.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\serilog\2.10.0\lib\netstandard2.1\Serilog.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Converters.Wpf.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Core.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Css.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Dom.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Model.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Rendering.Gdi.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Rendering.Wpf.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Runtime.Wpf.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.AppContext.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Buffers.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.CodeDom.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Collections.Concurrent.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Collections.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Collections.Immutable.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Collections.NonGeneric.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Collections.Specialized.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.Annotations.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\system.componentmodel.composition\4.5.0\ref\netstandard2.0\System.ComponentModel.Composition.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.DataAnnotations.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.EventBasedAsync.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.TypeConverter.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Configuration.ConfigurationManager.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Configuration.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Console.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Core.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Data.Common.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Data.DataSetExtensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Data.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Design.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.Contracts.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.Debug.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.DiagnosticSource.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Diagnostics.EventLog.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.FileVersionInfo.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Diagnostics.PerformanceCounter.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.Process.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.StackTrace.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.TextWriterTraceListener.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.Tools.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.TraceSource.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.Tracing.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.DirectoryServices.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Drawing.Common.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Drawing.Design.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Drawing.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Drawing.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Dynamic.Runtime.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Formats.Asn1.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Globalization.Calendars.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Globalization.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Globalization.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Compression.Brotli.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Compression.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Compression.FileSystem.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Compression.ZipFile.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.FileSystem.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.FileSystem.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.FileSystem.DriveInfo.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.FileSystem.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.FileSystem.Watcher.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.IsolatedStorage.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.MemoryMappedFiles.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.IO.Packaging.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Pipes.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Pipes.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.UnmanagedMemoryStream.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Linq.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Linq.Expressions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Linq.Parallel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Linq.Queryable.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Memory.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Http.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Http.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.HttpListener.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Mail.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.NameResolution.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.NetworkInformation.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Ping.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Requests.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Security.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.ServicePoint.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Sockets.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.WebClient.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.WebHeaderCollection.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.WebProxy.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.WebSockets.Client.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.WebSockets.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Numerics.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Numerics.Vectors.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ObjectModel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Printing.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\system.reactive\5.0.0\lib\net5.0\System.Reactive.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.DispatchProxy.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Emit.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Emit.ILGeneration.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Emit.Lightweight.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Metadata.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\system.reflection.metadataloadcontext\6.0.0\lib\net6.0\System.Reflection.MetadataLoadContext.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.TypeExtensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Resources.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Resources.Reader.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Resources.ResourceManager.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Resources.Writer.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.CompilerServices.Unsafe.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.CompilerServices.VisualC.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Handles.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.InteropServices.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.InteropServices.RuntimeInformation.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Intrinsics.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Loader.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Numerics.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Serialization.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Serialization.Formatters.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Serialization.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Serialization.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Serialization.Xml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Claims.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.Algorithms.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.Cng.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.Csp.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.Encoding.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.OpenSsl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Security.Cryptography.Pkcs.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Security.Cryptography.ProtectedData.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.X509Certificates.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Security.Cryptography.Xml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Security.Permissions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Principal.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Principal.Windows.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.SecureString.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ServiceModel.Web.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ServiceProcess.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.Encoding.CodePages.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.Encoding.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.Encoding.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.Encodings.Web.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.RegularExpressions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Threading.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Channels.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Overlapped.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Tasks.Dataflow.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Tasks.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Tasks.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Tasks.Parallel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Thread.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.ThreadPool.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Timer.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Transactions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Transactions.Local.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ValueTuple.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Web.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Web.HttpUtility.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Controls.Ribbon.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Windows.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Forms.Design.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Forms.Design.Editors.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Forms.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Forms.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Input.Manipulations.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Presentation.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Xaml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.Linq.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.ReaderWriter.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.Serialization.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.XDocument.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.XmlDocument.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.XmlSerializer.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.XPath.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.XPath.XDocument.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\tapeti.annotations\3.0.0\lib\netstandard2.0\Tapeti.Annotations.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\tapeti.dataannotations.extensions\3.0.0\lib\netstandard2.0\Tapeti.DataAnnotations.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\UIAutomationClient.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\UIAutomationClientSideProviders.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\UIAutomationProvider.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\UIAutomationTypes.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\WindowsBase.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\WindowsFormsIntegration.dll" />
</ItemGroup>
<ItemGroup>
<Compile Include="P:\Development\PettingZoo\PettingZoo.Tapeti\obj\Debug\net6.0-windows\UI\ClassSelection\ClassSelectionWindow.g.cs" />
<Compile Include="P:\Development\PettingZoo\PettingZoo.Tapeti\obj\Debug\net6.0-windows\UI\PackageSelection\PackageSelectionWindow.g.cs" />
<Compile Include="P:\Development\PettingZoo\PettingZoo.Tapeti\obj\Debug\net6.0-windows\GeneratedInternalTypeHelper.g.cs" />
</ItemGroup>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
</Project>

View File

@ -11,8 +11,8 @@ using PettingZoo.Core.Settings;
using PettingZoo.Tapeti.AssemblyLoader;
using PettingZoo.Tapeti.NuGet;
using PettingZoo.Tapeti.UI.ClassSelection;
using PettingZoo.Tapeti.UI.PackageProgress;
using PettingZoo.Tapeti.UI.PackageSelection;
using PettingZoo.WPF.ProgressWindow;
using Serilog;
namespace PettingZoo.Tapeti
@ -34,8 +34,6 @@ namespace PettingZoo.Tapeti
.WithSourcesFrom(Path.Combine(PettingZooPaths.InstallationRoot, @"nuget.config"))
.WithSourcesFrom(Path.Combine(PettingZooPaths.AppDataRoot, @"nuget.config"));
var dispatcher = Dispatcher.CurrentDispatcher;
var viewModel = new PackageSelectionViewModel(packageManager);
var selectionWindow = new PackageSelectionWindow(viewModel)
{
@ -44,27 +42,28 @@ namespace PettingZoo.Tapeti
viewModel.Select += (_, args) =>
{
dispatcher.Invoke(() =>
Application.Current.Dispatcher.Invoke(() =>
{
var windowBounds = selectionWindow.RestoreBounds;
selectionWindow.Close();
var progressWindow = new PackageProgressWindow();
var progressWindow = new ProgressWindow(TapetiClassLibraryExampleGeneratorStrings.ProgressWindowTitle);
progressWindow.Left = windowBounds.Left + (windowBounds.Width - progressWindow.Width) / 2;
progressWindow.Top = windowBounds.Top + (windowBounds.Height - progressWindow.Height) / 2;
progressWindow.Show();
var cancellationToken = progressWindow.CancellationToken;
Task.Run(async () =>
{
try
{
// TODO allow cancelling (by closing the progress window and optionally a Cancel button)
var assemblies = await args.Assemblies.GetAssemblies(progressWindow, CancellationToken.None);
var assemblies = await args.Assemblies.GetAssemblies(progressWindow, cancellationToken);
// var classes =
var examples = LoadExamples(assemblies);
dispatcher.Invoke(() =>
Application.Current.Dispatcher.Invoke(() =>
{
progressWindow.Close();
progressWindow = null;
@ -89,15 +88,16 @@ namespace PettingZoo.Tapeti
}
catch (Exception e)
{
dispatcher.Invoke(() =>
Application.Current.Dispatcher.Invoke(() =>
{
// ReSharper disable once ConstantConditionalAccessQualifier - if I remove it, there's a "Dereference of a possibly null reference" warning instead
progressWindow?.Close();
MessageBox.Show($"Error while loading assembly: {e.Message}", "Petting Zoo - Exception", MessageBoxButton.OK, MessageBoxImage.Error);
if (e is not OperationCanceledException)
MessageBox.Show($"Error while loading assembly: {e.Message}", "Petting Zoo - Exception", MessageBoxButton.OK, MessageBoxImage.Error);
});
}
});
}, CancellationToken.None);
});
};

View File

@ -0,0 +1,72 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace PettingZoo.Tapeti {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class TapetiClassLibraryExampleGeneratorStrings {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal TapetiClassLibraryExampleGeneratorStrings() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PettingZoo.Tapeti.TapetiClassLibraryExampleGeneratorStrings", typeof(TapetiClassLibraryExampleGeneratorStrings).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Reading message classes....
/// </summary>
internal static string ProgressWindowTitle {
get {
return ResourceManager.GetString("ProgressWindowTitle", resourceCulture);
}
}
}
}

View File

@ -112,12 +112,12 @@
<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>
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.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>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="WindowTitle" xml:space="preserve">
<data name="ProgressWindowTitle" xml:space="preserve">
<value>Reading message classes...</value>
</data>
</root>

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace PettingZoo.Tapeti
@ -59,7 +60,20 @@ namespace PettingZoo.Tapeti
actualType = equivalentType;
// TODO check for JsonConverter attribute? doubt we'll be able to generate a nice value for it, but at least we can provide a placeholder
try
{
if (type.GetCustomAttribute<JsonConverterAttribute>() != null)
{
// This type uses custom Json conversion so there's no way to know how to provide an example.
// We could try to create an instance of the type and pass it through the converter, but for now we'll
// just output a placeholder.
return "<custom JsonConverter - manual input required>";
}
}
catch
{
// Move along
}
// String is also a class
if (actualType == typeof(string))

View File

@ -1,14 +0,0 @@
<Window x:Class="PettingZoo.Tapeti.UI.PackageProgress.PackageProgressWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:packageProgress="clr-namespace:PettingZoo.Tapeti.UI.PackageProgress"
mc:Ignorable="d"
Height="80"
Width="400"
Title="{x:Static packageProgress:PackageProgressStrings.WindowTitle}"
ResizeMode="NoResize"
WindowStyle="ToolWindow">
<ProgressBar Height="25" Margin="16" VerticalAlignment="Center" Name="Progress" Maximum="100" />
</Window>

View File

@ -1,24 +0,0 @@
using System;
namespace PettingZoo.Tapeti.UI.PackageProgress
{
/// <summary>
/// Interaction logic for PackageProgressWindow.xaml
/// </summary>
public partial class PackageProgressWindow : IProgress<int>
{
public PackageProgressWindow()
{
InitializeComponent();
}
public void Report(int value)
{
Dispatcher.BeginInvoke(() =>
{
Progress.Value = value;
});
}
}
}

View File

@ -88,7 +88,6 @@ namespace PettingZoo.Tapeti.UI.PackageSelection
public ICommand AssemblyBrowse => assemblyBrowse;
// TODO hint for extra assemblies path
public static string HintNuGetSources => string.Format(PackageSelectionStrings.HintNuGetSources, PettingZooPaths.InstallationRoot, PettingZooPaths.AppDataRoot);
public string NuGetSearchTerm

View File

@ -17,6 +17,28 @@
</ItemGroup>
<ItemGroup>
<Compile Update="ProgressWindow\ProgressStrings.Designer.cs">
<DependentUpon>ProgressStrings.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="ProgressWindow\ProgressWindow.xaml.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="ProgressWindow\ProgressStrings.resx">
<LastGenOutput>ProgressStrings.Designer.cs</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Page Update="ProgressWindow\ProgressWindow.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
</Page>
<Page Update="Style.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
</Page>

View File

@ -8,7 +8,7 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace PettingZoo.Tapeti.UI.PackageProgress {
namespace PettingZoo.WPF.ProgressWindow {
using System;
@ -22,14 +22,14 @@ namespace PettingZoo.Tapeti.UI.PackageProgress {
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class PackageProgressStrings {
public class ProgressStrings {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal PackageProgressStrings() {
internal ProgressStrings() {
}
/// <summary>
@ -39,7 +39,7 @@ namespace PettingZoo.Tapeti.UI.PackageProgress {
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PettingZoo.Tapeti.UI.PackageProgress.PackageProgressStrings", typeof(PackageProgressStrings).Assembly);
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PettingZoo.WPF.ProgressWindow.ProgressStrings", typeof(ProgressStrings).Assembly);
resourceMan = temp;
}
return resourceMan;
@ -61,11 +61,11 @@ namespace PettingZoo.Tapeti.UI.PackageProgress {
}
/// <summary>
/// Looks up a localized string similar to Reading message classes....
/// Looks up a localized string similar to Cancel.
/// </summary>
public static string WindowTitle {
public static string ButtonCancel {
get {
return ResourceManager.GetString("WindowTitle", resourceCulture);
return ResourceManager.GetString("ButtonCancel", resourceCulture);
}
}
}

View File

@ -0,0 +1,123 @@
<?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=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ButtonCancel" xml:space="preserve">
<value>Cancel</value>
</data>
</root>

View File

@ -0,0 +1,16 @@
<Window x:Class="PettingZoo.WPF.ProgressWindow.ProgressWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:progress="clr-namespace:PettingZoo.WPF.ProgressWindow"
mc:Ignorable="d"
Width="400"
ResizeMode="NoResize"
WindowStyle="ToolWindow"
SizeToContent="Height">
<StackPanel Orientation="Vertical">
<ProgressBar Height="25" Margin="16" VerticalAlignment="Center" Name="Progress" Maximum="100" />
<Button HorizontalAlignment="Center" Margin="0,0,0,16" Content="{x:Static progress:ProgressStrings.ButtonCancel}" Click="CancelButton_OnClick" />
</StackPanel>
</Window>

View File

@ -0,0 +1,44 @@
using System;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
namespace PettingZoo.WPF.ProgressWindow
{
/// <summary>
/// Interaction logic for ProgressWindow.xaml
/// </summary>
public partial class ProgressWindow : IProgress<int>
{
private readonly CancellationTokenSource cancellationTokenSource = new();
public CancellationToken CancellationToken => cancellationTokenSource.Token;
public ProgressWindow(string title)
{
InitializeComponent();
Title = title;
Closed += (_, _) =>
{
cancellationTokenSource.Cancel();
};
}
public void Report(int value)
{
Dispatcher.BeginInvoke(() =>
{
Progress.Value = value;
});
}
private void CancelButton_OnClick(object sender, RoutedEventArgs e)
{
cancellationTokenSource.Cancel();
((Button)sender).IsEnabled = false;
}
}
}

View File

@ -93,6 +93,7 @@
<Style x:Key="Payload" TargetType="{x:Type avalonedit:TextEditor}">
<Setter Property="FontFamily" Value="Consolas,Courier New" />
<Setter Property="WordWrap" Value="True" />
</Style>
<Style x:Key="ControlBorder" TargetType="{x:Type Border}">

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 58 58" style="enable-background:new 0 0 58 58;" xml:space="preserve">
<g>
<g>
<polygon style="fill:#EFEBDE;" points="46.5,14 32.5,0 1.5,0 1.5,58 46.5,58 "/>
<g>
<path style="fill:#D5D0BB;" d="M11.5,23h25c0.552,0,1-0.447,1-1s-0.448-1-1-1h-25c-0.552,0-1,0.447-1,1S10.948,23,11.5,23z"/>
<path style="fill:#D5D0BB;" d="M11.5,15h10c0.552,0,1-0.447,1-1s-0.448-1-1-1h-10c-0.552,0-1,0.447-1,1S10.948,15,11.5,15z"/>
<path style="fill:#D5D0BB;" d="M36.5,29h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S37.052,29,36.5,29z"/>
<path style="fill:#D5D0BB;" d="M36.5,37h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S37.052,37,36.5,37z"/>
<path style="fill:#D5D0BB;" d="M36.5,45h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S37.052,45,36.5,45z"/>
</g>
<polygon style="fill:#D5D0BB;" points="32.5,0 32.5,14 46.5,14 "/>
</g>
<g>
<rect x="34.5" y="36" style="fill:#21AE5E;" width="22" height="22"/>
<rect x="44.5" y="37.586" style="fill:#FFFFFF;" width="2" height="16"/>
<polygon style="fill:#FFFFFF;" points="45.5,55 38.5,48.293 39.976,46.879 45.5,52.172 51.024,46.879 52.5,48.293 "/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 58 58" style="enable-background:new 0 0 58 58;" xml:space="preserve">
<g>
<g>
<polygon style="fill:#EFEBDE;" points="46,14 32,0 1,0 1,58 46,58 "/>
<g>
<path style="fill:#D5D0BB;" d="M11,23h25c0.552,0,1-0.447,1-1s-0.448-1-1-1H11c-0.552,0-1,0.447-1,1S10.448,23,11,23z"/>
<path style="fill:#D5D0BB;" d="M11,15h10c0.552,0,1-0.447,1-1s-0.448-1-1-1H11c-0.552,0-1,0.447-1,1S10.448,15,11,15z"/>
<path style="fill:#D5D0BB;" d="M36,29H11c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S36.552,29,36,29z"/>
<path style="fill:#D5D0BB;" d="M36,37H11c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S36.552,37,36,37z"/>
<path style="fill:#D5D0BB;" d="M36,45H11c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S36.552,45,36,45z"/>
</g>
<polygon style="fill:#D5D0BB;" points="32,0 32,14 46,14 "/>
</g>
<g>
<rect x="35" y="36" style="fill:#48A0DC;" width="22" height="22"/>
<rect x="45" y="42" style="fill:#FFFFFF;" width="2" height="16"/>
<polygon style="fill:#FFFFFF;" points="51.293,48.707 46,43.414 40.707,48.707 39.293,47.293 46,40.586 52.707,47.293 "/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -23,7 +23,9 @@
<None Remove="Images\Dock.svg" />
<None Remove="Images\Error.svg" />
<None Remove="Images\Example.svg" />
<None Remove="Images\Export.svg" />
<None Remove="Images\Folder.svg" />
<None Remove="Images\Import.svg" />
<None Remove="Images\Ok.svg" />
<None Remove="Images\PublishSend.svg" />
<None Remove="Images\Undock.svg" />
@ -36,7 +38,9 @@
<Resource Include="Images\Dock.svg" />
<Resource Include="Images\Error.svg" />
<Resource Include="Images\Example.svg" />
<Resource Include="Images\Export.svg" />
<Resource Include="Images\Folder.svg" />
<Resource Include="Images\Import.svg" />
<Resource Include="Images\Ok.svg" />
<Resource Include="Images\Publish.svg" />
<Resource Include="Images\PublishSend.svg" />

View File

@ -0,0 +1,419 @@
<Project>
<PropertyGroup>
<AssemblyName>PettingZoo</AssemblyName>
<IntermediateOutputPath>obj\Debug\</IntermediateOutputPath>
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
<MSBuildProjectExtensionsPath>P:\Development\PettingZoo\PettingZoo\obj\</MSBuildProjectExtensionsPath>
<_TargetAssemblyProjectName>PettingZoo</_TargetAssemblyProjectName>
</PropertyGroup>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Version>0.1</Version>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
<Authors>Mark van Renswoude</Authors>
<Product>Petting Zoo</Product>
<Description>Petting Zoo - a live RabbitMQ message viewer</Description>
<Copyright />
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<StartupObject>PettingZoo.Program</StartupObject>
<PackageIcon>
</PackageIcon>
<PackageIconUrl />
<ApplicationIcon>PettingZoo.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<None Remove="Images\Busy.svg" />
<None Remove="Images\Dock.svg" />
<None Remove="Images\Error.svg" />
<None Remove="Images\Example.svg" />
<None Remove="Images\Export.svg" />
<None Remove="Images\Folder.svg" />
<None Remove="Images\Import.svg" />
<None Remove="Images\Ok.svg" />
<None Remove="Images\PublishSend.svg" />
<None Remove="Images\Undock.svg" />
</ItemGroup>
<ItemGroup>
</ItemGroup>
<ItemGroup>
<PackageReference Include="AvalonEdit" Version="6.1.3.50" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="SharpVectors" Version="1.7.7" />
<PackageReference Include="SimpleInjector" Version="5.3.2" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PettingZoo.Core\PettingZoo.Core.csproj" />
<ProjectReference Include="..\PettingZoo.RabbitMQ\PettingZoo.RabbitMQ.csproj" />
<ProjectReference Include="..\PettingZoo.Settings.LiteDB\PettingZoo.Settings.LiteDB.csproj" />
<ProjectReference Include="..\PettingZoo.Tapeti\PettingZoo.Tapeti.csproj" />
<ProjectReference Include="..\PettingZoo.WPF\PettingZoo.WPF.csproj" />
</ItemGroup>
<ItemGroup>
</ItemGroup>
<ItemGroup>
<Compile Update="UI\Connection\ConnectionDisplayNameStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>ConnectionDisplayNameStrings.resx</DependentUpon>
</Compile>
<Compile Update="UI\Connection\ConnectionWindowStrings.Designer.cs">
<DependentUpon>ConnectionWindowStrings.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="UI\Main\MainWindowStrings.Designer.cs">
<DependentUpon>MainWindowStrings.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="UI\Subscribe\SubscribeWindowStrings.Designer.cs">
<DependentUpon>SubscribeWindowStrings.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="UI\Tab\Publisher\PayloadEditorStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>PayloadEditorStrings.resx</DependentUpon>
</Compile>
<Compile Update="UI\Tab\Publisher\TapetiPublisherViewStrings.Designer.cs">
<DependentUpon>TapetiPublisherViewStrings.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="UI\Tab\Publisher\TapetiPublisherView.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="UI\Tab\Publisher\RawPublisherViewStrings.Designer.cs">
<DependentUpon>RawPublisherViewStrings.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="UI\Tab\Publisher\PublisherViewStrings.Designer.cs">
<DependentUpon>PublisherViewStrings.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="UI\Tab\Subscriber\SubscriberViewStrings.Designer.cs">
<DependentUpon>SubscriberViewStrings.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="UI\Tab\Undocked\UndockedTabHostStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>UndockedTabHostStrings.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="UI\Connection\ConnectionDisplayNameStrings.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>ConnectionDisplayNameStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="UI\Connection\ConnectionWindowStrings.resx">
<LastGenOutput>ConnectionWindowStrings.Designer.cs</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="UI\Main\MainWindowStrings.resx">
<LastGenOutput>MainWindowStrings.Designer.cs</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="UI\Subscribe\SubscribeWindowStrings.resx">
<LastGenOutput>SubscribeWindowStrings.Designer.cs</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="UI\Tab\Publisher\PayloadEditorStrings.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>PayloadEditorStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="UI\Tab\Publisher\TapetiPublisherViewStrings.resx">
<LastGenOutput>TapetiPublisherViewStrings.Designer.cs</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="UI\Tab\Publisher\RawPublisherViewStrings.resx">
<LastGenOutput>RawPublisherViewStrings.Designer.cs</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="UI\Tab\Publisher\PublisherViewStrings.resx">
<LastGenOutput>PublisherViewStrings.Designer.cs</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="UI\Tab\Subscriber\SubscriberViewStrings.resx">
<LastGenOutput>SubscriberViewStrings.Designer.cs</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="UI\Tab\Undocked\UndockedTabHostStrings.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>UndockedTabHostStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
</ItemGroup>
<ItemGroup>
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\Accessibility.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\avalonedit\6.1.3.50\lib\net6.0-windows7.0\ICSharpCode.AvalonEdit.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\litedb\5.0.11\lib\netstandard2.0\LiteDB.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\litedb.async\0.0.11\lib\netstandard2.0\litedbasync.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\Microsoft.CSharp.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\Microsoft.VisualBasic.Core.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\Microsoft.VisualBasic.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\Microsoft.VisualBasic.Forms.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\microsoft.web.xdt\3.0.0\lib\netstandard2.0\Microsoft.Web.XmlTransform.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\Microsoft.Win32.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\Microsoft.Win32.Registry.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\Microsoft.Win32.Registry.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\Microsoft.Win32.SystemEvents.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\mscorlib.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\netstandard.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\newtonsoft.json\13.0.1\lib\netstandard2.0\Newtonsoft.Json.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.commands\6.0.0\lib\net5.0\NuGet.Commands.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.common\6.0.0\lib\netstandard2.0\NuGet.Common.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.configuration\6.0.0\lib\netstandard2.0\NuGet.Configuration.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.credentials\6.0.0\lib\net5.0\NuGet.Credentials.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.dependencyresolver.core\6.0.0\lib\net5.0\NuGet.DependencyResolver.Core.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.frameworks\6.0.0\lib\netstandard2.0\NuGet.Frameworks.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.librarymodel\6.0.0\lib\netstandard2.0\NuGet.LibraryModel.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.packagemanagement\6.0.0\lib\netstandard2.0\NuGet.PackageManagement.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.packaging\6.0.0\lib\net5.0\NuGet.Packaging.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.projectmodel\6.0.0\lib\net5.0\NuGet.ProjectModel.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.protocol\6.0.0\lib\net5.0\NuGet.Protocol.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.resolver\6.0.0\lib\net5.0\NuGet.Resolver.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.versioning\6.0.0\lib\netstandard2.0\NuGet.Versioning.dll" />
<ReferencePath Include="P:\Development\PettingZoo\PettingZoo.Core\bin\Debug\net6.0\PettingZoo.Core.dll" />
<ReferencePath Include="P:\Development\PettingZoo\PettingZoo.RabbitMQ\bin\Debug\net6.0\PettingZoo.RabbitMQ.dll" />
<ReferencePath Include="P:\Development\PettingZoo\PettingZoo.Settings.LiteDB\bin\Debug\net6.0\PettingZoo.Settings.LiteDB.dll" />
<ReferencePath Include="P:\Development\PettingZoo\PettingZoo.Tapeti\bin\Debug\net6.0-windows\PettingZoo.Tapeti.dll" />
<ReferencePath Include="P:\Development\PettingZoo\PettingZoo.WPF\bin\Debug\net6.0-windows\PettingZoo.WPF.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationCore.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.Aero.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.Aero2.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.AeroLite.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.Classic.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.Luna.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.Royale.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationUI.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\rabbitmq.client\6.2.2\lib\netstandard2.0\RabbitMQ.Client.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\ReachFramework.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\serilog\2.10.0\lib\netstandard2.1\Serilog.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\serilog.sinks.file\5.0.0\lib\net5.0\Serilog.Sinks.File.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Converters.Wpf.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Core.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Css.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Dom.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Model.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Rendering.Gdi.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Rendering.Wpf.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Runtime.Wpf.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\simpleinjector\5.3.2\lib\netstandard2.1\SimpleInjector.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.AppContext.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Buffers.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.CodeDom.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Collections.Concurrent.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Collections.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Collections.Immutable.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Collections.NonGeneric.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Collections.Specialized.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.Annotations.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\system.componentmodel.composition\4.5.0\ref\netstandard2.0\System.ComponentModel.Composition.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.DataAnnotations.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.EventBasedAsync.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.TypeConverter.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Configuration.ConfigurationManager.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Configuration.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Console.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Core.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Data.Common.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Data.DataSetExtensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Data.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Design.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.Contracts.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.Debug.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.DiagnosticSource.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Diagnostics.EventLog.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.FileVersionInfo.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Diagnostics.PerformanceCounter.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.Process.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.StackTrace.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.TextWriterTraceListener.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.Tools.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.TraceSource.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.Tracing.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.DirectoryServices.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Drawing.Common.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Drawing.Design.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Drawing.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Drawing.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Dynamic.Runtime.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Formats.Asn1.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Globalization.Calendars.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Globalization.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Globalization.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Compression.Brotli.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Compression.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Compression.FileSystem.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Compression.ZipFile.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.FileSystem.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.FileSystem.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.FileSystem.DriveInfo.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.FileSystem.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.FileSystem.Watcher.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.IsolatedStorage.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.MemoryMappedFiles.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.IO.Packaging.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Pipes.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Pipes.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.UnmanagedMemoryStream.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Linq.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Linq.Expressions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Linq.Parallel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Linq.Queryable.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Memory.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Http.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Http.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.HttpListener.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Mail.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.NameResolution.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.NetworkInformation.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Ping.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Requests.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Security.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.ServicePoint.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Sockets.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.WebClient.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.WebHeaderCollection.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.WebProxy.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.WebSockets.Client.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.WebSockets.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Numerics.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Numerics.Vectors.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ObjectModel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Printing.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\system.reactive\5.0.0\lib\net5.0\System.Reactive.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.DispatchProxy.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Emit.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Emit.ILGeneration.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Emit.Lightweight.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Metadata.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\system.reflection.metadataloadcontext\6.0.0\lib\net6.0\System.Reflection.MetadataLoadContext.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.TypeExtensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Resources.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Resources.Reader.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Resources.ResourceManager.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Resources.Writer.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.CompilerServices.Unsafe.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.CompilerServices.VisualC.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Handles.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.InteropServices.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.InteropServices.RuntimeInformation.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Intrinsics.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Loader.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Numerics.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Serialization.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Serialization.Formatters.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Serialization.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Serialization.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Serialization.Xml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Claims.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.Algorithms.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.Cng.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.Csp.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.Encoding.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.OpenSsl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Security.Cryptography.Pkcs.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Security.Cryptography.ProtectedData.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.X509Certificates.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Security.Cryptography.Xml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Security.Permissions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Principal.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Principal.Windows.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.SecureString.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ServiceModel.Web.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ServiceProcess.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.Encoding.CodePages.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.Encoding.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.Encoding.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.Encodings.Web.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.Json.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.RegularExpressions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Threading.AccessControl.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Channels.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Overlapped.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Tasks.Dataflow.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Tasks.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Tasks.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Tasks.Parallel.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Thread.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.ThreadPool.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Timer.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Transactions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Transactions.Local.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ValueTuple.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Web.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Web.HttpUtility.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Controls.Ribbon.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Windows.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Forms.Design.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Forms.Design.Editors.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Forms.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Forms.Primitives.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Input.Manipulations.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Presentation.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Xaml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.Linq.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.ReaderWriter.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.Serialization.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.XDocument.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.XmlDocument.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.XmlSerializer.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.XPath.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.XPath.XDocument.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\tapeti.annotations\3.0.0\lib\netstandard2.0\Tapeti.Annotations.dll" />
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\tapeti.dataannotations.extensions\3.0.0\lib\netstandard2.0\Tapeti.DataAnnotations.Extensions.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\UIAutomationClient.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\UIAutomationClientSideProviders.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\UIAutomationProvider.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\UIAutomationTypes.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\WindowsBase.dll" />
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\WindowsFormsIntegration.dll" />
</ItemGroup>
<ItemGroup>
<Compile Include="P:\Development\PettingZoo\PettingZoo\obj\Debug\net6.0-windows\UI\Connection\ConnectionDisplayNameDialog.g.cs" />
<Compile Include="P:\Development\PettingZoo\PettingZoo\obj\Debug\net6.0-windows\UI\Connection\ConnectionWindow.g.cs" />
<Compile Include="P:\Development\PettingZoo\PettingZoo\obj\Debug\net6.0-windows\UI\Main\MainWindow.g.cs" />
<Compile Include="P:\Development\PettingZoo\PettingZoo\obj\Debug\net6.0-windows\UI\Subscribe\SubscribeWindow.g.cs" />
<Compile Include="P:\Development\PettingZoo\PettingZoo\obj\Debug\net6.0-windows\UI\Tab\Publisher\PayloadEditorControl.g.cs" />
<Compile Include="P:\Development\PettingZoo\PettingZoo\obj\Debug\net6.0-windows\UI\Tab\Publisher\PublisherView.g.cs" />
<Compile Include="P:\Development\PettingZoo\PettingZoo\obj\Debug\net6.0-windows\UI\Tab\Publisher\RawPublisherView.g.cs" />
<Compile Include="P:\Development\PettingZoo\PettingZoo\obj\Debug\net6.0-windows\UI\Tab\Publisher\TapetiPublisherView.g.cs" />
<Compile Include="P:\Development\PettingZoo\PettingZoo\obj\Debug\net6.0-windows\UI\Tab\Subscriber\SubscriberView.g.cs" />
<Compile Include="P:\Development\PettingZoo\PettingZoo\obj\Debug\net6.0-windows\UI\Tab\Undocked\UndockedTabHostWindow.g.cs" />
<Compile Include="P:\Development\PettingZoo\PettingZoo\obj\Debug\net6.0-windows\App.g.cs" />
<Compile Include="P:\Development\PettingZoo\PettingZoo\obj\Debug\net6.0-windows\GeneratedInternalTypeHelper.g.cs" />
</ItemGroup>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
</Project>

View File

@ -4,14 +4,17 @@ using System.IO;
using System.Windows;
using System.Windows.Markup;
using PettingZoo.Core.Connection;
using PettingZoo.Core.ExportImport;
using PettingZoo.Core.Generator;
using PettingZoo.Core.Settings;
using PettingZoo.RabbitMQ;
using PettingZoo.Settings.LiteDB;
using PettingZoo.Tapeti;
using PettingZoo.Tapeti.Export;
using PettingZoo.UI.Connection;
using PettingZoo.UI.Main;
using PettingZoo.UI.Subscribe;
using PettingZoo.UI.Tab;
using Serilog;
using SimpleInjector;
@ -79,6 +82,13 @@ namespace PettingZoo
container.Register<IConnectionSettingsRepository, LiteDBConnectionSettingsRepository>();
container.Register<IUISettingsRepository, LiteDBUISettingsRepository>();
container.Register<IExampleGenerator, TapetiClassLibraryExampleGenerator>();
container.RegisterSingleton<ITabHostProvider, TabHostProvider>();
container.Register<ITabFactory, ViewTabFactory>();
container.RegisterInstance<IExportImportFormatProvider>(new ExportImportFormatProvider(
new TapetiCmdExportFormat(),
new TapetiCmdImportFormat()
));
container.Register<MainWindow>();

View File

@ -1,14 +1,15 @@
Must-have
---------
- Check required fields before enabling Publish button
Should-have
-----------
- Save / load publisher messages (either as templates or to disk)
- Tapeti: export received messages to Tapeti.Cmd JSON file / Tapeti.Cmd command-line
- Tapeti: fetch NuGet dependencies to improve the chances of succesfully loading the assembly, instead of the current "extraAssembliesPaths" workaround
- Single tab for responses, don't create a new subscriber tab for 1 message each time
Use the CorrelationId in the list for such cases instead of the routing key (which is the name of the dynamic queue for the responses).
Set the CorrelationId to the request routing key for example, so the different responses can be somewhat identified.
Nice-to-have
------------
------------
- Save / load publisher messages (either as templates or to disk)
- Tapeti: fetch NuGet dependencies to improve the chances of succesfully loading the assembly, instead of the current "extraAssembliesPaths" workaround

View File

@ -38,6 +38,13 @@
</StackPanel>
</Button>
<Separator Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" />
<Button Command="{Binding ImportCommand}">
<StackPanel Orientation="Horizontal">
<Image Source="{svgc:SvgImage Source=/Images/Import.svg, AppName=PettingZoo}" Width="16" Height="16" Style="{StaticResource ToolbarIcon}"/>
<TextBlock Margin="3,0,0,0" Text="{x:Static main:MainWindowStrings.CommandImport}" />
</StackPanel>
</Button>
<Separator Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" />
<Button Command="{Binding SubscribeCommand}">
<StackPanel Orientation="Horizontal">
<Image Source="{svgc:SvgImage Source=/Images/Subscribe.svg, AppName=PettingZoo}" Width="16" Height="16" Style="{StaticResource ToolbarIcon}"/>

View File

@ -5,10 +5,11 @@ using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using PettingZoo.Core.Connection;
using PettingZoo.Core.Generator;
using PettingZoo.Core.ExportImport;
using PettingZoo.UI.Connection;
using PettingZoo.UI.Subscribe;
using PettingZoo.UI.Tab;
using Serilog;
namespace PettingZoo.UI.Main
{
@ -20,11 +21,12 @@ namespace PettingZoo.UI.Main
public bool WasMaximized;
public MainWindow(IConnectionFactory connectionFactory, IConnectionDialog connectionDialog, ISubscribeDialog subscribeDialog, IExampleGenerator exampleGenerator)
public MainWindow(ILogger logger, IConnectionFactory connectionFactory, IConnectionDialog connectionDialog, ISubscribeDialog subscribeDialog,
ITabHostProvider tabHostProvider, ITabFactory tabFactory, IExportImportFormatProvider exportImportFormatProvider)
{
WindowStartupLocation = WindowStartupLocation.CenterScreen;
viewModel = new MainWindowViewModel(connectionFactory, connectionDialog, subscribeDialog, this, exampleGenerator)
viewModel = new MainWindowViewModel(logger, connectionFactory, connectionDialog, subscribeDialog, this, tabHostProvider, tabFactory, exportImportFormatProvider)
{
TabHostWindow = this
};

View File

@ -78,6 +78,15 @@ namespace PettingZoo.UI.Main {
}
}
/// <summary>
/// Looks up a localized string similar to Import....
/// </summary>
public static string CommandImport {
get {
return ResourceManager.GetString("CommandImport", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to New Publisher.
/// </summary>
@ -141,6 +150,15 @@ namespace PettingZoo.UI.Main {
}
}
/// <summary>
/// Looks up a localized string similar to Importing messages....
/// </summary>
public static string ImportProgressWindowTitle {
get {
return ResourceManager.GetString("ImportProgressWindowTitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Connected.
/// </summary>

View File

@ -112,10 +112,10 @@
<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>
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.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>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="CommandConnect" xml:space="preserve">
<value>Connect</value>
@ -123,6 +123,9 @@
<data name="CommandDisconnect" xml:space="preserve">
<value>Disconnect</value>
</data>
<data name="CommandImport" xml:space="preserve">
<value>Import...</value>
</data>
<data name="CommandPublish" xml:space="preserve">
<value>New Publisher</value>
</data>
@ -144,6 +147,9 @@
<data name="DeliveryModePersistent" xml:space="preserve">
<value>Persistent</value>
</data>
<data name="ImportProgressWindowTitle" xml:space="preserve">
<value>Importing messages...</value>
</data>
<data name="StatusConnected" xml:space="preserve">
<value>Connected</value>
</data>

View File

@ -1,17 +1,25 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
using PettingZoo.Core.Connection;
using PettingZoo.Core.Generator;
using PettingZoo.Core.ExportImport;
using PettingZoo.UI.Connection;
using PettingZoo.UI.Subscribe;
using PettingZoo.UI.Tab;
using PettingZoo.UI.Tab.Subscriber;
using PettingZoo.UI.Tab.Undocked;
using PettingZoo.WPF.ProgressWindow;
using PettingZoo.WPF.ViewModel;
using Serilog;
using Application = System.Windows.Application;
using MessageBox = System.Windows.MessageBox;
namespace PettingZoo.UI.Main
{
@ -25,11 +33,14 @@ namespace PettingZoo.UI.Main
public class MainWindowViewModel : BaseViewModel, IAsyncDisposable, ITabHost
{
private readonly ILogger logger;
private readonly IConnectionFactory connectionFactory;
private readonly IConnectionDialog connectionDialog;
private readonly ISubscribeDialog subscribeDialog;
private readonly ITabContainer tabContainer;
private readonly ITabHostProvider tabHostProvider;
private readonly ITabFactory tabFactory;
private readonly IExportImportFormatProvider exportImportFormatProvider;
private SubscribeDialogParams? subscribeDialogParams;
private IConnection? connection;
@ -43,6 +54,7 @@ namespace PettingZoo.UI.Main
private readonly DelegateCommand subscribeCommand;
private readonly DelegateCommand closeTabCommand;
private readonly DelegateCommand undockTabCommand;
private readonly DelegateCommand importCommand;
private ConnectionStatusType connectionStatusType;
@ -90,6 +102,7 @@ namespace PettingZoo.UI.Main
public ICommand SubscribeCommand => subscribeCommand;
public ICommand CloseTabCommand => closeTabCommand;
public ICommand UndockTabCommand => undockTabCommand;
public ICommand ImportCommand => importCommand;
public IEnumerable<TabToolbarCommand> ToolbarCommands => ActiveTab is ITabToolbarCommands tabToolbarCommands
? tabToolbarCommands.ToolbarCommands
@ -102,13 +115,20 @@ namespace PettingZoo.UI.Main
Tabs.Count > 0 ? Visibility.Collapsed : Visibility.Visible;
public MainWindowViewModel(IConnectionFactory connectionFactory, IConnectionDialog connectionDialog,
ISubscribeDialog subscribeDialog, ITabContainer tabContainer, IExampleGenerator exampleGenerator)
public MainWindowViewModel(ILogger logger, IConnectionFactory connectionFactory, IConnectionDialog connectionDialog,
ISubscribeDialog subscribeDialog, ITabContainer tabContainer, ITabHostProvider tabHostProvider, ITabFactory tabFactory,
IExportImportFormatProvider exportImportFormatProvider)
{
tabHostProvider.SetInstance(this);
this.logger = logger;
this.connectionFactory = connectionFactory;
this.connectionDialog = connectionDialog;
this.subscribeDialog = subscribeDialog;
this.tabContainer = tabContainer;
this.tabHostProvider = tabHostProvider;
this.tabFactory = tabFactory;
this.exportImportFormatProvider = exportImportFormatProvider;
connectionStatus = GetConnectionStatus(null);
connectionStatusType = ConnectionStatusType.Error;
@ -120,8 +140,7 @@ namespace PettingZoo.UI.Main
subscribeCommand = new DelegateCommand(SubscribeExecute, IsConnectedCanExecute);
closeTabCommand = new DelegateCommand(CloseTabExecute, HasActiveTabCanExecute);
undockTabCommand = new DelegateCommand(UndockTabExecute, HasActiveTabCanExecute);
tabFactory = new ViewTabFactory(this, exampleGenerator);
importCommand = new DelegateCommand(ImportExecute);
}
@ -226,7 +245,7 @@ namespace PettingZoo.UI.Main
if (tab == null)
return;
var tabHostWindow = UndockedTabHostWindow.Create(this, tab, tabContainer.TabWidth, tabContainer.TabHeight);
var tabHostWindow = UndockedTabHostWindow.Create(tabHostProvider, tab, tabContainer.TabWidth, tabContainer.TabHeight);
undockedTabs.Add(tab, tabHostWindow);
tabHostWindow.Show();
@ -234,6 +253,87 @@ namespace PettingZoo.UI.Main
}
private void ImportExecute()
{
var formats = exportImportFormatProvider.ImportFormats.ToArray();
var dialog = new OpenFileDialog
{
Filter = string.Join('|', formats.Select(f => f.Filter))
};
if (dialog.ShowDialog() != DialogResult.OK)
return;
if (dialog.FilterIndex <= 0 || dialog.FilterIndex > formats.Length)
return;
var filename = dialog.FileName;
var format = formats[dialog.FilterIndex - 1];
var progressWindow = new ProgressWindow(MainWindowStrings.ImportProgressWindowTitle)
{
Owner = TabHostWindow,
WindowStartupLocation = WindowStartupLocation.CenterOwner
};
progressWindow.Show();
Task.Run(async () =>
{
try
{
IReadOnlyList<ReceivedMessageInfo> messages;
await using (var importFile =
new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
messages = await format.Import(
new StreamProgressDecorator(importFile, progressWindow).Stream,
progressWindow.CancellationToken);
}
if (progressWindow.CancellationToken.IsCancellationRequested)
return;
await Application.Current.Dispatcher.BeginInvoke(() =>
{
progressWindow.Close();
progressWindow = null;
AddTab(tabFactory.CreateSubscriberTab(connection,
new ImportSubscriber(filename, messages)));
});
}
catch (OperationCanceledException)
{
// User cancelled
}
catch (Exception e)
{
logger.Error(e, "Error while importing messages");
await Application.Current.Dispatcher.BeginInvoke(() =>
{
progressWindow?.Close();
progressWindow = null;
MessageBox.Show(string.Format(SubscriberViewStrings.ExportError, e.Message),
SubscriberViewStrings.ExportResultTitle,
MessageBoxButton.OK, MessageBoxImage.Information);
});
}
finally
{
if (progressWindow != null)
await Application.Current.Dispatcher.BeginInvoke(() =>
{
progressWindow.Close();
});
}
}, CancellationToken.None);
}
private ITab? RemoveActiveTab()
{
if (ActiveTab == null)
@ -330,8 +430,18 @@ namespace PettingZoo.UI.Main
public class DesignTimeMainWindowViewModel : MainWindowViewModel
{
public DesignTimeMainWindowViewModel() : base(null!, null!, null!, null!, null!)
public DesignTimeMainWindowViewModel() : base(null!, null!, null!, null!, null!, new DesignTimeTabHostProvider(), null!, null!)
{
}
private class DesignTimeTabHostProvider : ITabHostProvider
{
public ITabHost Instance => null!;
public void SetInstance(ITabHost instance)
{
}
}
}
}

View File

@ -8,7 +8,7 @@ namespace PettingZoo.UI.Tab
public interface ITabFactory
{
ITab CreateSubscriberTab(IConnection connection, ISubscriber subscriber);
ITab CreateSubscriberTab(IConnection? connection, ISubscriber subscriber);
ITab CreatePublisherTab(IConnection connection, ReceivedMessageInfo? fromReceivedMessage = null);
}
}

View File

@ -0,0 +1,9 @@
namespace PettingZoo.UI.Tab
{
public interface ITabHostProvider
{
public ITabHost Instance { get; }
public void SetInstance(ITabHost instance);
}
}

View File

@ -21,7 +21,7 @@ namespace PettingZoo.UI.Tab.Publisher
private readonly IConnection connection;
private readonly IExampleGenerator exampleGenerator;
private readonly ITabFactory tabFactory;
private readonly ITabHost tabHost;
private readonly ITabHostProvider tabHostProvider;
private bool sendToExchange = true;
private string exchange = "";
@ -45,7 +45,9 @@ namespace PettingZoo.UI.Tab.Publisher
public bool SendToExchange
{
get => sendToExchange;
set => SetField(ref sendToExchange, value, otherPropertiesChanged: new[] { nameof(SendToQueue), nameof(ExchangeVisibility), nameof(QueueVisibility), nameof(Title) });
set => SetField(ref sendToExchange, value,
delegateCommandsChanged: new [] { publishCommand },
otherPropertiesChanged: new[] { nameof(SendToQueue), nameof(ExchangeVisibility), nameof(QueueVisibility), nameof(Title) });
}
@ -59,21 +61,21 @@ namespace PettingZoo.UI.Tab.Publisher
public string Exchange
{
get => exchange;
set => SetField(ref exchange, value);
set => SetField(ref exchange, value, delegateCommandsChanged: new[] { publishCommand });
}
public string RoutingKey
{
get => routingKey;
set => SetField(ref routingKey, value, otherPropertiesChanged: new[] { nameof(Title) });
set => SetField(ref routingKey, value, delegateCommandsChanged: new[] { publishCommand }, otherPropertiesChanged: new[] { nameof(Title) });
}
public string Queue
{
get => queue;
set => SetField(ref queue, value, otherPropertiesChanged: new[] { nameof(Title) });
set => SetField(ref queue, value, delegateCommandsChanged: new[] { publishCommand }, otherPropertiesChanged: new[] { nameof(Title) });
}
@ -154,12 +156,12 @@ namespace PettingZoo.UI.Tab.Publisher
string IPublishDestination.RoutingKey => SendToExchange ? RoutingKey : Queue;
public PublisherViewModel(ITabHost tabHost, ITabFactory tabFactory, IConnection connection, IExampleGenerator exampleGenerator, ReceivedMessageInfo? fromReceivedMessage = null)
public PublisherViewModel(ITabHostProvider tabHostProvider, ITabFactory tabFactory, IConnection connection, IExampleGenerator exampleGenerator, ReceivedMessageInfo? fromReceivedMessage = null)
{
this.connection = connection;
this.exampleGenerator = exampleGenerator;
this.tabFactory = tabFactory;
this.tabHost = tabHost;
this.tabHostProvider = tabHostProvider;
publishCommand = new DelegateCommand(PublishExecute, PublishCanExecute);
@ -183,6 +185,17 @@ namespace PettingZoo.UI.Tab.Publisher
private bool PublishCanExecute()
{
if (SendToExchange)
{
if (string.IsNullOrWhiteSpace(Exchange) || string.IsNullOrWhiteSpace(RoutingKey))
return false;
}
else
{
if (string.IsNullOrWhiteSpace(Queue))
return false;
}
return messageTypePublishCommand?.CanExecute(null) ?? false;
}
@ -197,6 +210,11 @@ namespace PettingZoo.UI.Tab.Publisher
if (rawPublisherView == null)
{
rawPublisherViewModel = new RawPublisherViewModel(connection, this);
rawPublisherViewModel.PublishCommand.CanExecuteChanged += (_, _) =>
{
publishCommand.RaiseCanExecuteChanged();
};
rawPublisherView ??= new RawPublisherView(rawPublisherViewModel);
}
else
@ -213,6 +231,11 @@ namespace PettingZoo.UI.Tab.Publisher
if (tapetiPublisherView == null)
{
tapetiPublisherViewModel = new TapetiPublisherViewModel(connection, this, exampleGenerator);
tapetiPublisherViewModel.PublishCommand.CanExecuteChanged += (_, _) =>
{
publishCommand.RaiseCanExecuteChanged();
};
tapetiPublisherView ??= new TapetiPublisherView(tapetiPublisherViewModel);
if (tabHostWindow != null)
@ -264,7 +287,7 @@ namespace PettingZoo.UI.Tab.Publisher
var subscriber = connection.Subscribe();
var tab = tabFactory.CreateSubscriberTab(connection, subscriber);
tabHost.AddTab(tab);
tabHostProvider.Instance.AddTab(tab);
subscriber.Start();
return subscriber.QueueName;

View File

@ -115,7 +115,7 @@ namespace PettingZoo.UI.Tab.Publisher
public string Payload
{
get => payload;
set => SetField(ref payload, value);
set => SetField(ref payload, value, delegateCommandsChanged: new [] { publishCommand });
}
@ -267,10 +267,9 @@ namespace PettingZoo.UI.Tab.Publisher
}
private static bool PublishCanExecute()
private bool PublishCanExecute()
{
// TODO validate input
return true;
return !string.IsNullOrWhiteSpace(Payload);
}

View File

@ -36,10 +36,15 @@ namespace PettingZoo.UI.Tab.Publisher
public string ClassName
{
get => string.IsNullOrEmpty(className) ? AssemblyName + "." : className;
get => string.IsNullOrWhiteSpace(className)
? string.IsNullOrWhiteSpace(AssemblyName)
? ""
: AssemblyName + "."
: className;
set
{
if (SetField(ref className, value))
if (SetField(ref className, value, delegateCommandsChanged: new[] { publishCommand }))
validatingExample = null;
}
}
@ -48,7 +53,7 @@ namespace PettingZoo.UI.Tab.Publisher
public string AssemblyName
{
get => assemblyName;
set => SetField(ref assemblyName, value, otherPropertiesChanged:
set => SetField(ref assemblyName, value, delegateCommandsChanged: new[] { publishCommand }, otherPropertiesChanged:
string.IsNullOrEmpty(value) || string.IsNullOrEmpty(className)
? new [] { nameof(ClassName) }
: null
@ -59,7 +64,7 @@ namespace PettingZoo.UI.Tab.Publisher
public string Payload
{
get => payload;
set => SetField(ref payload, value);
set => SetField(ref payload, value, delegateCommandsChanged: new[] { publishCommand });
}
@ -119,7 +124,7 @@ namespace PettingZoo.UI.Tab.Publisher
{
exampleGenerator.Select(tabHostWindow, example =>
{
Dispatcher.CurrentDispatcher.BeginInvoke(() =>
Application.Current.Dispatcher.BeginInvoke(() =>
{
switch (example)
{
@ -164,12 +169,15 @@ namespace PettingZoo.UI.Tab.Publisher
}
private static bool PublishCanExecute()
private bool PublishCanExecute()
{
// TODO validate input
return true;
return
!string.IsNullOrWhiteSpace(assemblyName) &&
!string.IsNullOrWhiteSpace(ClassName) &&
!string.IsNullOrWhiteSpace(Payload);
}
public void HostWindowChanged(Window? hostWindow)
{
tabHostWindow = hostWindow;

View File

@ -7,6 +7,7 @@
xmlns:res="clr-namespace:PettingZoo.UI.Tab.Subscriber"
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
xmlns:avalonedit="http://icsharpcode.net/sharpdevelop/avalonedit"
xmlns:connection="clr-namespace:PettingZoo.Core.Connection;assembly=PettingZoo.Core"
mc:Ignorable="d"
d:DesignHeight="450"
d:DesignWidth="800"
@ -24,48 +25,46 @@
<ListBox Grid.Column="0" Grid.Row="0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding Messages}"
SelectedItem="{Binding Path=SelectedMessage, Mode=TwoWay}"
ui:ListBox.AutoScroll="True"
x:Name="ReferenceControlForBorder">
x:Name="ReferenceControlForBorder"
Grid.IsSharedSizeScope="True">
<ListBox.Resources>
<ui:BindingProxy x:Key="ContextMenuProxy" Data="{Binding}" />
<CollectionViewSource x:Key="Messages"
Source="{Binding Messages}" />
<CollectionViewSource x:Key="UnreadMessages"
Source="{Binding UnreadMessages}" />
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="150" SharedSizeGroup="DateTime"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- TODO insert as non-focusable item instead, so it's not part of the selection (and perhaps also fixes the bug mentioned in SubscriberViewModel) -->
<Grid Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2">
<ListBox.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource Messages}}" />
<ListBoxItem HorizontalContentAlignment="Stretch" IsEnabled="False" IsHitTestVisible="False">
<Grid Visibility="{Binding UnreadMessagesVisibility}">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="DateTime" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.Visibility>
<MultiBinding Converter="{StaticResource SameMessageVisibilityConverter}">
<Binding RelativeSource="{RelativeSource Self}" Path="DataContext" />
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ListBox}}" Path="DataContext.NewMessage" />
</MultiBinding>
</Grid.Visibility>
<Separator Grid.Column="0" Margin="0,0,8,0" />
<TextBlock Grid.Column="1" Text="{x:Static res:SubscriberViewStrings.LabelNewMessages}" HorizontalAlignment="Center" Background="{Binding Background, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" Foreground="{x:Static SystemColors.GrayTextBrush}" />
<Separator Grid.Column="2" Margin="8,0,0,0" />
</Grid>
</Grid>
</ListBoxItem>
<CollectionContainer Collection="{Binding Source={StaticResource UnreadMessages}}" />
</CompositeCollection>
</ListBox.ItemsSource>
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type connection:ReceivedMessageInfo}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="150" SharedSizeGroup="DateTime"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="1" Text="{Binding ReceivedTimestamp, StringFormat=g}" Style="{StaticResource Timestamp}" />
<TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding RoutingKey}" Style="{StaticResource RoutingKey}" />
<TextBlock Grid.Column="0" Text="{Binding ReceivedTimestamp, StringFormat=g}" Style="{StaticResource Timestamp}" />
<TextBlock Grid.Column="1" Text="{Binding RoutingKey}" Style="{StaticResource RoutingKey}" />
<Grid.ContextMenu>
<ContextMenu>

View File

@ -1,45 +1,55 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Threading;
using PettingZoo.Core.Connection;
using PettingZoo.Core.ExportImport;
using PettingZoo.Core.Rendering;
using PettingZoo.WPF.ProgressWindow;
using PettingZoo.WPF.ViewModel;
// TODO if the "New message" line is visible when this tab is undocked, the line in the ListBox does not shrink. Haven't been able to figure out yet how to solve it
using Serilog;
using Application = System.Windows.Application;
using IConnection = PettingZoo.Core.Connection.IConnection;
using MessageBox = System.Windows.MessageBox;
using Timer = System.Threading.Timer;
namespace PettingZoo.UI.Tab.Subscriber
{
public class SubscriberViewModel : BaseViewModel, ITabToolbarCommands, ITabActivate
{
private readonly ITabHost tabHost;
private readonly ILogger logger;
private readonly ITabHostProvider tabHostProvider;
private readonly ITabFactory tabFactory;
private readonly IConnection connection;
private readonly IConnection? connection;
private readonly ISubscriber subscriber;
private readonly Dispatcher dispatcher;
private readonly IExportImportFormatProvider exportImportFormatProvider;
private ReceivedMessageInfo? selectedMessage;
private readonly DelegateCommand clearCommand;
private readonly DelegateCommand exportCommand;
private readonly TabToolbarCommand[] toolbarCommands;
private IDictionary<string, string>? selectedMessageProperties;
private readonly DelegateCommand createPublisherCommand;
private bool tabActive;
private ReceivedMessageInfo? newMessage;
private Timer? newMessageTimer;
private int unreadCount;
public ICommand ClearCommand => clearCommand;
public ICommand ExportCommand => exportCommand;
// ReSharper disable once UnusedMember.Global - it is, but via a proxy
public ICommand CreatePublisherCommand => createPublisherCommand;
public ObservableCollection<ReceivedMessageInfo> Messages { get; }
public ObservableCollectionEx<ReceivedMessageInfo> Messages { get; }
public ObservableCollectionEx<ReceivedMessageInfo> UnreadMessages { get; }
public ReceivedMessageInfo? SelectedMessage
{
@ -52,11 +62,7 @@ namespace PettingZoo.UI.Tab.Subscriber
}
public ReceivedMessageInfo? NewMessage
{
get => newMessage;
set => SetField(ref newMessage, value);
}
public Visibility UnreadMessagesVisibility => UnreadMessages.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
public string SelectedMessageBody =>
@ -76,21 +82,27 @@ namespace PettingZoo.UI.Tab.Subscriber
public IEnumerable<TabToolbarCommand> ToolbarCommands => toolbarCommands;
public SubscriberViewModel(ITabHost tabHost, ITabFactory tabFactory, IConnection connection, ISubscriber subscriber)
public SubscriberViewModel(ILogger logger, ITabHostProvider tabHostProvider, ITabFactory tabFactory, IConnection? connection, ISubscriber subscriber, IExportImportFormatProvider exportImportFormatProvider)
{
this.tabHost = tabHost;
this.logger = logger;
this.tabHostProvider = tabHostProvider;
this.tabFactory = tabFactory;
this.connection = connection;
this.subscriber = subscriber;
this.exportImportFormatProvider = exportImportFormatProvider;
dispatcher = Dispatcher.CurrentDispatcher;
Messages = new ObservableCollectionEx<ReceivedMessageInfo>();
Messages.AddRange(subscriber.GetInitialMessages());
Messages = new ObservableCollection<ReceivedMessageInfo>();
clearCommand = new DelegateCommand(ClearExecute, ClearCanExecute);
UnreadMessages = new ObservableCollectionEx<ReceivedMessageInfo>();
clearCommand = new DelegateCommand(ClearExecute, HasMessagesCanExecute);
exportCommand = new DelegateCommand(ExportExecute, HasMessagesCanExecute);
toolbarCommands = new[]
{
new TabToolbarCommand(ClearCommand, SubscriberViewStrings.CommandClear, SvgIconHelper.LoadFromResource("/Images/Clear.svg"))
new TabToolbarCommand(ClearCommand, SubscriberViewStrings.CommandClear, SvgIconHelper.LoadFromResource("/Images/Clear.svg")),
new TabToolbarCommand(ExportCommand, SubscriberViewStrings.CommandExport, SvgIconHelper.LoadFromResource("/Images/Export.svg"))
};
createPublisherCommand = new DelegateCommand(CreatePublisherExecute, CreatePublisherCanExecute);
@ -99,47 +111,145 @@ namespace PettingZoo.UI.Tab.Subscriber
subscriber.Start();
}
private void ClearExecute()
{
Messages.Clear();
clearCommand.RaiseCanExecuteChanged();
UnreadMessages.Clear();
HasMessagesChanged();
RaisePropertyChanged(nameof(UnreadMessagesVisibility));
}
private bool ClearCanExecute()
private bool HasMessagesCanExecute()
{
return Messages.Count > 0;
return Messages.Count > 0 || UnreadMessages.Count > 0;
}
private void HasMessagesChanged()
{
clearCommand.RaiseCanExecuteChanged();
exportCommand.RaiseCanExecuteChanged();
}
private void ExportExecute()
{
var formats = exportImportFormatProvider.ExportFormats.ToArray();
var dialog = new SaveFileDialog
{
Filter = string.Join('|', formats.Select(f => f.Filter))
};
if (dialog.ShowDialog() != DialogResult.OK)
return;
// 1-based? Seriously?
if (dialog.FilterIndex <= 0 || dialog.FilterIndex > formats.Length)
return;
var messages = Messages.Concat(UnreadMessages).ToArray();
var filename = dialog.FileName;
var format = formats[dialog.FilterIndex - 1];
var progressWindow = new ProgressWindow(SubscriberViewStrings.ExportProgressWindowTitle)
{
Owner = Application.Current.MainWindow, // TODO I forgot if we have access to our host window here (which can be main or undocked), would be nicer if we did
WindowStartupLocation = WindowStartupLocation.CenterOwner
};
progressWindow.Show();
Task.Run(async () =>
{
try
{
await using (var exportFile = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Read))
{
await format.Export(
exportFile,
new ListEnumerableProgressDecorator<ReceivedMessageInfo>(messages, progressWindow),
progressWindow.CancellationToken);
}
if (progressWindow.CancellationToken.IsCancellationRequested)
return;
await Application.Current.Dispatcher.BeginInvoke(() =>
{
progressWindow.Close();
progressWindow = null;
MessageBox.Show(string.Format(SubscriberViewStrings.ExportSuccess, messages.Length, filename),
SubscriberViewStrings.ExportResultTitle,
MessageBoxButton.OK, MessageBoxImage.Information);
});
}
catch (OperationCanceledException)
{
// User cancelled
}
catch (Exception e)
{
logger.Error(e, "Error while exporting messages");
await Application.Current.Dispatcher.BeginInvoke(() =>
{
progressWindow?.Close();
progressWindow = null;
MessageBox.Show(string.Format(SubscriberViewStrings.ExportError, e.Message),
SubscriberViewStrings.ExportResultTitle,
MessageBoxButton.OK, MessageBoxImage.Information);
});
}
finally
{
if (progressWindow != null)
await Application.Current.Dispatcher.BeginInvoke(() =>
{
progressWindow.Close();
});
}
});
}
private void CreatePublisherExecute()
{
if (connection == null)
return;
var publisherTab = tabFactory.CreatePublisherTab(connection, SelectedMessage);
tabHost.AddTab(publisherTab);
tabHostProvider.Instance.AddTab(publisherTab);
}
private bool CreatePublisherCanExecute()
{
return SelectedMessage != null;
return connection != null && SelectedMessage != null;
}
private void SubscriberMessageReceived(object? sender, MessageReceivedEventArgs args)
{
dispatcher.BeginInvoke(() =>
Application.Current.Dispatcher.BeginInvoke(() =>
{
if (!tabActive)
{
unreadCount++;
RaisePropertyChanged(nameof(Title));
NewMessage ??= args.MessageInfo;
UnreadMessages.Add(args.MessageInfo);
if (UnreadMessages.Count == 1)
RaisePropertyChanged(nameof(UnreadMessagesVisibility));
}
else
Messages.Add(args.MessageInfo);
Messages.Add(args.MessageInfo);
clearCommand.RaiseCanExecuteChanged();
HasMessagesChanged();
});
}
@ -161,16 +271,32 @@ namespace PettingZoo.UI.Tab.Subscriber
RaisePropertyChanged(nameof(Title));
if (NewMessage == null)
if (UnreadMessages.Count == 0)
return;
newMessageTimer?.Dispose();
newMessageTimer = new Timer(
_ =>
{
dispatcher.BeginInvoke(() =>
Application.Current.Dispatcher.BeginInvoke(() =>
{
NewMessage = null;
if (UnreadMessages.Count == 0)
return;
Messages.BeginUpdate();
UnreadMessages.BeginUpdate();
try
{
Messages.AddRange(UnreadMessages);
UnreadMessages.Clear();
}
finally
{
UnreadMessages.EndUpdate();
Messages.EndUpdate();
}
RaisePropertyChanged(nameof(UnreadMessagesVisibility));
});
},
null,
@ -178,6 +304,7 @@ namespace PettingZoo.UI.Tab.Subscriber
Timeout.InfiniteTimeSpan);
}
public void Deactivate()
{
if (newMessageTimer != null)
@ -186,7 +313,6 @@ namespace PettingZoo.UI.Tab.Subscriber
newMessageTimer = null;
}
NewMessage = null;
tabActive = false;
}
}
@ -194,25 +320,24 @@ namespace PettingZoo.UI.Tab.Subscriber
public class DesignTimeSubscriberViewModel : SubscriberViewModel
{
public DesignTimeSubscriberViewModel() : base(null!, null!, null!, new DesignTimeSubscriber())
public DesignTimeSubscriberViewModel() : base(null!, null!, null!, null!, new DesignTimeSubscriber(), null!)
{
for (var i = 1; i <= 5; i++)
Messages.Add(new ReceivedMessageInfo(
"designtime",
$"designtime.message.{i}",
Encoding.UTF8.GetBytes(@"Design-time message"),
(i > 2 ? UnreadMessages : Messages).Add(new ReceivedMessageInfo(
"designtime",
$"designtime.message.{i}",
Encoding.UTF8.GetBytes(@"Design-time message"),
new MessageProperties(null)
{
ContentType = "text/fake",
ReplyTo = "/dev/null"
},
},
DateTime.Now));
SelectedMessage = Messages[2];
NewMessage = Messages[2];
SelectedMessage = UnreadMessages[0];
}
private class DesignTimeSubscriber : ISubscriber
{
public ValueTask DisposeAsync()
@ -229,9 +354,16 @@ namespace PettingZoo.UI.Tab.Subscriber
public event EventHandler<MessageReceivedEventArgs>? MessageReceived;
#pragma warning restore CS0067
public IEnumerable<ReceivedMessageInfo> GetInitialMessages()
{
return Enumerable.Empty<ReceivedMessageInfo>();
}
public void Start()
{
}
}
}
}
}

View File

@ -69,6 +69,15 @@ namespace PettingZoo.UI.Tab.Subscriber {
}
}
/// <summary>
/// Looks up a localized string similar to Export....
/// </summary>
public static string CommandExport {
get {
return ResourceManager.GetString("CommandExport", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Open in new Publisher tab.
/// </summary>
@ -96,6 +105,42 @@ namespace PettingZoo.UI.Tab.Subscriber {
}
}
/// <summary>
/// Looks up a localized string similar to Error while exporting messages: {0}.
/// </summary>
public static string ExportError {
get {
return ResourceManager.GetString("ExportError", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Exporting messages....
/// </summary>
public static string ExportProgressWindowTitle {
get {
return ResourceManager.GetString("ExportProgressWindowTitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Export.
/// </summary>
public static string ExportResultTitle {
get {
return ResourceManager.GetString("ExportResultTitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Exported {0} message(s) to {1}.
/// </summary>
public static string ExportSuccess {
get {
return ResourceManager.GetString("ExportSuccess", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to New messages.
/// </summary>

View File

@ -120,6 +120,9 @@
<data name="CommandClear" xml:space="preserve">
<value>Clear</value>
</data>
<data name="CommandExport" xml:space="preserve">
<value>Export...</value>
</data>
<data name="ContextPublish" xml:space="preserve">
<value>Open in new Publisher tab</value>
</data>
@ -129,6 +132,18 @@
<data name="DeliveryModePersistent" xml:space="preserve">
<value>Persistent</value>
</data>
<data name="ExportError" xml:space="preserve">
<value>Error while exporting messages: {0}</value>
</data>
<data name="ExportProgressWindowTitle" xml:space="preserve">
<value>Exporting messages...</value>
</data>
<data name="ExportResultTitle" xml:space="preserve">
<value>Export</value>
</data>
<data name="ExportSuccess" xml:space="preserve">
<value>Exported {0} message(s) to {1}</value>
</data>
<data name="LabelNewMessages" xml:space="preserve">
<value>New messages</value>
</data>

View File

@ -0,0 +1,18 @@
using System;
namespace PettingZoo.UI.Tab
{
public class TabHostProvider : ITabHostProvider
{
private ITabHost? instance;
public ITabHost Instance => instance ?? throw new InvalidOperationException("ITabHost instance must be initialized before acquiring");
// ReSharper disable once ParameterHidesMember
public void SetInstance(ITabHost instance)
{
this.instance = instance;
}
}
}

View File

@ -10,7 +10,7 @@ namespace PettingZoo.UI.Tab.Undocked
{
public class UndockedTabHostViewModel : BaseViewModel, ITabActivate
{
private readonly ITabHost tabHost;
private readonly ITabHostProvider tabHostProvider;
private readonly ITab tab;
private readonly DelegateCommand dockCommand;
@ -25,9 +25,9 @@ namespace PettingZoo.UI.Tab.Undocked
public ICommand DockCommand => dockCommand;
public UndockedTabHostViewModel(ITabHost tabHost, ITab tab)
public UndockedTabHostViewModel(ITabHostProvider tabHostProvider, ITab tab)
{
this.tabHost = tabHost;
this.tabHostProvider = tabHostProvider;
this.tab = tab;
tab.PropertyChanged += (_, args) =>
@ -43,13 +43,13 @@ namespace PettingZoo.UI.Tab.Undocked
private void DockCommandExecute()
{
tabHost.DockTab(tab);
tabHostProvider.Instance.DockTab(tab);
}
public void WindowClosed()
{
tabHost.UndockedTabClosed(tab);
tabHostProvider.Instance.UndockedTabClosed(tab);
}

View File

@ -10,9 +10,9 @@ namespace PettingZoo.UI.Tab.Undocked
/// </summary>
public partial class UndockedTabHostWindow
{
public static UndockedTabHostWindow Create(ITabHost tabHost, ITab tab, double width, double height)
public static UndockedTabHostWindow Create(ITabHostProvider tabHostProvider, ITab tab, double width, double height)
{
var viewModel = new UndockedTabHostViewModel(tabHost, tab);
var viewModel = new UndockedTabHostViewModel(tabHostProvider, tab);
var window = new UndockedTabHostWindow(viewModel)
{
Width = width,

View File

@ -1,26 +1,32 @@
using PettingZoo.Core.Connection;
using PettingZoo.Core.ExportImport;
using PettingZoo.Core.Generator;
using PettingZoo.UI.Tab.Publisher;
using PettingZoo.UI.Tab.Subscriber;
using Serilog;
namespace PettingZoo.UI.Tab
{
public class ViewTabFactory : ITabFactory
{
private readonly ITabHost tabHost;
private readonly ILogger logger;
private readonly ITabHostProvider tabHostProvider;
private readonly IExampleGenerator exampleGenerator;
private readonly IExportImportFormatProvider exportImportFormatProvider;
public ViewTabFactory(ITabHost tabHost, IExampleGenerator exampleGenerator)
public ViewTabFactory(ILogger logger, ITabHostProvider tabHostProvider, IExampleGenerator exampleGenerator, IExportImportFormatProvider exportImportFormatProvider)
{
this.tabHost = tabHost;
this.logger = logger;
this.tabHostProvider = tabHostProvider;
this.exampleGenerator = exampleGenerator;
this.exportImportFormatProvider = exportImportFormatProvider;
}
public ITab CreateSubscriberTab(IConnection connection, ISubscriber subscriber)
public ITab CreateSubscriberTab(IConnection? connection, ISubscriber subscriber)
{
var viewModel = new SubscriberViewModel(tabHost, this, connection, subscriber);
var viewModel = new SubscriberViewModel(logger, tabHostProvider, this, connection, subscriber, exportImportFormatProvider);
return new ViewTab<SubscriberView, SubscriberViewModel>(
new SubscriberView(viewModel),
viewModel,
@ -30,7 +36,7 @@ namespace PettingZoo.UI.Tab
public ITab CreatePublisherTab(IConnection connection, ReceivedMessageInfo? fromReceivedMessage = null)
{
var viewModel = new PublisherViewModel(tabHost, this, connection, exampleGenerator, fromReceivedMessage);
var viewModel = new PublisherViewModel(tabHostProvider, this, connection, exampleGenerator, fromReceivedMessage);
return new ViewTab<PublisherView, PublisherViewModel>(
new PublisherView(viewModel),
viewModel,

View File

@ -1,12 +1,45 @@
# ![Petting Zoo](https://raw.githubusercontent.com/MvRens/PettingZoo/master/PettingZoo/Images/PettingZoo-48.png) Petting Zoo
##### A RabbitMQ live message viewer
# ![Petting Zoo](./PettingZoo/Images/PettingZoo-48.png) Petting Zoo
##### A RabbitMQ live message viewer (and publisher)
ToDo: explain how it brings you coffee, fame and world peace. Or maybe just makes watching the messages flow slightly more comfortable.
PettingZoo provides a desktop interface for subscribing and publishing to RabbitMQ. It is a useful tool in debugging, allowing you to monitor the flow of messages in a running system and replay those messages if required.
PettingZoo requires .NET 6 to run.
## Features
1. Subscribe to one or more exchanges with specified routing keys to inspect published messages
2. Publish new messages to an exchange or to a specific queue
3. JSON syntax highlighting and validation
4. Support for publishing and validating [Tapeti](https://github.com/MvRens/Tapeti) messages from assembly files or directly from (private) NuGet feeds
5. Support for exporting and importing [Tapeti.Cmd](https://github.com/MvRens/Tapeti.Cmd) compatible single-file JSON
## Builds
Builds are automatically run using AppVeyor. Release versions are available as a [GitHub release](https://github.com/MvRens/PettingZoo/releases) and include a ZIP file containing the executable and required files for 64-bits Windows.
Extract the ZIP file and run PettingZoo.exe to get started.
The source code is compiled using Visual Studio 2022.
[![Build status](https://ci.appveyor.com/api/projects/status/gqsw03v2evy0l0gv/branch/master?svg=true)](https://ci.appveyor.com/project/MvRens/pettingzoo/branch/master) Master build (stable release)
[![Build status](https://ci.appveyor.com/api/projects/status/gqsw03v2evy0l0gv?svg=true)](https://ci.appveyor.com/project/MvRens/pettingzoo) Latest build
## Screenshots
##### Subscribing to messages
![Subscribe example](./Docs/Subscribe.png)
##### Publishing a message
![Publish example](./Docs/Publish.png)
##### Publishing a message from a Tapeti-compatible assembly
![Tapeti publish example](./Docs/TapetiPublish.png)
## Credits
#### Icons
Toolbar icons are from the Interaction Assets pack by Madebyoliver
Toolbar icons are from the (now defunct) Interaction Assets pack by Madebyoliver
<http://www.flaticon.com/authors/madebyoliver>
Designed by Freepik and distributed by Flaticon