diff --git a/.idea/.idea.PSCHelpdesk/.idea/.name b/.idea/.idea.PSCHelpdesk/.idea/.name
deleted file mode 100644
index 6f7d947..0000000
--- a/.idea/.idea.PSCHelpdesk/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-PSCHelpdesk
\ No newline at end of file
diff --git a/.idea/.idea.PSCHelpdesk/.idea/workspace.xml b/.idea/.idea.PSCHelpdesk/.idea/workspace.xml
index 5d5768f..a5a2607 100644
--- a/.idea/.idea.PSCHelpdesk/.idea/workspace.xml
+++ b/.idea/.idea.PSCHelpdesk/.idea/workspace.xml
@@ -11,24 +11,87 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -114,35 +177,35 @@
- {
- "keyToString": {
- ".NET Project.PSCHelpdesk.Desktop ohne plugin.executor": "Run",
- ".NET Project.PSCHelpdesk.Desktop.executor": "Debug",
- "Publish to folder.Build HetznerServer Plugin Debug.executor": "Run",
- "Publish to folder.Copy Hetzner Target.executor": "Run",
- "Publish to folder.Copy NextCloud Target.executor": "Run",
- "Publish to folder.Publish HetznerServer to folder.executor": "Run",
- "Publish to folder.Publish NextCloud to folder.executor": "Run",
- "Publish to folder.Publish Nextcloud to folder.executor": "Run",
- "RunOnceActivity.ShowReadmeOnStart": "true",
- "XThreadsFramesViewSplitterKey": "0.4427131",
- "git-widget-placeholder": "master",
- "ignore.virus.scanning.warn.message": "true",
- "last_opened_file_path": "/home/thomas/RiderProjects/PSCHelpdesk/PSCHelpdesk/PSCHelpdesk.Desktop/bin/Debug/net9.0/plugins",
- "node.js.detected.package.eslint": "true",
- "node.js.detected.package.tslint": "true",
- "node.js.selected.package.eslint": "(autodetect)",
- "node.js.selected.package.tslint": "(autodetect)",
- "nodejs_package_manager_path": "npm",
- "settings.editor.selected.configurable": "SolutionBuilderGeneralOptionsPage",
- "vue.rearranger.settings.migration": "true"
+
+}]]>
@@ -258,6 +321,7 @@
+
@@ -286,14 +350,7 @@
file://$PROJECT_DIR$/HetznerServer/Menu/MainMenu.cs13
-
-
-
-
-
-
-
-
+
@@ -361,24 +418,6 @@
-
- file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/dd582eafcc7da4dc5ece1e7e4de37b1f271b42b4cea54a2aecfe3bda3fd2e5a/HyperlinkButton.cs
- 80
-
-
-
-
- file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/dd582eafcc7da4dc5ece1e7e4de37b1f271b42b4cea54a2aecfe3bda3fd2e5a/HyperlinkButton.cs
- 78
-
-
-
-
- file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/dd582eafcc7da4dc5ece1e7e4de37b1f271b42b4cea54a2aecfe3bda3fd2e5a/HyperlinkButton.cs
- 60
-
-
- file://$PROJECT_DIR$/HetznerServer/Views/ServerView.axaml.cs29
diff --git a/HetznerServer/Views/ServerView.axaml b/HetznerServer/Views/ServerView.axaml
index 0183ba8..b1579fd 100644
--- a/HetznerServer/Views/ServerView.axaml
+++ b/HetznerServer/Views/ServerView.axaml
@@ -92,6 +92,11 @@
+
+
+
diff --git a/Nextcloud/Views/NotesView.axaml b/Nextcloud/Views/NotesView.axaml
index 0457ef0..52d9e0f 100644
--- a/Nextcloud/Views/NotesView.axaml
+++ b/Nextcloud/Views/NotesView.axaml
@@ -14,7 +14,12 @@
DisplayMode="Inline"
OpenPaneLength="300">
-
+
+
+
+
diff --git a/PSCHelpdesk/PSCHelpdesk.Desktop/PSCHelpdesk.Desktop.csproj b/PSCHelpdesk/PSCHelpdesk.Desktop/PSCHelpdesk.Desktop.csproj
index bef86cc..116b071 100644
--- a/PSCHelpdesk/PSCHelpdesk.Desktop/PSCHelpdesk.Desktop.csproj
+++ b/PSCHelpdesk/PSCHelpdesk.Desktop/PSCHelpdesk.Desktop.csproj
@@ -6,6 +6,7 @@
net9.0enabletrue
+ Always
@@ -28,7 +29,29 @@
-
-
+
+
+
+
+
+
+
+
diff --git a/_dist/hetzner/Avalonia.Base.dll b/_dist/hetzner/Avalonia.Base.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.Controls.dll b/_dist/hetzner/Avalonia.Controls.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.DesignerSupport.dll b/_dist/hetzner/Avalonia.DesignerSupport.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.Dialogs.dll b/_dist/hetzner/Avalonia.Dialogs.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.Markup.Xaml.dll b/_dist/hetzner/Avalonia.Markup.Xaml.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.Markup.dll b/_dist/hetzner/Avalonia.Markup.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.Metal.dll b/_dist/hetzner/Avalonia.Metal.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.MicroCom.dll b/_dist/hetzner/Avalonia.MicroCom.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.OpenGL.dll b/_dist/hetzner/Avalonia.OpenGL.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.ReactiveUI.dll b/_dist/hetzner/Avalonia.ReactiveUI.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.Remote.Protocol.dll b/_dist/hetzner/Avalonia.Remote.Protocol.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.Vulkan.dll b/_dist/hetzner/Avalonia.Vulkan.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.Xaml.Interactions.Custom.dll b/_dist/hetzner/Avalonia.Xaml.Interactions.Custom.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.Xaml.Interactions.DragAndDrop.dll b/_dist/hetzner/Avalonia.Xaml.Interactions.DragAndDrop.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.Xaml.Interactions.Draggable.dll b/_dist/hetzner/Avalonia.Xaml.Interactions.Draggable.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.Xaml.Interactions.Events.dll b/_dist/hetzner/Avalonia.Xaml.Interactions.Events.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.Xaml.Interactions.Responsive.dll b/_dist/hetzner/Avalonia.Xaml.Interactions.Responsive.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.Xaml.Interactions.dll b/_dist/hetzner/Avalonia.Xaml.Interactions.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.Xaml.Interactivity.dll b/_dist/hetzner/Avalonia.Xaml.Interactivity.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Avalonia.dll b/_dist/hetzner/Avalonia.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/DynamicData.dll b/_dist/hetzner/DynamicData.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/HetznerCloudApi.dll b/_dist/hetzner/HetznerCloudApi.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/HetznerServer.dll b/_dist/hetzner/HetznerServer.dll
index aba62a7..166d678 100644
Binary files a/_dist/hetzner/HetznerServer.dll and b/_dist/hetzner/HetznerServer.dll differ
diff --git a/_dist/hetzner/HetznerServer.pdb b/_dist/hetzner/HetznerServer.pdb
index cda2ac0..36a5c02 100644
Binary files a/_dist/hetzner/HetznerServer.pdb and b/_dist/hetzner/HetznerServer.pdb differ
diff --git a/_dist/hetzner/MicroCom.Runtime.dll b/_dist/hetzner/MicroCom.Runtime.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Microsoft.Extensions.DependencyInjection.Abstractions.dll b/_dist/hetzner/Microsoft.Extensions.DependencyInjection.Abstractions.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Microsoft.Extensions.DependencyInjection.dll b/_dist/hetzner/Microsoft.Extensions.DependencyInjection.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Newtonsoft.Json.dll b/_dist/hetzner/Newtonsoft.Json.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/ReactiveUI.dll b/_dist/hetzner/ReactiveUI.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Renci.SshNet.dll b/_dist/hetzner/Renci.SshNet.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/Splat.dll b/_dist/hetzner/Splat.dll
old mode 100644
new mode 100755
diff --git a/_dist/hetzner/System.Reactive.dll b/_dist/hetzner/System.Reactive.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.Base.dll b/_dist/nextcloud/Avalonia.Base.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.Controls.dll b/_dist/nextcloud/Avalonia.Controls.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.DesignerSupport.dll b/_dist/nextcloud/Avalonia.DesignerSupport.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.Dialogs.dll b/_dist/nextcloud/Avalonia.Dialogs.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.Markup.Xaml.dll b/_dist/nextcloud/Avalonia.Markup.Xaml.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.Markup.dll b/_dist/nextcloud/Avalonia.Markup.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.Metal.dll b/_dist/nextcloud/Avalonia.Metal.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.MicroCom.dll b/_dist/nextcloud/Avalonia.MicroCom.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.OpenGL.dll b/_dist/nextcloud/Avalonia.OpenGL.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.ReactiveUI.dll b/_dist/nextcloud/Avalonia.ReactiveUI.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.Remote.Protocol.dll b/_dist/nextcloud/Avalonia.Remote.Protocol.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.Svg.dll b/_dist/nextcloud/Avalonia.Svg.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.Vulkan.dll b/_dist/nextcloud/Avalonia.Vulkan.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.Xaml.Interactions.Custom.dll b/_dist/nextcloud/Avalonia.Xaml.Interactions.Custom.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.Xaml.Interactions.DragAndDrop.dll b/_dist/nextcloud/Avalonia.Xaml.Interactions.DragAndDrop.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.Xaml.Interactions.Draggable.dll b/_dist/nextcloud/Avalonia.Xaml.Interactions.Draggable.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.Xaml.Interactions.Events.dll b/_dist/nextcloud/Avalonia.Xaml.Interactions.Events.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.Xaml.Interactions.Responsive.dll b/_dist/nextcloud/Avalonia.Xaml.Interactions.Responsive.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.Xaml.Interactions.dll b/_dist/nextcloud/Avalonia.Xaml.Interactions.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.Xaml.Interactivity.dll b/_dist/nextcloud/Avalonia.Xaml.Interactivity.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Avalonia.dll b/_dist/nextcloud/Avalonia.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/AvaloniaEdit.dll b/_dist/nextcloud/AvaloniaEdit.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/ColorTextBlock.Avalonia.dll b/_dist/nextcloud/ColorTextBlock.Avalonia.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/CommunityToolkit.Mvvm.dll b/_dist/nextcloud/CommunityToolkit.Mvvm.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/CommunityToolkit.Mvvm.pdb b/_dist/nextcloud/CommunityToolkit.Mvvm.pdb
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/CommunityToolkit.Mvvm.xml b/_dist/nextcloud/CommunityToolkit.Mvvm.xml
old mode 100644
new mode 100755
index be75f03..63cfd9d
--- a/_dist/nextcloud/CommunityToolkit.Mvvm.xml
+++ b/_dist/nextcloud/CommunityToolkit.Mvvm.xml
@@ -1,4490 +1,4490 @@
-
-
-
- CommunityToolkit.Mvvm
-
-
-
-
- A helper type for the type.
-
-
-
-
- The cached for
-
-
-
-
- An interface for a grouped collection of items.
-
-
-
-
- Gets the key for the current collection.
-
-
-
-
- Gets the number of items currently in the grouped collection.
-
-
-
-
- Gets the element at the specified index in the current collection.
-
- The zero-based index of the element to get.
- The element at the specified index in the read-only list.
- Thrown if the index is out of range.
-
-
-
- An interface for a grouped collection of items.
-
- The type of the group key.
- The type of elements in the group.
-
-
-
- Gets the element at the specified index in the current collection.
-
- The zero-based index of the element to get.
- The element at the specified index in the read-only list.
- Thrown if the index is out of range.
-
-
-
- An interface for a grouped collection of items.
-
- The type of the group key.
-
-
-
- Gets the key for the current collection.
-
-
-
-
- The extensions methods to simplify the usage of .
-
-
-
-
- Returns the first group with key.
-
- The type of the group key.
- The type of the items in the collection.
- The source instance.
- The key of the group to query.
- The first group matching .
- Thrown if or are .
- The target group does not exist.
-
-
-
- Returns the first group with key or if not found.
-
- The type of the group key.
- The type of the items in the collection.
- The source instance.
- The key of the group to query.
- The first group matching or .
- Thrown if or are .
-
-
-
- Adds a key-value item into a target .
-
- The type of the group key.
- The type of the items in the collection.
- The source instance.
- The key of the group to add.
- The added .
- Thrown if or are .
-
-
-
- Adds a key-collection item into a target .
-
- The type of the group key.
- The type of the items in the collection.
- The source instance.
- The group of items to add.
- The added .
- Thrown if or are .
-
-
-
- Adds a key-collection item into a target .
-
- The type of the group key.
- The type of the items in the collection.
- The source instance.
- The key of the group where will be added.
- The collection to add.
- The added .
- Thrown if , or are .
-
-
-
- Adds a key-value item into a target .
-
- The type of the group key.
- The type of the items in the collection.
- The source instance.
- The key of the group to add.
- The added .
- Thrown if or are .
-
-
-
- Adds a key-value item into a target .
-
- The type of the group key.
- The type of the items in the collection.
- The source instance.
- The group of items to add.
- The added .
- Thrown if or are .
-
-
-
- Adds a key-value item into a target .
-
- The type of the group key.
- The type of the items in the collection.
- The source instance.
- The key of the group where will be added.
- The collection to add.
- The added .
- Thrown if , or are .
-
-
-
- Adds a key-value item into a target .
-
- The type of the group key.
- The type of the items in the collection.
- The source instance.
- The key of the group to add.
- The instance to insert at the right position.
- The added .
- Thrown if , or are .
-
-
-
- Adds a key-value item into a target .
-
- The type of the group key.
- The type of the items in the collection.
- The source instance.
- The group of items to add.
- The instance to insert at the right position.
- The added .
- Thrown if , or are .
-
-
-
- Adds a key-value item into a target .
-
- The type of the group key.
- The type of the items in the collection.
- The source instance.
- The key of the group where will be added.
- The instance to insert at the right position.
- The collection to add.
- The added .
- Thrown if , , or are .
-
-
-
- Add into the first group with key.
- If the group does not exist, it will be added.
-
- The type of the group key.
- The type of the items in the collection.
- The source instance.
- The key of the group where the should be added.
- The item to add.
- The instance of the which will receive the value. It will either be an existing group or a new group.
- Thrown if or are .
-
-
-
- Insert into the first group with key.
-
- The type of the group key.
- The type of the items in the collection.
- The source instance.
- The key of the group where to insert .
- The item to add.
- The instance of the which will receive the value.
- Thrown if or are .
-
-
-
- Insert into the first group with key.
-
- The type of the group key.
- The type of the items in the collection.
- The source instance.
- The key of the group where to insert .
- The instance to compare keys.
- The item to add.
- The instance to compare elements.
- The instance of the which will receive the value.
- Thrown if , , or are .
-
-
-
- Remove the first occurrence of the group with from the grouped collection.
- It will not do anything if the group does not exist.
-
- The type of the group key.
- The type of the items in the collection.
- The source instance.
- The key of the group to remove.
- Thrown if or are .
-
-
-
- Remove the first from the first group with from the grouped collection.
- It will not do anything if the group or the item does not exist.
-
- The type of the group key.
- The type of the items in the collection.
- The source instance.
- The key of the group where the should be removed.
- The item to remove.
- If true (default value), the group will be removed once it becomes empty.
- Thrown if or are .
-
-
-
- An observable list of observable groups.
-
- The type of the group keys.
- The type of elements in the collection.
-
-
-
- Initializes a new instance of the class.
-
-
-
-
- Initializes a new instance of the class.
-
- The initial data to add in the grouped collection.
- Thrown if is .
-
-
-
-
-
-
- Tries to get the underlying instance, if present.
-
- The resulting , if one was in use.
- Whether or not a instance has been found.
-
-
-
-
-
-
-
-
-
- An observable group.
- It associates a to an .
-
- The type of the group key.
- The type of elements in the group.
-
-
-
- Initializes a new instance of the class.
-
- The key for the group.
- Thrown if is .
-
-
-
- Initializes a new instance of the class.
-
- The grouping to fill the group.
- Thrown if is .
-
-
-
- Initializes a new instance of the class.
-
- The key for the group.
- The initial collection of data to add to the group.
- Thrown if or are .
-
-
-
- Gets or sets the key of the group.
-
- Thrown if is .
-
-
-
- Tries to get the underlying instance, if present.
-
- The resulting , if one was in use.
- Whether or not a instance has been found.
-
-
-
-
-
-
-
-
-
- A read-only list of groups.
-
- The type of the group keys.
- The type of elements in the collection.
-
-
-
- Initializes a new instance of the class.
-
- The source collection to wrap.
- Thrown if is .
-
-
-
- Initializes a new instance of the class.
-
- The source collection to wrap.
- Thrown if is .
-
-
-
-
-
-
-
-
-
-
-
-
- Forwards the event whenever it is raised by the wrapped collection.
-
- The wrapped collection (an of instance).
- The arguments.
- Thrown if a range operation is requested.
-
-
-
- Returns the first group with key or if not found.
-
- The key of the group to query (assumed not to be ).
- The first group matching .
-
-
-
- A read-only observable group. It associates a to a .
-
- The type of the group key.
- The type of elements in the group.
-
-
-
- Initializes a new instance of the class.
-
- The key of the group.
- The collection of items to add in the group.
- Thrown if or are .
-
-
-
- Initializes a new instance of the class.
-
- The to wrap.
- Thrown if is .
-
-
-
-
-
-
-
-
-
-
-
-
- An attribute that indicates that a given type should implement the interface and
- have minimal built-in functionality to support it. This includes exposing the necessary event and having two methods
- to raise it that mirror and
- . For more extensive support, use .
-
- This attribute can be used as follows:
-
- [INotifyPropertyChanged]
- partial class MyViewModel : SomeOtherClass
- {
- // Other members here...
- }
-
-
-
-
-
-
- Gets or sets a value indicating whether or not to also generate all the additional helper methods that are found
- in as well (eg. .
- If set to , only the event and
- the two overloads will be generated.
- The default value is .
-
-
-
-
- An attribute that can be used to support properties in generated properties. When this attribute is
- used, the generated property setter will also call for the properties specified
- in the attribute data, causing the validation logic for the command to be executed again. This can be useful to keep the code compact
- when there are one or more dependent commands that should also be notified when a property is updated. If this attribute is used in
- a field without , it is ignored (just like ).
-
- In order to use this attribute, the target property has to implement the interface.
-
-
- This attribute can be used as follows:
-
- partial class MyViewModel : ObservableObject
- {
- [ObservableProperty]
- [NotifyCanExecuteChangedFor(nameof(GreetUserCommand))]
- private string name;
-
- public IRelayCommand GreetUserCommand { get; }
- }
-
-
- And with this, code analogous to this will be generated:
-
- partial class MyViewModel
- {
- public string Name
- {
- get => name;
- set
- {
- if (SetProperty(ref name, value))
- {
- GreetUserCommand.NotifyCanExecuteChanged();
- }
- }
- }
- }
-
-
-
-
-
- Initializes a new instance of the class.
-
- The name of the command to also notify when the annotated property changes.
-
-
-
- Initializes a new instance of the class.
-
- The name of the property to also notify when the annotated property changes.
-
- The other command names to also notify when the annotated property changes. This parameter can optionally
- be used to indicate a series of dependent commands from the same attribute, to keep the code more compact.
-
-
-
-
- Gets the command names to also notify when the annotated property changes.
-
-
-
-
- An attribute that can be used to support in generated properties, when applied to
- fields contained in a type that is inheriting from and using any validation attributes.
- When this attribute is used, the generated property setter will also call .
- This allows generated properties to opt-in into validation behavior without having to fallback into a full explicit observable property.
-
- This attribute can be used as follows:
-
- partial class MyViewModel : ObservableValidator
- {
- [ObservableProperty]
- [NotifyDataErrorInfo]
- [Required]
- [MinLength(2)]
- private string username;
- }
-
-
- And with this, code analogous to this will be generated:
-
- partial class MyViewModel
- {
- [Required]
- [MinLength(2)]
- public string Username
- {
- get => username;
- set => SetProperty(ref username, value, validate: true);
- }
- }
-
-
-
-
-
- An attribute that can be used to support in generated properties. When this attribute is
- used, the generated property setter will also call (or the equivalent
- method in the target class) for the properties specified in the attribute data. This can be useful to keep the code compact when
- there are one or more dependent properties that should also be reported as updated when the value of the annotated observable
- property is changed. If this attribute is used in a field without , it is ignored.
-
- In order to use this attribute, the containing type has to implement the interface
- and expose a method with the same signature as . If the containing
- type also implements the interface and exposes a method with the same signature as
- , then this method will be invoked as well by the property setter.
-
-
- This attribute can be used as follows:
-
- partial class MyViewModel : ObservableObject
- {
- [ObservableProperty]
- [NotifyPropertyChangedFor(nameof(FullName))]
- private string name;
-
- [ObservableProperty]
- [NotifyPropertyChangedFor(nameof(FullName))]
- private string surname;
-
- public string FullName => $"{Name} {Surname}";
- }
-
-
- And with this, code analogous to this will be generated:
-
- partial class MyViewModel
- {
- public string Name
- {
- get => name;
- set
- {
- if (!EqualityComparer<string>.Default.Equals(name, value))
- {
- OnPropertyChanging(nameof(Name));
- OnPropertyChanged(nameof(FullName));
-
- name = value;
-
- OnPropertyChanged(nameof(Name));
- OnPropertyChanged(nameof(FullName));
- }
- }
- }
-
- public string Surname
- {
- get => surname;
- set
- {
- if (!EqualityComparer<string>.Default.Equals(name, value))
- {
- OnPropertyChanging(nameof(Surname));
- OnPropertyChanged(nameof(FullName));
-
- surname = value;
-
- OnPropertyChanged(nameof(Surname));
- OnPropertyChanged(nameof(FullName));
- }
- }
- }
- }
-
-
-
-
-
- Initializes a new instance of the class.
-
- The name of the property to also notify when the annotated property changes.
-
-
-
- Initializes a new instance of the class.
-
- The name of the property to also notify when the annotated property changes.
-
- The other property names to also notify when the annotated property changes. This parameter can optionally
- be used to indicate a series of dependent properties from the same attribute, to keep the code more compact.
-
-
-
-
- Gets the property names to also notify when the annotated property changes.
-
-
-
-
- An attribute that can be used to support in generated properties, when applied to fields
- contained in a type that is either inheriting from , or annotated with .
- When this attribute is used, the generated property setter will also call .
- This allows generated properties to opt-in into broadcasting behavior without having to fallback into a full explicit observable property.
-
- This attribute can be used as follows:
-
- partial class MyViewModel : ObservableRecipient
- {
- [ObservableProperty]
- [NotifyPropertyChangedRecipients]
- private string username;
- }
-
-
-
- And with this, code analogous to this will be generated:
-
- partial class MyViewModel
- {
- public string Username
- {
- get => username;
- set => SetProperty(ref username, value, broadcast: true);
- }
- }
-
-
-
- This attribute can also be added to a class, and if so it will affect all generated properties in that type and inherited types.
-
-
-
-
-
- An attribute that indicates that a given type should have all the members from
- generated into it, as well as the and
- interfaces. This can be useful when you want the same functionality from into a class
- that already inherits from another one (since C# doesn't support multiple inheritance). This attribute will trigger
- the source generator to just create the same APIs directly into the decorated class.
-
- This attribute can be used as follows:
-
- [ObservableObject]
- partial class MyViewModel : SomeOtherClass
- {
- // Other members here...
- }
-
-
- And with this, the same APIs from will be available on this type as well.
-
-
-
-
- An attribute that indicates that a given field should be wrapped by a generated observable property.
- In order to use this attribute, the containing type has to inherit from , or it
- must be using or .
- If the containing type also implements the (that is, if it either inherits from
- or is using ), then the generated code will
- also invoke to signal that event.
-
- This attribute can be used as follows:
-
- partial class MyViewModel : ObservableObject
- {
- [ObservableProperty]
- private string name;
-
- [ObservableProperty]
- private bool isEnabled;
- }
-
-
- And with this, code analogous to this will be generated:
-
- partial class MyViewModel
- {
- public string Name
- {
- get => name;
- set => SetProperty(ref name, value);
- }
-
- public bool IsEnabled
- {
- get => isEnabled;
- set => SetProperty(ref isEnabled, value);
- }
- }
-
-
-
- The generated properties will automatically use the UpperCamelCase format for their names,
- which will be derived from the field names. The generator can also recognize fields using either
- the _lowerCamel or m_lowerCamel naming scheme. Otherwise, the first character in the
- source field name will be converted to uppercase (eg. isEnabled to IsEnabled).
-
-
-
-
- An attribute that indicates that a given type should have all the members from
- generated into it. This can be useful when you want the same functionality from into
- a class that already inherits from another one (since C# doesn't support multiple inheritance). This attribute will trigger
- the source generator to just create the same APIs directly into the decorated class. For instance, this attribute can be
- used to easily combine the functionality from both and ,
- by using as the base class and adding this attribute to the declared type.
-
- This attribute can be used as follows:
-
- [ObservableRecipient]
- partial class MyViewModel : ObservableValidator
- {
- // Other members here...
- }
-
-
- And with this, the same APIs from will be available on this type as well.
-
- To avoid conflicts with other APIs in types where the new members are being generated, constructors are only generated when the annotated
- type doesn't have any explicit constructors being declared. If that is the case, the same constructors from
- are emitted, with the accessibility adapted to that of the annotated type. Otherwise, they are skipped, so the type being annotated has the
- responsibility of properly initializing the property. Additionally, if the annotated type inherits
- from , the overloads will be skipped
- as well, as they would conflict with the methods.
-
-
-
- In order to work, needs to be applied to a type that inherits from
- (either directly or indirectly), or to one decorated with .
- This is because the methods rely on some of the inherited members to work.
- If this condition is not met, the code will fail to build.
-
-
-
-
- A base class for objects of which the properties must be observable.
-
-
-
-
-
-
-
-
-
-
- Raises the event.
-
- The input instance.
- Thrown if is .
-
-
-
- Raises the event.
-
- The input instance.
- Thrown if is .
-
-
-
- Raises the event.
-
- (optional) The name of the property that changed.
-
-
-
- Raises the event.
-
- (optional) The name of the property that changed.
-
-
-
- Compares the current and new values for a given property. If the value has changed,
- raises the event, updates the property with the new
- value, then raises the event.
-
- The type of the property that changed.
- The field storing the property's value.
- The property's value after the change occurred.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
-
- The and events are not raised
- if the current and new value for the target property are the same.
-
-
-
-
- Compares the current and new values for a given property. If the value has changed,
- raises the event, updates the property with the new
- value, then raises the event.
- See additional notes about this overload in .
-
- The type of the property that changed.
- The field storing the property's value.
- The property's value after the change occurred.
- The instance to use to compare the input values.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
- Thrown if is .
-
-
-
- Compares the current and new values for a given property. If the value has changed,
- raises the event, updates the property with the new
- value, then raises the event.
- This overload is much less efficient than and it
- should only be used when the former is not viable (eg. when the target property being
- updated does not directly expose a backing field that can be passed by reference).
- For performance reasons, it is recommended to use a stateful callback if possible through
- the whenever possible
- instead of this overload, as that will allow the C# compiler to cache the input callback and
- reduce the memory allocations. More info on that overload are available in the related XML
- docs. This overload is here for completeness and in cases where that is not applicable.
-
- The type of the property that changed.
- The current property value.
- The property's value after the change occurred.
- A callback to invoke to update the property value.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
-
- The and events are not raised
- if the current and new value for the target property are the same.
-
- Thrown if is .
-
-
-
- Compares the current and new values for a given property. If the value has changed,
- raises the event, updates the property with the new
- value, then raises the event.
- See additional notes about this overload in .
-
- The type of the property that changed.
- The current property value.
- The property's value after the change occurred.
- The instance to use to compare the input values.
- A callback to invoke to update the property value.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
- Thrown if or are .
-
-
-
- Compares the current and new values for a given nested property. If the value has changed,
- raises the event, updates the property and then raises the
- event. The behavior mirrors that of ,
- with the difference being that this method is used to relay properties from a wrapped model in the
- current instance. This type is useful when creating wrapping, bindable objects that operate over
- models that lack support for notification (eg. for CRUD operations).
- Suppose we have this model (eg. for a database row in a table):
-
- public class Person
- {
- public string Name { get; set; }
- }
-
- We can then use a property to wrap instances of this type into our observable model (which supports
- notifications), injecting the notification to the properties of that model, like so:
-
- public class BindablePerson : ObservableObject
- {
- public Model { get; }
-
- public BindablePerson(Person model)
- {
- Model = model;
- }
-
- public string Name
- {
- get => Model.Name;
- set => Set(Model.Name, value, Model, (model, name) => model.Name = name);
- }
- }
-
- This way we can then use the wrapping object in our application, and all those "proxy" properties will
- also raise notifications when changed. Note that this method is not meant to be a replacement for
- , and it should only be used when relaying properties to a model that
- doesn't support notifications, and only if you can't implement notifications to that model directly (eg. by having
- it inherit from ). The syntax relies on passing the target model and a stateless callback
- to allow the C# compiler to cache the function, which results in much better performance and no memory usage.
-
- The type of model whose property (or field) to set.
- The type of property (or field) to set.
- The current property value.
- The property's value after the change occurred.
- The model containing the property being updated.
- The callback to invoke to set the target property value, if a change has occurred.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
-
- The and events are not
- raised if the current and new value for the target property are the same.
-
- Thrown if or are .
-
-
-
- Compares the current and new values for a given nested property. If the value has changed,
- raises the event, updates the property and then raises the
- event. The behavior mirrors that of ,
- with the difference being that this method is used to relay properties from a wrapped model in the
- current instance. See additional notes about this overload in .
-
- The type of model whose property (or field) to set.
- The type of property (or field) to set.
- The current property value.
- The property's value after the change occurred.
- The instance to use to compare the input values.
- The model containing the property being updated.
- The callback to invoke to set the target property value, if a change has occurred.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
- Thrown if , or are .
-
-
-
- Compares the current and new values for a given field (which should be the backing
- field for a property). If the value has changed, raises the
- event, updates the field and then raises the event.
- The behavior mirrors that of , with the difference being that
- this method will also monitor the new value of the property (a generic ) and will also
- raise the again for the target property when it completes.
- This can be used to update bindings observing that or any of its properties.
- This method and its overload specifically rely on the type, which needs
- to be used in the backing field for the target property. The field doesn't need to be
- initialized, as this method will take care of doing that automatically. The
- type also includes an implicit operator, so it can be assigned to any instance directly.
- Here is a sample property declaration using this method:
-
- private TaskNotifier myTask;
-
- public Task MyTask
- {
- get => myTask;
- private set => SetAndNotifyOnCompletion(ref myTask, value);
- }
-
-
- The field notifier to modify.
- The property's value after the change occurred.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
-
- The and events are not raised if the current
- and new value for the target property are the same. The return value being only
- indicates that the new value being assigned to is different than the previous one,
- and it does not mean the new instance passed as argument is in any particular state.
-
-
-
-
- Compares the current and new values for a given field (which should be the backing
- field for a property). If the value has changed, raises the
- event, updates the field and then raises the event.
- This method is just like ,
- with the difference being an extra parameter with a callback being invoked
- either immediately, if the new task has already completed or is , or upon completion.
-
- The field notifier to modify.
- The property's value after the change occurred.
- A callback to invoke to update the property value.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
-
- The and events are not raised
- if the current and new value for the target property are the same.
-
- Thrown if is .
-
-
-
- Compares the current and new values for a given field (which should be the backing
- field for a property). If the value has changed, raises the
- event, updates the field and then raises the event.
- The behavior mirrors that of , with the difference being that
- this method will also monitor the new value of the property (a generic ) and will also
- raise the again for the target property when it completes.
- This can be used to update bindings observing that or any of its properties.
- This method and its overload specifically rely on the type, which needs
- to be used in the backing field for the target property. The field doesn't need to be
- initialized, as this method will take care of doing that automatically. The
- type also includes an implicit operator, so it can be assigned to any instance directly.
- Here is a sample property declaration using this method:
-
- private TaskNotifier<int> myTask;
-
- public Task<int> MyTask
- {
- get => myTask;
- private set => SetAndNotifyOnCompletion(ref myTask, value);
- }
-
-
- The type of result for the to set and monitor.
- The field notifier to modify.
- The property's value after the change occurred.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
-
- The and events are not raised if the current
- and new value for the target property are the same. The return value being only
- indicates that the new value being assigned to is different than the previous one,
- and it does not mean the new instance passed as argument is in any particular state.
-
-
-
-
- Compares the current and new values for a given field (which should be the backing
- field for a property). If the value has changed, raises the
- event, updates the field and then raises the event.
- This method is just like ,
- with the difference being an extra parameter with a callback being invoked
- either immediately, if the new task has already completed or is , or upon completion.
-
- The type of result for the to set and monitor.
- The field notifier to modify.
- The property's value after the change occurred.
- A callback to invoke to update the property value.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
-
- The and events are not raised
- if the current and new value for the target property are the same.
-
- Thrown if is .
-
-
-
- Implements the notification logic for the related methods.
-
- The type of to set and monitor.
- The field notifier.
- The property's value after the change occurred.
- (optional) A callback to invoke to update the property value.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
-
-
-
- An interface for task notifiers of a specified type.
-
- The type of value to store.
-
-
-
- Gets or sets the wrapped value.
-
-
-
-
- A wrapping class that can hold a value.
-
-
-
-
- Initializes a new instance of the class.
-
-
-
-
-
-
-
- Unwraps the value stored in the current instance.
-
- The input instance.
-
-
-
- A wrapping class that can hold a value.
-
- The type of value for the wrapped instance.
-
-
-
- Initializes a new instance of the class.
-
-
-
-
-
-
-
- Unwraps the value stored in the current instance.
-
- The input instance.
-
-
-
- A base class for observable objects that also acts as recipients for messages. This class is an extension of
- which also provides built-in support to use the type.
-
-
-
-
- Initializes a new instance of the class.
-
-
- This constructor will produce an instance that will use the instance
- to perform requested operations. It will also be available locally through the property.
-
-
-
-
- Initializes a new instance of the class.
-
- The instance to use to send messages.
- Thrown if is .
-
-
-
- Gets the instance in use.
-
-
-
-
- Gets or sets a value indicating whether the current view model is currently active.
-
-
-
-
- Invoked whenever the property is set to .
- Use this method to register to messages and do other initialization for this instance.
-
-
- The base implementation registers all messages for this recipients that have been declared
- explicitly through the interface, using the default channel.
- For more details on how this works, see the method.
- If you need more fine tuned control, want to register messages individually or just prefer
- the lambda-style syntax for message registration, override this method and register manually.
-
-
-
-
- Invoked whenever the property is set to .
- Use this method to unregister from messages and do general cleanup for this instance.
-
-
- The base implementation unregisters all messages for this recipient. It does so by
- invoking , which removes all registered
- handlers for a given subscriber, regardless of what token was used to register them.
- That is, all registered handlers across all subscription channels will be removed.
-
-
-
-
- Broadcasts a with the specified
- parameters, without using any particular token (so using the default channel).
-
- The type of the property that changed.
- The value of the property before it changed.
- The value of the property after it changed.
- The name of the property that changed.
-
- You should override this method if you wish to customize the channel being
- used to send the message (eg. if you need to use a specific token for the channel).
-
-
-
-
- Compares the current and new values for a given property. If the value has changed,
- raises the event, updates the property with
- the new value, then raises the event.
-
- The type of the property that changed.
- The field storing the property's value.
- The property's value after the change occurred.
- If , will also be invoked.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
-
- This method is just like , just with the addition
- of the parameter. As such, following the behavior of the base method,
- the and events
- are not raised if the current and new value for the target property are the same.
-
-
-
-
- Compares the current and new values for a given property. If the value has changed,
- raises the event, updates the property with
- the new value, then raises the event.
- See additional notes about this overload in .
-
- The type of the property that changed.
- The field storing the property's value.
- The property's value after the change occurred.
- The instance to use to compare the input values.
- If , will also be invoked.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
- Thrown if is .
-
-
-
- Compares the current and new values for a given property. If the value has changed,
- raises the event, updates the property with
- the new value, then raises the event. Similarly to
- the method, this overload should only be
- used when can't be used directly.
-
- The type of the property that changed.
- The current property value.
- The property's value after the change occurred.
- A callback to invoke to update the property value.
- If , will also be invoked.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
-
- This method is just like , just with the addition
- of the parameter. As such, following the behavior of the base method,
- the and events
- are not raised if the current and new value for the target property are the same.
-
- Thrown if is .
-
-
-
- Compares the current and new values for a given property. If the value has changed,
- raises the event, updates the property with
- the new value, then raises the event.
- See additional notes about this overload in .
-
- The type of the property that changed.
- The current property value.
- The property's value after the change occurred.
- The instance to use to compare the input values.
- A callback to invoke to update the property value.
- If , will also be invoked.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
- Thrown if or are .
-
-
-
- Compares the current and new values for a given nested property. If the value has changed,
- raises the event, updates the property and then raises the
- event. The behavior mirrors that of
- , with the difference being that this
- method is used to relay properties from a wrapped model in the current instance. For more info, see the docs for
- .
-
- The type of model whose property (or field) to set.
- The type of property (or field) to set.
- The current property value.
- The property's value after the change occurred.
- The model
- The callback to invoke to set the target property value, if a change has occurred.
- If , will also be invoked.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
- Thrown if or are .
-
-
-
- Compares the current and new values for a given nested property. If the value has changed,
- raises the event, updates the property and then raises the
- event. The behavior mirrors that of
- ,
- with the difference being that this method is used to relay properties from a wrapped model in the
- current instance. For more info, see the docs for
- .
-
- The type of model whose property (or field) to set.
- The type of property (or field) to set.
- The current property value.
- The property's value after the change occurred.
- The instance to use to compare the input values.
- The model
- The callback to invoke to set the target property value, if a change has occurred.
- If , will also be invoked.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
- Thrown if , or are .
-
-
-
- A base class for objects implementing the interface. This class
- also inherits from , so it can be used for observable items too.
-
-
-
-
- The instance used to track compiled delegates to validate entities.
-
-
-
-
- The instance used to track display names for properties to validate.
-
-
- This is necessary because we want to reuse the same instance for all validations, but
- with the same behavior with respect to formatted names that new instances would have provided. The issue is that the
- property is not refreshed when we set ,
- so we need to replicate the same logic to retrieve the right display name for properties to validate and update that
- property manually right before passing the context to and proceed with the normal functionality.
-
-
-
-
- The cached for .
-
-
-
-
- The instance currently in use.
-
-
-
-
- The instance used to store previous validation results.
-
-
-
-
- Indicates the total number of properties with errors (not total errors).
- This is used to allow to operate in O(1) time, as it can just
- check whether this value is not 0 instead of having to traverse .
-
-
-
-
-
-
-
- Initializes a new instance of the class.
- This constructor will create a new that will
- be used to validate all properties, which will reference the current instance
- and no additional services or validation properties and settings.
-
-
-
-
- Initializes a new instance of the class.
- This constructor will create a new that will
- be used to validate all properties, which will reference the current instance.
-
- A set of key/value pairs to make available to consumers.
-
-
-
- Initializes a new instance of the class.
- This constructor will create a new that will
- be used to validate all properties, which will reference the current instance.
-
- An instance to make available during validation.
- A set of key/value pairs to make available to consumers.
-
-
-
- Initializes a new instance of the class.
- This constructor will store the input instance,
- and it will use it to validate all properties for the current viewmodel.
-
-
- The instance to use to validate properties.
-
- This instance will be passed to all
- calls executed by the current viewmodel, and its property will be updated every time
- before the call is made to set the name of the property being validated. The property name will not be reset after that, so the
- value of will always indicate the name of the last property that was validated, if any.
-
-
- Thrown if is .
-
-
-
-
-
-
- Compares the current and new values for a given property. If the value has changed,
- raises the event, updates the property with
- the new value, then raises the event.
-
- The type of the property that changed.
- The field storing the property's value.
- The property's value after the change occurred.
- If , will also be validated.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
-
- This method is just like , just with the addition
- of the parameter. If that is set to , the new value will be
- validated and will be raised if needed. Following the behavior of the base method,
- the and events
- are not raised if the current and new value for the target property are the same.
-
- Thrown if is .
-
-
-
- Compares the current and new values for a given property. If the value has changed,
- raises the event, updates the property with
- the new value, then raises the event.
- See additional notes about this overload in .
-
- The type of the property that changed.
- The field storing the property's value.
- The property's value after the change occurred.
- The instance to use to compare the input values.
- If , will also be validated.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
- Thrown if or are .
-
-
-
- Compares the current and new values for a given property. If the value has changed,
- raises the event, updates the property with
- the new value, then raises the event. Similarly to
- the method, this overload should only be
- used when can't be used directly.
-
- The type of the property that changed.
- The current property value.
- The property's value after the change occurred.
- A callback to invoke to update the property value.
- If , will also be validated.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
-
- This method is just like , just with the addition
- of the parameter. As such, following the behavior of the base method,
- the and events
- are not raised if the current and new value for the target property are the same.
-
- Thrown if or are .
-
-
-
- Compares the current and new values for a given property. If the value has changed,
- raises the event, updates the property with
- the new value, then raises the event.
- See additional notes about this overload in .
-
- The type of the property that changed.
- The current property value.
- The property's value after the change occurred.
- The instance to use to compare the input values.
- A callback to invoke to update the property value.
- If , will also be validated.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
- Thrown if , or are .
-
-
-
- Compares the current and new values for a given nested property. If the value has changed,
- raises the event, updates the property and then raises the
- event. The behavior mirrors that of
- , with the difference being that this
- method is used to relay properties from a wrapped model in the current instance. For more info, see the docs for
- .
-
- The type of model whose property (or field) to set.
- The type of property (or field) to set.
- The current property value.
- The property's value after the change occurred.
- The model
- The callback to invoke to set the target property value, if a change has occurred.
- If , will also be validated.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
- Thrown if , or are .
-
-
-
- Compares the current and new values for a given nested property. If the value has changed,
- raises the event, updates the property and then raises the
- event. The behavior mirrors that of
- ,
- with the difference being that this method is used to relay properties from a wrapped model in the
- current instance. For more info, see the docs for
- .
-
- The type of model whose property (or field) to set.
- The type of property (or field) to set.
- The current property value.
- The property's value after the change occurred.
- The instance to use to compare the input values.
- The model
- The callback to invoke to set the target property value, if a change has occurred.
- If , will also be validated.
- (optional) The name of the property that changed.
- if the property was changed, otherwise.
- Thrown if , , or are .
-
-
-
- Tries to validate a new value for a specified property. If the validation is successful,
- is called, otherwise no state change is performed.
-
- The type of the property that changed.
- The field storing the property's value.
- The property's value after the change occurred.
- The resulting validation errors, if any.
- (optional) The name of the property that changed.
- Whether the validation was successful and the property value changed as well.
- Thrown if is .
-
-
-
- Tries to validate a new value for a specified property. If the validation is successful,
- is called, otherwise no state change is performed.
-
- The type of the property that changed.
- The field storing the property's value.
- The property's value after the change occurred.
- The instance to use to compare the input values.
- The resulting validation errors, if any.
- (optional) The name of the property that changed.
- Whether the validation was successful and the property value changed as well.
- Thrown if or are .
-
-
-
- Tries to validate a new value for a specified property. If the validation is successful,
- is called, otherwise no state change is performed.
-
- The type of the property that changed.
- The current property value.
- The property's value after the change occurred.
- A callback to invoke to update the property value.
- The resulting validation errors, if any.
- (optional) The name of the property that changed.
- Whether the validation was successful and the property value changed as well.
- Thrown if or are .
-
-
-
- Tries to validate a new value for a specified property. If the validation is successful,
- is called, otherwise no state change is performed.
-
- The type of the property that changed.
- The current property value.
- The property's value after the change occurred.
- The instance to use to compare the input values.
- A callback to invoke to update the property value.
- The resulting validation errors, if any.
- (optional) The name of the property that changed.
- Whether the validation was successful and the property value changed as well.
- Thrown if , or are .
-
-
-
- Tries to validate a new value for a specified property. If the validation is successful,
- is called, otherwise no state change is performed.
-
- The type of model whose property (or field) to set.
- The type of property (or field) to set.
- The current property value.
- The property's value after the change occurred.
- The model
- The callback to invoke to set the target property value, if a change has occurred.
- The resulting validation errors, if any.
- (optional) The name of the property that changed.
- Whether the validation was successful and the property value changed as well.
- Thrown if , or are .
-
-
-
- Tries to validate a new value for a specified property. If the validation is successful,
- is called, otherwise no state change is performed.
-
- The type of model whose property (or field) to set.
- The type of property (or field) to set.
- The current property value.
- The property's value after the change occurred.
- The instance to use to compare the input values.
- The model
- The callback to invoke to set the target property value, if a change has occurred.
- The resulting validation errors, if any.
- (optional) The name of the property that changed.
- Whether the validation was successful and the property value changed as well.
- Thrown if , , or are .
-
-
-
- Clears the validation errors for a specified property or for the entire entity.
-
-
- The name of the property to clear validation errors for.
- If a or empty name is used, all entity-level errors will be cleared.
-
-
-
-
-
-
-
-
-
-
- Validates all the properties in the current instance and updates all the tracked errors.
- If any changes are detected, the event will be raised.
-
-
- Only public instance properties (excluding custom indexers) that have at least one
- applied to them will be validated. All other
- members in the current instance will be ignored. None of the processed properties
- will be modified - they will only be used to retrieve their values and validate them.
-
-
-
-
- Validates a property with a specified name and a given input value.
- If any changes are detected, the event will be raised.
-
- The value to test for the specified property.
- The name of the property to validate.
- Thrown when is .
-
-
-
- Tries to validate a property with a specified name and a given input value, and returns
- the computed errors, if any. If the property is valid, it is assumed that its value is
- about to be set in the current object. Otherwise, no observable local state is modified.
-
- The value to test for the specified property.
- The name of the property to validate.
- The resulting validation errors, if any.
-
-
-
- Clears all the current errors for the entire entity.
-
-
-
-
- Clears all the current errors for a target property.
-
- The name of the property to clear errors for.
-
-
-
- Gets the display name for a given property. It could be a custom name or just the property name.
-
- The target property name being validated.
- The display name for the property.
-
-
-
- An internal helper to support the source generator APIs related to .
- This type is not intended to be used directly by user code.
-
-
-
-
- Invokes externally on a target instance.
-
- The target instance.
- The value to test for the specified property.
- The name of the property to validate.
-
-
-
- An internal helper used to support and generated code from its template.
- This type is not intended to be used directly by user code.
-
-
-
-
- Gets an awaitable object that skips end validation.
-
- The input to get the awaitable for.
- A object wrapping .
-
-
-
- A custom task awaitable object that skips end validation.
-
-
-
-
- The wrapped instance to create an awaiter for.
-
-
-
-
- Creates a new instance with the specified parameters.
-
- The wrapped instance to create an awaiter for.
-
-
-
- Gets an instance for the current underlying task.
-
- An instance for the current underlying task.
-
-
-
- An awaiter object for .
-
-
-
-
- The underlying instance.
-
-
-
-
- Creates a new instance with the specified parameters.
-
- The wrapped instance to create an awaiter for.
-
-
-
- Gets whether the operation has completed or not.
-
- This property is intended for compiler user rather than use directly in code.
-
-
-
- Ends the await operation.
-
- This method is intended for compiler user rather than use directly in code.
-
-
-
-
-
-
-
-
-
- A type that facilitates the use of the type.
- The provides the ability to configure services in a singleton, thread-safe
- service provider instance, which can then be used to resolve service instances.
- The first step to use this feature is to declare some services, for instance:
-
- public interface ILogger
- {
- void Log(string text);
- }
-
-
- public class ConsoleLogger : ILogger
- {
- void Log(string text) => Console.WriteLine(text);
- }
-
- Then the services configuration should then be done at startup, by calling the
- method and passing an instance with the services to use. That instance can
- be from any library offering dependency injection functionality, such as Microsoft.Extensions.DependencyInjection.
- For instance, using that library, can be used as follows in this example:
-
- Ioc.Default.ConfigureServices(
- new ServiceCollection()
- .AddSingleton<ILogger, Logger>()
- .BuildServiceProvider());
-
- Finally, you can use the instance (which implements )
- to retrieve the service instances from anywhere in your application, by doing as follows:
-
- Ioc.Default.GetService<ILogger>().Log("Hello world!");
-
-
-
-
-
- Gets the default instance.
-
-
-
-
- The instance to use, if initialized.
-
-
-
-
-
-
-
- Tries to resolve an instance of a specified service type.
-
- The type of service to resolve.
- An instance of the specified service, or .
- Thrown if the current instance has not been initialized.
-
-
-
- Resolves an instance of a specified service type.
-
- The type of service to resolve.
- An instance of the specified service, or .
-
- Thrown if the current instance has not been initialized, or if the
- requested service type was not registered in the service provider currently in use.
-
-
-
-
- Initializes the shared instance.
-
- The input instance to use.
- Thrown if is .
-
-
-
- Throws an when the property is used before initialization.
-
-
-
-
- Throws an when the property is missing a type registration.
-
-
-
-
- Throws an when a configuration is attempted more than once.
-
-
-
-
- A command that mirrors the functionality of , with the addition of
- accepting a returning a as the execute
- action, and providing an property that notifies changes when
- is invoked and when the returned completes.
-
-
-
-
- The cached for .
-
-
-
-
- The cached for .
-
-
-
-
- The cached for .
-
-
-
-
- The cached for .
-
-
-
-
- The to invoke when is used.
-
-
-
-
- The cancelable to invoke when is used.
-
- Only one between this and is not .
-
-
-
- The optional action to invoke when is used.
-
-
-
-
- The options being set for the current command.
-
-
-
-
- The instance to use to cancel .
-
- This is only used when is not .
-
-
-
-
-
-
-
-
-
- Initializes a new instance of the class.
-
- The execution logic.
- Thrown if is .
-
-
-
- Initializes a new instance of the class.
-
- The execution logic.
- The options to use to configure the async command.
- Thrown if is .
-
-
-
- Initializes a new instance of the class.
-
- The cancelable execution logic.
- Thrown if is .
-
-
-
- Initializes a new instance of the class.
-
- The cancelable execution logic.
- The options to use to configure the async command.
- Thrown if is .
-
-
-
- Initializes a new instance of the class.
-
- The execution logic.
- The execution status logic.
- Thrown if or are .
-
-
-
- Initializes a new instance of the class.
-
- The execution logic.
- The execution status logic.
- The options to use to configure the async command.
- Thrown if or are .
-
-
-
- Initializes a new instance of the class.
-
- The cancelable execution logic.
- The execution status logic.
- Thrown if or are .
-
-
-
- Initializes a new instance of the class.
-
- The cancelable execution logic.
- The execution status logic.
- The options to use to configure the async command.
- Thrown if or are .
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Awaits an input and throws an exception on the calling context, if the task fails.
-
- The input instance to await.
-
-
-
- Options to customize the behavior of and instances.
-
-
-
-
- No option is specified. The and types will use their default behavior:
-
- Concurrent execution is disallowed: a command is disabled if there is a pending asynchronous execution running.
-
-
- Exceptions are thrown on the calling context: calling will await the
- returned for the operation, and propagate the exception on the calling context.
-
- This behavior is consistent with synchronous commands, where exceptions in behave the same.
-
-
-
-
-
-
- Concurrent executions are allowed. This option makes it so that the same command can be invoked concurrently multiple times.
-
- Note that additional considerations should be taken into account in this case:
-
- If the command supports cancellation, previous invocations will automatically be canceled if a new one is started.
- The property will always represent the operation that was started last.
-
-
-
-
-
-
- Exceptions are not thrown on the calling context, and are propagated to instead.
-
- This affects how calls to behave. When this option is used, if an operation fails, that exception will not
- be rethrown on the calling context (as it is not awaited there). Instead, it will flow to .
-
-
- This option enables more advanced scenarios, where the property can be used to inspect the state of an operation
- that was queued. That is, even if the operation failed or was canceled, the details of that can be retrieved at a later time by accessing this property.
-
-
-
-
-
- A generic command that provides a more specific version of .
-
- The type of parameter being passed as input to the callbacks.
-
-
-
- The to invoke when is used.
-
-
-
-
- The cancelable to invoke when is used.
-
-
-
-
- The optional action to invoke when is used.
-
-
-
-
- The options being set for the current command.
-
-
-
-
- The instance to use to cancel .
-
-
-
-
-
-
-
-
-
-
- Initializes a new instance of the class.
-
- The execution logic.
- See notes in .
- Thrown if is .
-
-
-
- Initializes a new instance of the class.
-
- The execution logic.
- The options to use to configure the async command.
- See notes in .
- Thrown if is .
-
-
-
- Initializes a new instance of the class.
-
- The cancelable execution logic.
- See notes in .
- Thrown if is .
-
-
-
- Initializes a new instance of the class.
-
- The cancelable execution logic.
- The options to use to configure the async command.
- See notes in .
- Thrown if is .
-
-
-
- Initializes a new instance of the class.
-
- The execution logic.
- The execution status logic.
- See notes in .
- Thrown if or are .
-
-
-
- Initializes a new instance of the class.
-
- The execution logic.
- The execution status logic.
- The options to use to configure the async command.
- See notes in .
- Thrown if or are .
-
-
-
- Initializes a new instance of the class.
-
- The cancelable execution logic.
- The execution status logic.
- See notes in .
- Thrown if or are .
-
-
-
- Initializes a new instance of the class.
-
- The cancelable execution logic.
- The execution status logic.
- The options to use to configure the async command.
- See notes in .
- Thrown if or are .
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- An attribute that can be used to automatically generate properties from declared methods. When this attribute
- is used to decorate a method, a generator will create a command property with the corresponding interface
- depending on the signature of the method. If an invalid method signature is used, the generator will report an error.
-
- In order to use this attribute, the containing type doesn't need to implement any interfaces. The generated properties will be lazily
- assigned but their value will never change, so there is no need to support property change notifications or other additional functionality.
-
-
- This attribute can be used as follows:
-
- partial class MyViewModel
- {
- [RelayCommand]
- private void GreetUser(User? user)
- {
- Console.WriteLine($"Hello {user.Name}!");
- }
- }
-
- And with this, code analogous to this will be generated:
-
- partial class MyViewModel
- {
- private RelayCommand? greetUserCommand;
-
- public IRelayCommand GreetUserCommand => greetUserCommand ??= new RelayCommand(GreetUser);
- }
-
-
-
- The following signatures are supported for annotated methods:
-
- void Method();
-
- Will generate an property (using a instance).
-
- void Method(T?);
-
- Will generate an property (using a instance).
-
- Task Method();
- Task Method(CancellationToken);
- Task<T> Method();
- Task<T> Method(CancellationToken);
-
- Will both generate an property (using an instance).
-
- Task Method(T?);
- Task Method(T?, CancellationToken);
- Task<T> Method(T?);
- Task<T> Method(T?, CancellationToken);
-
- Will both generate an property (using an instance).
-
-
-
-
-
- Gets or sets the name of the property or method that will be invoked to check whether the
- generated command can be executed at any given time. The referenced member needs to return
- a value, and has to have a signature compatible with the target command.
-
-
-
-
- Gets or sets a value indicating whether or not to allow concurrent executions for an asynchronous command.
-
- When set for an attribute used on a method that would result in an or an
- property to be generated, this will modify the behavior of these commands
- when an execution is invoked while a previous one is still running. It is the same as creating an instance of
- these command types with a constructor such as
- and using the value.
-
-
- Using this property is not valid if the target command doesn't map to an asynchronous command.
-
-
-
- Gets or sets a value indicating whether or not to exceptions should be propagated to .
-
- When set for an attribute used on a method that would result in an or an
- property to be generated, this will modify the behavior of these commands
- in case an exception is thrown by the underlying operation. It is the same as creating an instance of
- these command types with a constructor such as
- and using the value.
-
-
- Using this property is not valid if the target command doesn't map to an asynchronous command.
-
-
-
- Gets or sets a value indicating whether a cancel command should also be generated for an asynchronous command.
-
- When set to , this additional code will be generated:
-
- partial class MyViewModel
- {
- private ICommand? loginUserCancelCommand;
-
- public ICommand LoginUserCancelCommand => loginUserCancelCommand ??= LoginUserCommand.CreateCancelCommand();
- }
-
- Where LoginUserCommand is an defined in the class (or generated by this attribute as well).
-
-
- Using this property is not valid if the target command doesn't map to a cancellable asynchronous command.
-
-
-
- Extensions for the type.
-
-
-
-
- Creates an instance that can be used to cancel execution on the input command.
- The returned command will also notify when it can be executed based on the state of the wrapped command.
-
- The input instance to create a cancellation command for.
- An instance that can be used to monitor and signal cancellation for .
- The returned instance is not guaranteed to be unique across multiple invocations with the same arguments.
- Thrown if is .
-
-
-
- An interface expanding to support asynchronous operations.
-
-
-
-
- Gets the last scheduled , if available.
- This property notifies a change when the completes.
-
-
-
-
- Gets a value indicating whether a running operation for this command can currently be canceled.
-
-
- The exact sequence of events that types implementing this interface should raise is as follows:
-
-
- The command is initially not running: ,
- and are .
-
-
- The command starts running: and switch to
- . is set to .
-
-
- If the operation is canceled: switches to
- and switches to .
-
-
- The operation completes: and switch
- to . The state of is undefined.
-
-
- This only applies if the underlying logic for the command actually supports cancelation. If that is
- not the case, then and will always remain
- regardless of the current state of the command.
-
-
-
-
- Gets a value indicating whether a cancelation request has been issued for the current operation.
-
-
-
-
- Gets a value indicating whether the command currently has a pending operation being executed.
-
-
-
-
- Provides a more specific version of ,
- also returning the representing the async operation being executed.
-
- The input parameter.
- The representing the async operation being executed.
- Thrown if is incompatible with the underlying command implementation.
-
-
-
- Communicates a request for cancelation.
-
-
- If the underlying command is not running, or if it does not support cancelation, this method will perform no action.
- Note that even with a successful cancelation, the completion of the current operation might not be immediate.
-
-
-
-
- A generic interface representing a more specific version of .
-
- The type used as argument for the interface methods.
- This interface is needed to solve the diamond problem with base classes.
-
-
-
- Provides a strongly-typed variant of .
-
- The input parameter.
- The representing the async operation being executed.
-
-
-
- An interface expanding with the ability to raise
- the event externally.
-
-
-
-
- Notifies that the property has changed.
-
-
-
-
- A generic interface representing a more specific version of .
-
- The type used as argument for the interface methods.
-
-
-
- Provides a strongly-typed variant of .
-
- The input parameter.
- Whether or not the current command can be executed.
- Use this overload to avoid boxing, if is a value type.
-
-
-
- Provides a strongly-typed variant of .
-
- The input parameter.
- Use this overload to avoid boxing, if is a value type.
-
-
-
- A implementation wrapping to support cancellation.
-
-
-
-
- The wrapped instance.
-
-
-
-
- Creates a new instance.
-
- The instance to wrap.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- A reusable instance that is always disabled.
-
-
-
-
-
-
-
- Gets a shared, reusable instance.
-
-
- This instance can safely be used across multiple objects without having
- to worry about this static keeping others alive, as the event uses a
- custom accessor that just discards items (as the event is known to never
- be raised). As such, this instance will never act as root for other objects.
-
-
-
-
-
-
-
-
-
-
- An interface for commands that know whether they support cancellation or not.
-
-
-
-
- Gets whether or not the current command supports cancellation.
-
-
-
-
- A command whose sole purpose is to relay its functionality to other
- objects by invoking delegates. The default return value for the
- method is . This type does not allow you to accept command parameters
- in the and callback methods.
-
-
-
-
- The to invoke when is used.
-
-
-
-
- The optional action to invoke when is used.
-
-
-
-
-
-
-
- Initializes a new instance of the class that can always execute.
-
- The execution logic.
- Thrown if is .
-
-
-
- Initializes a new instance of the class.
-
- The execution logic.
- The execution status logic.
- Thrown if or are .
-
-
-
-
-
-
-
-
-
-
-
-
- A generic command whose sole purpose is to relay its functionality to other
- objects by invoking delegates. The default return value for the CanExecute
- method is . This class allows you to accept command parameters
- in the and callback methods.
-
- The type of parameter being passed as input to the callbacks.
-
-
-
- The to invoke when is used.
-
-
-
-
- The optional action to invoke when is used.
-
-
-
-
-
-
-
- Initializes a new instance of the class that can always execute.
-
- The execution logic.
-
- Due to the fact that the interface exposes methods that accept a
- nullable parameter, it is recommended that if is a reference type,
- you should always declare it as nullable, and to always perform checks within .
-
- Thrown if is .
-
-
-
- Initializes a new instance of the class.
-
- The execution logic.
- The execution status logic.
- See notes in .
- Thrown if or are .
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Tries to get a command argument of compatible type from an input .
-
- The input parameter.
- The resulting value, if any.
- Whether or not a compatible command argument could be retrieved.
-
-
-
- Throws an if an invalid command argument is used.
-
- The input parameter.
- Thrown with an error message to give info on the invalid parameter.
-
-
-
- An interface for a type providing the ability to exchange messages between different objects.
- This can be useful to decouple different modules of an application without having to keep strong
- references to types being referenced. It is also possible to send messages to specific channels, uniquely
- identified by a token, and to have different messengers in different sections of an applications.
- In order to use the functionalities, first define a message type, like so:
-
- public sealed class LoginCompletedMessage { }
-
- Then, register your a recipient for this message:
-
- Messenger.Default.Register<MyRecipientType, LoginCompletedMessage>(this, (r, m) =>
- {
- // Handle the message here...
- });
-
- The message handler here is a lambda expression taking two parameters: the recipient and the message.
- This is done to avoid the allocations for the closures that would've been generated if the expression
- had captured the current instance. The recipient type parameter is used so that the recipient can be
- directly accessed within the handler without the need to manually perform type casts. This allows the
- code to be less verbose and more reliable, as all the checks are done just at build time. If the handler
- is defined within the same type as the recipient, it is also possible to directly access private members.
- This allows the message handler to be a static method, which enables the C# compiler to perform a number
- of additional memory optimizations (such as caching the delegate, avoiding unnecessary memory allocations).
- Finally, send a message when needed, like so:
-
- Messenger.Default.Send<LoginCompletedMessage>();
-
- Additionally, the method group syntax can also be used to specify the message handler
- to invoke when receiving a message, if a method with the right signature is available
- in the current scope. This is helpful to keep the registration and handling logic separate.
- Following up from the previous example, consider a class having this method:
-
- private static void Receive(MyRecipientType recipient, LoginCompletedMessage message)
- {
- // Handle the message there
- }
-
- The registration can then be performed in a single line like so:
-
- Messenger.Default.Register(this, Receive);
-
- The C# compiler will automatically convert that expression to a instance
- compatible with .
- This will also work if multiple overloads of that method are available, each handling a different
- message type: the C# compiler will automatically pick the right one for the current message type.
- It is also possible to register message handlers explicitly using the interface.
- To do so, the recipient just needs to implement the interface and then call the
- extension, which will automatically register
- all the handlers that are declared by the recipient type. Registration for individual handlers is supported as well.
-
-
-
-
- Checks whether or not a given recipient has already been registered for a message.
-
- The type of message to check for the given recipient.
- The type of token to check the channel for.
- The target recipient to check the registration for.
- The token used to identify the target channel to check.
- Whether or not has already been registered for the specified message.
- Thrown if or are .
-
-
-
- Registers a recipient for a given type of message.
-
- The type of recipient for the message.
- The type of message to receive.
- The type of token to use to pick the messages to receive.
- The recipient that will receive the messages.
- A token used to determine the receiving channel to use.
- The to invoke when a message is received.
- Thrown if , or are .
- Thrown when trying to register the same message twice.
-
-
-
- Unregisters a recipient from all registered messages.
-
- The recipient to unregister.
-
- This method will unregister the target recipient across all channels.
- Use this method as an easy way to lose all references to a target recipient.
- If the recipient has no registered handler, this method does nothing.
-
- Thrown if is .
-
-
-
- Unregisters a recipient from all messages on a specific channel.
-
- The type of token to identify what channel to unregister from.
- The recipient to unregister.
- The token to use to identify which handlers to unregister.
- If the recipient has no registered handler, this method does nothing.
- Thrown if or are .
-
-
-
- Unregisters a recipient from messages of a given type.
-
- The type of message to stop receiving.
- The type of token to identify what channel to unregister from.
- The recipient to unregister.
- The token to use to identify which handlers to unregister.
- If the recipient has no registered handler, this method does nothing.
- Thrown if or are .
-
-
-
- Sends a message of the specified type to all registered recipients.
-
- The type of message to send.
- The type of token to identify what channel to use to send the message.
- The message to send.
- The token indicating what channel to use.
- The message that was sent (ie. ).
- Thrown if or are .
-
-
-
- Performs a cleanup on the current messenger.
- Invoking this method does not unregister any of the currently registered
- recipient, and it can be used to perform cleanup operations such as
- trimming the internal data structures of a messenger implementation.
-
-
-
-
- Resets the instance and unregisters all the existing recipients.
-
-
-
-
- Extensions for the type.
-
-
-
-
-
- A class that acts as a container to load the instance linked to
- the method.
- This class is needed to avoid forcing the initialization code in the static constructor to run as soon as
- the type is referenced, even if that is done just to use methods
- that do not actually require this instance to be available.
- We're effectively using this type to leverage the lazy loading of static constructors done by the runtime.
-
-
-
-
- The instance associated with .
-
-
-
-
- A non-generic version of .
-
-
-
-
- The instance used to track the preloaded registration action for each recipient.
-
-
-
-
- A class that acts as a static container to associate a instance to each
- type in use. This is done because we can only use a single type as key, but we need to track
- associations of each recipient type also across different communication channels, each identified by a token.
- Since the token is actually a compile-time parameter, we can use a wrapping class to let the runtime handle a different
- instance for each generic type instantiation. This lets us only worry about the recipient type being inspected.
-
- The token indicating what channel to use.
-
-
-
- The instance used to track the preloaded registration action for each recipient.
-
-
-
-
- Checks whether or not a given recipient has already been registered for a message.
-
- The type of message to check for the given recipient.
- The instance to use to check the registration.
- The target recipient to check the registration for.
- Whether or not has already been registered for the specified message.
- This method will use the default channel to check for the requested registration.
- Thrown if or are .
-
-
-
- Registers all declared message handlers for a given recipient, using the default channel.
-
- The instance to use to register the recipient.
- The recipient that will receive the messages.
- See notes for for more info.
- Thrown if or are .
-
-
-
- Registers all declared message handlers for a given recipient.
-
- The type of token to identify what channel to use to receive messages.
- The instance to use to register the recipient.
- The recipient that will receive the messages.
- The token indicating what channel to use.
-
- This method will register all messages corresponding to the interfaces
- being implemented by . If none are present, this method will do nothing.
- Note that unlike all other extensions, this method will use reflection to find the handlers to register.
- Once the registration is complete though, the performance will be exactly the same as with handlers
- registered directly through any of the other generic extensions for the interface.
-
- Thrown if , or are .
-
-
-
- Registers a recipient for a given type of message.
-
- The type of message to receive.
- The instance to use to register the recipient.
- The recipient that will receive the messages.
- Thrown when trying to register the same message twice.
- This method will use the default channel to perform the requested registration.
- Thrown if or are .
-
-
-
- Registers a recipient for a given type of message.
-
- The type of message to receive.
- The type of token to identify what channel to use to receive messages.
- The instance to use to register the recipient.
- The recipient that will receive the messages.
- The token indicating what channel to use.
- Thrown when trying to register the same message twice.
- This method will use the default channel to perform the requested registration.
- Thrown if , or are .
-
-
-
- Registers a recipient for a given type of message.
-
- The type of message to receive.
- The instance to use to register the recipient.
- The recipient that will receive the messages.
- The to invoke when a message is received.
- Thrown when trying to register the same message twice.
- This method will use the default channel to perform the requested registration.
- Thrown if , or are .
-
-
-
- Registers a recipient for a given type of message.
-
- The type of recipient for the message.
- The type of message to receive.
- The instance to use to register the recipient.
- The recipient that will receive the messages.
- The to invoke when a message is received.
- Thrown when trying to register the same message twice.
- This method will use the default channel to perform the requested registration.
- Thrown if , or are .
-
-
-
- Registers a recipient for a given type of message.
-
- The type of message to receive.
- The type of token to use to pick the messages to receive.
- The instance to use to register the recipient.
- The recipient that will receive the messages.
- A token used to determine the receiving channel to use.
- The to invoke when a message is received.
- Thrown when trying to register the same message twice.
- Thrown if , or are .
-
-
-
- Unregisters a recipient from messages of a given type.
-
- The type of message to stop receiving.
- The instance to use to unregister the recipient.
- The recipient to unregister.
-
- This method will unregister the target recipient only from the default channel.
- If the recipient has no registered handler, this method does nothing.
-
- Thrown if or are .
-
-
-
- Sends a message of the specified type to all registered recipients.
-
- The type of message to send.
- The instance to use to send the message.
- The message that has been sent.
-
- This method is a shorthand for when the
- message type exposes a parameterless constructor: it will automatically create
- a new instance and send that to its recipients.
-
- Thrown if is .
-
-
-
- Sends a message of the specified type to all registered recipients.
-
- The type of message to send.
- The instance to use to send the message.
- The message to send.
- The message that was sent (ie. ).
- Thrown if or are .
-
-
-
- Sends a message of the specified type to all registered recipients.
-
- The type of message to send.
- The type of token to identify what channel to use to send the message.
- The instance to use to send the message.
- The token indicating what channel to use.
- The message that has been sen.
-
- This method will automatically create a new instance
- just like , and then send it to the right recipients.
-
- Thrown if or are .
-
-
-
- Creates an instance that can be used to be notified whenever a message of a given type is broadcast by a messenger.
-
- The type of message to use to receive notification for through the resulting instance.
- The instance to use to register the recipient.
- An instance to receive notifications for messages being broadcast.
- Thrown if is .
-
-
-
- Creates an instance that can be used to be notified whenever a message of a given type is broadcast by a messenger.
-
- The type of message to use to receive notification for through the resulting instance.
- The type of token to identify what channel to use to receive messages.
- The instance to use to register the recipient.
- A token used to determine the receiving channel to use.
- An instance to receive notifications for messages being broadcast.
- Thrown if or are .
-
-
-
- An implementations for a given message type.
-
- The type of messages to listen to.
-
-
-
- The instance to use to register the recipient.
-
-
-
-
- Creates a new instance with the given parameters.
-
- The instance to use to register the recipient.
-
-
-
-
-
-
- An implementation for .
-
-
-
-
- The instance to use to register the recipient.
-
-
-
-
- The target instance currently in use.
-
-
-
-
- Creates a new instance with the specified parameters.
-
- The instance to use to register the recipient.
- The instance to use to create the recipient for.
-
-
-
-
-
-
-
-
-
- An implementations for a given pair of message and token types.
-
- The type of messages to listen to.
- The type of token to identify what channel to use to receive messages.
-
-
-
- The instance to use to register the recipient.
-
-
-
-
- The token used to determine the receiving channel to use.
-
-
-
-
- Creates a new instance with the given parameters.
-
- The instance to use to register the recipient.
- A token used to determine the receiving channel to use.
-
-
-
-
-
-
- An implementation for .
-
-
-
-
- The instance to use to register the recipient.
-
-
-
-
- The target instance currently in use.
-
-
-
-
- The token used to determine the receiving channel to use.
-
-
-
-
- Creates a new instance with the specified parameters.
-
- The instance to use to register the recipient.
- The instance to use to create the recipient for.
- A token used to determine the receiving channel to use.
-
-
-
-
-
-
-
-
-
- A simple buffer writer implementation using pooled arrays.
-
- The type of items to store in the list.
-
- This type is a to avoid the object allocation and to
- enable the pattern-based support. We aren't worried with consumers not
- using this type correctly since it's private and only accessible within the parent type.
-
-
-
-
- The default buffer size to use to expand empty arrays.
-
-
-
-
- The underlying array.
-
-
-
-
- The span mapping to .
-
- All writes are done through this to avoid covariance checks.
-
-
-
- The starting offset within .
-
-
-
-
- Creates a new instance of the struct.
-
- A new instance.
-
-
-
- Gets a with the current items.
-
-
-
-
- Adds a new item to the current collection.
-
- The item to add.
-
-
-
- Resets the underlying array and the stored items.
-
-
-
-
- Resizes when there is no space left for new items, then adds one
-
- The item to add.
-
-
-
-
-
-
- A dispatcher type that invokes a given callback.
-
-
- This type is used to avoid type aliasing with when the generic
- arguments are not known. Additionally, this is an abstract class and not an interface so that when
- is called, virtual dispatch will be used instead of interface
- stub dispatch, which is much slower and with more indirections.
-
-
-
-
- Invokes the current callback on a target recipient, with a specified message.
-
- The target recipient for the message.
- The message being broadcast.
-
-
-
- A generic version of .
-
- The type of recipient for the message.
- The type of message to receive.
-
-
-
- The underlying callback to invoke.
-
-
-
-
- Initializes a new instance of the class.
-
- The input instance.
-
-
-
-
-
-
- A simple type representing an immutable pair of types.
-
-
- This type replaces a simple as it's faster in its
- and methods, and because
- unlike a value tuple it exposes its fields as immutable. Additionally, the
- and fields provide additional clarity reading
- the code compared to and .
-
-
-
-
- The type of registered message.
-
-
-
-
- The type of registration token.
-
-
-
-
- Initializes a new instance of the struct.
-
- The type of registered message.
- The type of registration token.
-
-
-
-
-
-
-
-
-
-
-
-
- An empty type representing a generic token with no specific value.
-
-
-
-
-
-
-
-
-
-
-
-
-
- An interface for a recipient that declares a registration for a specific message type.
-
- The type of message to receive.
-
-
-
- Receives a given message instance.
-
- The message being received.
-
-
-
- A used to represent actions to invoke when a message is received.
- The recipient is given as an input argument to allow message registrations to avoid creating
- closures: if an instance method on a recipient needs to be invoked it is possible to just
- cast the recipient to the right type and then access the local method from that instance.
-
- The type of recipient for the message.
- The type of message to receive.
- The recipient that is receiving the message.
- The message being received.
-
-
-
- A for request messages that can receive multiple replies, which can either be used directly or through derived classes.
-
- The type of request to make.
-
-
-
- The collection of received replies. We accept both instance, representing already running
- operations that can be executed in parallel, or instances, which can be used so that multiple
- asynchronous operations are only started sequentially from and do not overlap in time.
-
-
-
-
- The instance used to link the token passed to
- and the one passed to all subscribers to the message.
-
-
-
-
- Gets the instance that will be linked to the
- one used to asynchronously enumerate the received responses. This can be used to cancel asynchronous
- replies that are still being processed, if no new items are needed from this request message.
- Consider the following example, where we define a message to retrieve the currently opened documents:
-
- public class OpenDocumentsRequestMessage : AsyncCollectionRequestMessage<XmlDocument> { }
-
- We can then request and enumerate the results like so:
-
- await foreach (var document in Messenger.Default.Send<OpenDocumentsRequestMessage>())
- {
- // Process each document here...
- }
-
- If we also want to control the cancellation of the token passed to each subscriber to the message,
- we can do so by passing a token we control to the returned message before starting the enumeration
- ().
- The previous snippet with this additional change looks as follows:
-
- await foreach (var document in Messenger.Default.Send<OpenDocumentsRequestMessage>().WithCancellation(cts.Token))
- {
- // Process each document here...
- }
-
- When no more new items are needed (or for any other reason depending on the situation), the token
- passed to the enumerator can be canceled (by calling ),
- and that will also notify the remaining tasks in the request message. The token exposed by the message
- itself will automatically be linked and canceled with the one passed to the enumerator.
-
-
-
-
- Replies to the current request message.
-
- The response to use to reply to the request message.
-
-
-
- Replies to the current request message.
-
- The response to use to reply to the request message.
- Thrown if is .
-
-
-
- Replies to the current request message.
-
- The response to use to reply to the request message.
- Thrown if is .
-
-
-
- Gets the collection of received response items.
-
- A value to stop the operation.
- The collection of received response items.
-
-
-
-
-
-
- A for async request messages, which can either be used directly or through derived classes.
-
- The type of request to make.
-
-
-
- Gets the message response.
-
- Thrown when is .
-
-
-
- Gets a value indicating whether a response has already been assigned to this instance.
-
-
-
-
- Replies to the current request message.
-
- The response to use to reply to the request message.
- Thrown if has already been set.
-
-
-
- Replies to the current request message.
-
- The response to use to reply to the request message.
- Thrown if is .
- Thrown if has already been set.
-
-
-
-
-
-
- Throws an when a response is not available.
-
-
-
-
- Throws an when or are called twice.
-
-
-
-
- A for request messages that can receive multiple replies, which can either be used directly or through derived classes.
-
- The type of request to make.
-
-
-
- Gets the message responses.
-
-
-
-
- Replies to the current request message.
-
- The response to use to reply to the request message.
-
-
-
-
-
-
-
-
-
- A message used to broadcast property changes in observable objects.
-
- The type of the property to broadcast the change for.
-
-
-
- Initializes a new instance of the class.
-
- The original sender of the broadcast message.
- The name of the property that changed.
- The value that the property had before the change.
- The value that the property has after the change.
- Thrown if is .
-
-
-
- Gets the original sender of the broadcast message.
-
-
-
-
- Gets the name of the property that changed.
-
-
-
-
- Gets the value that the property had before the change.
-
-
-
-
- Gets the value that the property has after the change.
-
-
-
-
- A for request messages, which can either be used directly or through derived classes.
-
- The type of request to make.
-
-
-
- Gets the message response.
-
- Thrown when is .
-
-
-
- Gets a value indicating whether a response has already been assigned to this instance.
-
-
-
-
- Replies to the current request message.
-
- The response to use to reply to the request message.
- Thrown if has already been set.
-
-
-
- Implicitly gets the response from a given instance.
-
- The input instance.
- Thrown if is .
- Thrown when is .
-
-
-
- Throws an when a response is not available.
-
-
-
-
- Throws an when is called twice.
-
-
-
-
- A base message that signals whenever a specific value has changed.
-
- The type of value that has changed.
-
-
-
- Initializes a new instance of the class.
-
- The value that has changed.
-
-
-
- Gets the value that has changed.
-
-
-
-
- A class providing a reference implementation for the interface.
-
-
- This implementation uses strong references to track the registered
- recipients, so it is necessary to manually unregister them when they're no longer needed.
-
-
-
-
- The collection of currently registered recipients, with a link to their linked message receivers.
-
-
- This collection is used to allow reflection-free access to all the existing
- registered recipients from and other methods in this type,
- so that all the existing handlers can be removed without having to dynamically create
- the generic types for the containers of the various dictionaries mapping the handlers.
-
-
-
-
- The and instance for types combination.
-
-
- The values are just of type as we don't know the type parameters in advance.
- Each method relies on to get the type-safe instance of the
- or class for each pair of generic arguments in use.
-
-
-
-
- Gets the default instance.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Registers a recipient for a given type of message.
-
- The type of message to receive.
- The type of token to use to pick the messages to receive.
- The recipient that will receive the messages.
- A token used to determine the receiving channel to use.
- The input instance to register, or null.
- Thrown when trying to register the same message twice.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Tries to get the instance of currently
- registered recipients for the input type.
-
- The type of message to send.
- The resulting instance, if found.
- Whether or not the required instance was found.
-
-
-
- Tries to get the instance of currently registered recipients
- for the combination of types and .
-
- The type of message to send.
- The type of token to identify what channel to use to send the message.
- The resulting instance, if found.
- Whether or not the required instance was found.
-
-
-
- Gets the instance of currently
- registered recipients for the input type.
-
- The type of message to send.
- A instance with the requested type arguments.
-
-
-
- Gets the instance of currently registered recipients
- for the combination of types and .
-
- The type of message to send.
- The type of token to identify what channel to use to send the message.
- A instance with the requested type arguments.
-
-
-
- A mapping type representing a link to recipients and their view of handlers per communication channel.
-
-
- This type is a specialization of for tokens.
-
-
-
-
- Initializes a new instance of the class.
-
- The message type being used.
-
-
-
- Creates a new instance of the class.
-
- The type of message to receive.
- A new instance.
-
-
-
-
-
-
- A mapping type representing a link to recipients and their view of handlers per communication channel.
-
- The type of token to use to pick the messages to receive.
-
- This type is defined for simplicity and as a workaround for the lack of support for using type aliases
- over open generic types in C# (using type aliases can only be used for concrete, closed types).
-
-
-
-
- Initializes a new instance of the class.
-
- The message type being used.
-
-
-
- Creates a new instance of the class.
-
- The type of message to receive.
- A new instance.
-
-
-
-
-
-
- An interface for the and types which allows to retrieve
- the type arguments from a given generic instance without having any prior knowledge about those arguments.
-
-
-
-
- Gets the instance representing the current type arguments.
-
-
-
-
- A simple type representing a recipient.
-
-
- This type is used to enable fast indexing in each mapping dictionary,
- since it acts as an external override for the and
- methods for arbitrary objects, removing both
- the virtual call and preventing instances overriding those methods in this context.
- Using this type guarantees that all the equality operations are always only done
- based on reference equality for each registered recipient, regardless of its type.
-
-
-
-
- The registered recipient.
-
-
-
-
- Initializes a new instance of the struct.
-
- The target recipient instance.
-
-
-
-
-
-
-
-
-
-
-
-
- Throws an when trying to add a duplicate handler.
-
-
-
-
- A class providing a reference implementation for the interface.
-
-
-
- This implementation uses weak references to track the registered
- recipients, so it is not necessary to manually unregister them when they're no longer needed.
-
-
- The type will automatically perform internal trimming when
- full GC collections are invoked, so calling manually is not necessary to
- ensure that on average the internal data structures are as trimmed and compact as possible.
-
-
-
-
-
- The map of currently registered recipients for all message types.
-
-
-
-
- Initializes a new instance of the class.
-
-
-
-
- Gets the default instance.
-
-
-
-
-
-
-
-
-
-
- Registers a recipient for a given type of message.
-
- The type of message to receive.
- The type of token to use to pick the messages to receive.
- The recipient that will receive the messages.
- A token used to determine the receiving channel to use.
- Thrown when trying to register the same message twice.
-
- This method is a variation of
- that is specialized for recipients implementing . See more comments at the top of this type, as well as
- within and in the types.
-
-
-
-
- Registers a recipient for a given type of message.
-
- The type of message to receive.
- The type of token to use to pick the messages to receive.
- The recipient that will receive the messages.
- A token used to determine the receiving channel to use.
- The input instance to register, or null.
- Thrown when trying to register the same message twice.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Implements the broadcasting logic for .
-
-
-
-
-
-
- This method is not a local function to avoid triggering multiple compilations due to TToken
- potentially being a value type, which results in specialized code due to reified generics. This is
- necessary to work around a Roslyn limitation that causes unnecessary type parameters in local
- functions not to be discarded in the synthesized methods. Additionally, keeping this loop outside
- of the EH block (the block) can help result in slightly better codegen.
-
-
-
-
-
-
-
-
-
-
- Executes a cleanup without locking the current instance. This method has to be
- invoked when a lock on has already been acquired.
-
-
-
-
- Executes a cleanup without locking the current instance. This method has to be
- invoked when a lock on has already been acquired.
-
-
-
-
- Throws an when trying to add a duplicate handler.
-
-
-
-
- A container for all shared configuration switches for the MVVM Toolkit.
-
-
-
- This type uses a very specific setup for configuration switches to ensure ILLink can work the best.
- This mirrors the architecture of feature switches in the runtime as well, and it's needed so that
- no static constructor is generated for the type.
-
-
- For more info, see .
-
-
-
-
-
- The configuration property name for .
-
-
-
-
- The backing field for .
-
-
-
-
- Gets a value indicating whether or not support for should be enabled (defaults to ).
-
-
-
-
- Gets a configuration value for a specified property.
-
- The property name to retrieve the value for.
- The cached result for the target configuration value.
- The default value for the feature switch, if not set.
- The value of the specified configuration setting.
-
-
-
- Internal polyfill for .
-
-
-
-
- Throws an if is .
-
- The reference type argument to validate as non-.
- The name of the parameter with which corresponds.
-
-
-
- A specialized version for generic values.
-
- The type of values to check.
-
- This type is needed because if there had been a generic overload with a generic parameter, all calls
- would have just been bound by that by the compiler instead of the overload.
-
-
-
-
- Throws an if is .
-
- The reference type argument to validate as non-.
- The name of the parameter with which corresponds.
-
-
-
- Throws an .
-
- The name of the parameter that failed validation.
-
-
-
- A specialized implementation to be used with messenger types.
-
- The type of keys in the dictionary.
- The type of values in the dictionary.
-
-
-
- The index indicating the start of a free linked list.
-
-
-
-
- The array of 1-based indices for the items stored in .
-
-
-
-
- The array of currently stored key-value pairs (ie. the lists for each hash group).
-
-
-
-
- A coefficient used to speed up retrieving the target bucket when doing lookups.
-
-
-
-
- The current number of items stored in the map.
-
-
-
-
- The 1-based index for the start of the free list within .
-
-
-
-
- The total number of empty items.
-
-
-
-
- Initializes a new instance of the class.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Checks whether or not the dictionary contains a pair with a specified key.
-
- The key to look for.
- Whether or not the key was present in the dictionary.
-
-
-
- Gets the value if present for the specified key.
-
- The key to look for.
- The value found, otherwise .
- Whether or not the key was present.
-
-
-
-
-
-
- Gets the value for the specified key, or, if the key is not present,
- adds an entry and returns the value by ref. This makes it possible to
- add or update a value in a single look up operation.
-
- Key to look for.
- Reference to the new or existing value.
-
-
-
-
-
-
- Enumerator for .
-
-
-
-
- The entries being enumerated.
-
-
-
-
- The current enumeration index.
-
-
-
-
- The current dictionary count.
-
-
-
-
- Creates a new instance.
-
- The input dictionary to enumerate.
-
-
-
-
-
-
- Gets the current key.
-
-
-
-
- Gets the current value.
-
-
-
-
- Gets the value for the specified key, or.
-
- Key to look for.
- Reference to the existing value.
-
-
-
- Initializes the current instance.
-
- The target capacity.
-
-
-
-
- Resizes the current dictionary to reduce the number of collisions
-
-
-
-
- Gets a reference to a target bucket from an input hashcode.
-
- The input hashcode.
- A reference to the target bucket.
-
-
-
- A type representing a map entry, ie. a node in a given list.
-
-
-
-
- The cached hashcode for ;
-
-
-
-
- 0-based index of next entry in chain: -1 means end of chain
- also encodes whether this entry this.itself_ is part of the free list by changing sign and subtracting 3,
- so -2 means end of free list, -3 means index 0 but on free list, -4 means index 1 but on free list, etc.
-
-
-
-
- The key for the value in the current node.
-
-
-
-
- The value in the current node, if present.
-
-
-
-
- Throws an when trying to load an element with a missing key.
-
-
-
-
- A helper class for .
-
-
-
-
- Maximum prime smaller than the maximum array length.
-
-
-
-
- An arbitrary prime factor used in .
-
-
-
-
- Table of prime numbers to use as hash table sizes.
-
-
-
-
- Checks whether a value is a prime.
-
- The value to check.
- Whether or not is a prime.
-
-
-
- Gets the smallest prime bigger than a specified value.
-
- The target minimum value.
- The new prime that was found.
-
-
-
- Returns size of hashtable to grow to.
-
- The previous table size.
- The expanded table size.
-
-
-
- Returns approximate reciprocal of the divisor: ceil(2**64 / divisor).
-
- This should only be used on 64-bit.
-
-
-
- Performs a mod operation using the multiplier pre-computed with .
-
- This should only be used on 64-bit.
-
-
-
- A base interface masking instances and exposing non-generic functionalities.
-
-
-
-
- Gets the count of entries in the dictionary.
-
-
-
-
- Clears the current dictionary.
-
-
-
-
- An interface providing key type contravariant and value type covariant access
- to a instance.
-
- The contravariant type of keys in the dictionary.
- The covariant type of values in the dictionary.
-
-
-
- Gets the value with the specified key.
-
- The key to look for.
- The returned value.
- Thrown if the key wasn't present.
-
-
-
- An interface providing key type contravariant access to a instance.
-
- The contravariant type of keys in the dictionary.
-
-
-
- Tries to remove a value with a specified key, if present.
-
- The key of the value to remove.
- Whether or not the key was present.
-
-
-
- Schedules a callback roughly every gen 2 GC (you may see a Gen 0 an Gen 1 but only once).
- Ported from https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Gen2GcCallback.cs.
-
-
-
-
- The callback to invoke at each GC.
-
-
-
-
- A weak to the target object to pass to .
-
-
-
-
- Initializes a new instance of the class.
-
- The callback to invoke at each GC.
- The target object to pass as argument to .
-
-
-
- Schedules a callback to be called on each GC until the target is collected.
-
- The callback to invoke at each GC.
- The target object to pass as argument to .
-
-
-
- Finalizes an instance of the class.
- This finalizer is re-registered with as long as
- the target object is alive, which means it will be executed again every time a generation 2
- collection is triggered (as the instance itself would be moved to
- that generation after surviving the generation 0 and 1 collections the first time).
-
-
-
-
- A custom instance that is specifically optimized to be used
- by . In particular, it offers zero-allocation enumeration of stored items.
-
- Tke key of items to store in the table.
- The values to store in the table.
-
-
-
- Initial length of the table. Must be a power of two.
-
-
-
-
- This lock protects all mutation of data in the table. Readers do not take this lock.
-
-
-
-
- The actual storage for the table; swapped out as the table grows.
-
-
-
-
- Initializes a new instance of the class.
-
-
-
-
-
-
-
- Tries to add a new pair to the table.
-
- The key to add.
- The value to associate with key.
-
-
-
-
-
-
-
-
-
- Implements the functionality for under a lock.
-
- The input key.
- The callback to use to create a new item.
- The new item to store.
-
-
-
-
-
-
- Provides an enumerator for the current instance.
-
-
-
-
- Parent table, set to null when disposed.
-
-
-
-
- Last index in the container that should be enumerated.
-
-
-
-
- The current index into the container.
-
-
-
-
- The current key, if available.
-
-
-
-
- The current value, if available.
-
-
-
-
- Initializes a new instance of the class.
-
- The input instance being enumerated.
-
-
-
-
-
-
-
-
-
- Gets the current key.
-
-
-
-
- Gets the current value.
-
-
-
-
- Worker for adding a new key/value pair. Will resize the container if it is full.
-
- The key for the new entry.
- The value for the new entry.
-
-
-
- A single entry within a instance.
-
-
-
-
- Holds key and value using a weak reference for the key and a strong reference for the
- value that is traversed only if the key is reachable without going through the value.
-
-
-
-
- Cached copy of key's hashcode.
-
-
-
-
- Index of next entry, -1 if last.
-
-
-
-
- Container holds the actual data for the table. A given instance of Container always has the same capacity. When we need
- more capacity, we create a new Container, copy the old one into the new one, and discard the old one. This helps enable
- lock-free reads from the table, as readers never need to deal with motion of entries due to rehashing.
-
-
-
-
- The with which this container is associated.
-
-
-
-
- buckets[hashcode & (buckets.Length - 1)] contains index of the first entry in bucket (-1 if empty).
-
-
-
-
- The table entries containing the stored dependency handles
-
-
-
-
- firstFreeEntry < entries.Length => table has capacity, entries grow from the bottom of the table.
-
-
-
-
- Flag detects if OOM or other background exception threw us out of the lock.
-
-
-
-
- Set to true when initially finalized
-
-
-
-
- Used to ensure the next allocated container isn't finalized until this one is GC'd.
-
-
-
-
- Initializes a new instance of the class.
-
- The input object associated with the current instance.
-
-
-
- Initializes a new instance of the class.
-
- The input object associated with the current instance.
- The array of buckets.
- The array of entries.
- The index of the first free entry.
-
-
-
- Gets the capacity of the current container.
-
-
-
-
- Gets the index of the first free entry.
-
-
-
-
- Worker for adding a new key/value pair. Container must NOT be full.
-
-
-
-
- Worker for finding a key/value pair. Must hold lock.
-
-
-
-
- Returns -1 if not found (if key expires during FindEntry, this can be treated as "not found.").
- Must hold lock, or be prepared to retry the search while holding lock.
-
- This method requires to be on the stack to be properly tracked.
-
-
-
- Gets the entry at the specified entry index.
-
-
-
-
- Removes the specified key from the table, if it exists.
-
-
-
-
- Removes a given entry at a specified index.
-
- The index of the entry to remove.
-
-
-
- Resize, and scrub expired keys off bucket lists. Must hold .
-
-
- is less than entries.Length on exit, that is, the table has at least one free entry.
-
-
-
-
- Creates a new of a specified size with the current items.
-
- The new requested size.
- The new instance with the requested size.
-
-
-
- Verifies that the current instance is valid.
-
- Thrown if the current instance is invalid.
-
-
-
- Finalizes the current instance.
-
-
-
-
+
+
+
+ CommunityToolkit.Mvvm
+
+
+
+
+ A helper type for the type.
+
+
+
+
+ The cached for
+
+
+
+
+ An interface for a grouped collection of items.
+
+
+
+
+ Gets the key for the current collection.
+
+
+
+
+ Gets the number of items currently in the grouped collection.
+
+
+
+
+ Gets the element at the specified index in the current collection.
+
+ The zero-based index of the element to get.
+ The element at the specified index in the read-only list.
+ Thrown if the index is out of range.
+
+
+
+ An interface for a grouped collection of items.
+
+ The type of the group key.
+ The type of elements in the group.
+
+
+
+ Gets the element at the specified index in the current collection.
+
+ The zero-based index of the element to get.
+ The element at the specified index in the read-only list.
+ Thrown if the index is out of range.
+
+
+
+ An interface for a grouped collection of items.
+
+ The type of the group key.
+
+
+
+ Gets the key for the current collection.
+
+
+
+
+ The extensions methods to simplify the usage of .
+
+
+
+
+ Returns the first group with key.
+
+ The type of the group key.
+ The type of the items in the collection.
+ The source instance.
+ The key of the group to query.
+ The first group matching .
+ Thrown if or are .
+ The target group does not exist.
+
+
+
+ Returns the first group with key or if not found.
+
+ The type of the group key.
+ The type of the items in the collection.
+ The source instance.
+ The key of the group to query.
+ The first group matching or .
+ Thrown if or are .
+
+
+
+ Adds a key-value item into a target .
+
+ The type of the group key.
+ The type of the items in the collection.
+ The source instance.
+ The key of the group to add.
+ The added .
+ Thrown if or are .
+
+
+
+ Adds a key-collection item into a target .
+
+ The type of the group key.
+ The type of the items in the collection.
+ The source instance.
+ The group of items to add.
+ The added .
+ Thrown if or are .
+
+
+
+ Adds a key-collection item into a target .
+
+ The type of the group key.
+ The type of the items in the collection.
+ The source instance.
+ The key of the group where will be added.
+ The collection to add.
+ The added .
+ Thrown if , or are .
+
+
+
+ Adds a key-value item into a target .
+
+ The type of the group key.
+ The type of the items in the collection.
+ The source instance.
+ The key of the group to add.
+ The added .
+ Thrown if or are .
+
+
+
+ Adds a key-value item into a target .
+
+ The type of the group key.
+ The type of the items in the collection.
+ The source instance.
+ The group of items to add.
+ The added .
+ Thrown if or are .
+
+
+
+ Adds a key-value item into a target .
+
+ The type of the group key.
+ The type of the items in the collection.
+ The source instance.
+ The key of the group where will be added.
+ The collection to add.
+ The added .
+ Thrown if , or are .
+
+
+
+ Adds a key-value item into a target .
+
+ The type of the group key.
+ The type of the items in the collection.
+ The source instance.
+ The key of the group to add.
+ The instance to insert at the right position.
+ The added .
+ Thrown if , or are .
+
+
+
+ Adds a key-value item into a target .
+
+ The type of the group key.
+ The type of the items in the collection.
+ The source instance.
+ The group of items to add.
+ The instance to insert at the right position.
+ The added .
+ Thrown if , or are .
+
+
+
+ Adds a key-value item into a target .
+
+ The type of the group key.
+ The type of the items in the collection.
+ The source instance.
+ The key of the group where will be added.
+ The instance to insert at the right position.
+ The collection to add.
+ The added .
+ Thrown if , , or are .
+
+
+
+ Add into the first group with key.
+ If the group does not exist, it will be added.
+
+ The type of the group key.
+ The type of the items in the collection.
+ The source instance.
+ The key of the group where the should be added.
+ The item to add.
+ The instance of the which will receive the value. It will either be an existing group or a new group.
+ Thrown if or are .
+
+
+
+ Insert into the first group with key.
+
+ The type of the group key.
+ The type of the items in the collection.
+ The source instance.
+ The key of the group where to insert .
+ The item to add.
+ The instance of the which will receive the value.
+ Thrown if or are .
+
+
+
+ Insert into the first group with key.
+
+ The type of the group key.
+ The type of the items in the collection.
+ The source instance.
+ The key of the group where to insert .
+ The instance to compare keys.
+ The item to add.
+ The instance to compare elements.
+ The instance of the which will receive the value.
+ Thrown if , , or are .
+
+
+
+ Remove the first occurrence of the group with from the grouped collection.
+ It will not do anything if the group does not exist.
+
+ The type of the group key.
+ The type of the items in the collection.
+ The source instance.
+ The key of the group to remove.
+ Thrown if or are .
+
+
+
+ Remove the first from the first group with from the grouped collection.
+ It will not do anything if the group or the item does not exist.
+
+ The type of the group key.
+ The type of the items in the collection.
+ The source instance.
+ The key of the group where the should be removed.
+ The item to remove.
+ If true (default value), the group will be removed once it becomes empty.
+ Thrown if or are .
+
+
+
+ An observable list of observable groups.
+
+ The type of the group keys.
+ The type of elements in the collection.
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+ Initializes a new instance of the class.
+
+ The initial data to add in the grouped collection.
+ Thrown if is .
+
+
+
+
+
+
+ Tries to get the underlying instance, if present.
+
+ The resulting , if one was in use.
+ Whether or not a instance has been found.
+
+
+
+
+
+
+
+
+
+ An observable group.
+ It associates a to an .
+
+ The type of the group key.
+ The type of elements in the group.
+
+
+
+ Initializes a new instance of the class.
+
+ The key for the group.
+ Thrown if is .
+
+
+
+ Initializes a new instance of the class.
+
+ The grouping to fill the group.
+ Thrown if is .
+
+
+
+ Initializes a new instance of the class.
+
+ The key for the group.
+ The initial collection of data to add to the group.
+ Thrown if or are .
+
+
+
+ Gets or sets the key of the group.
+
+ Thrown if is .
+
+
+
+ Tries to get the underlying instance, if present.
+
+ The resulting , if one was in use.
+ Whether or not a instance has been found.
+
+
+
+
+
+
+
+
+
+ A read-only list of groups.
+
+ The type of the group keys.
+ The type of elements in the collection.
+
+
+
+ Initializes a new instance of the class.
+
+ The source collection to wrap.
+ Thrown if is .
+
+
+
+ Initializes a new instance of the class.
+
+ The source collection to wrap.
+ Thrown if is .
+
+
+
+
+
+
+
+
+
+
+
+
+ Forwards the event whenever it is raised by the wrapped collection.
+
+ The wrapped collection (an of instance).
+ The arguments.
+ Thrown if a range operation is requested.
+
+
+
+ Returns the first group with key or if not found.
+
+ The key of the group to query (assumed not to be ).
+ The first group matching .
+
+
+
+ A read-only observable group. It associates a to a .
+
+ The type of the group key.
+ The type of elements in the group.
+
+
+
+ Initializes a new instance of the class.
+
+ The key of the group.
+ The collection of items to add in the group.
+ Thrown if or are .
+
+
+
+ Initializes a new instance of the class.
+
+ The to wrap.
+ Thrown if is .
+
+
+
+
+
+
+
+
+
+
+
+
+ An attribute that indicates that a given type should implement the interface and
+ have minimal built-in functionality to support it. This includes exposing the necessary event and having two methods
+ to raise it that mirror and
+ . For more extensive support, use .
+
+ This attribute can be used as follows:
+
+ [INotifyPropertyChanged]
+ partial class MyViewModel : SomeOtherClass
+ {
+ // Other members here...
+ }
+
+
+
+
+
+
+ Gets or sets a value indicating whether or not to also generate all the additional helper methods that are found
+ in as well (eg. .
+ If set to , only the event and
+ the two overloads will be generated.
+ The default value is .
+
+
+
+
+ An attribute that can be used to support properties in generated properties. When this attribute is
+ used, the generated property setter will also call for the properties specified
+ in the attribute data, causing the validation logic for the command to be executed again. This can be useful to keep the code compact
+ when there are one or more dependent commands that should also be notified when a property is updated. If this attribute is used in
+ a field without , it is ignored (just like ).
+
+ In order to use this attribute, the target property has to implement the interface.
+
+
+ This attribute can be used as follows:
+
+ partial class MyViewModel : ObservableObject
+ {
+ [ObservableProperty]
+ [NotifyCanExecuteChangedFor(nameof(GreetUserCommand))]
+ private string name;
+
+ public IRelayCommand GreetUserCommand { get; }
+ }
+
+
+ And with this, code analogous to this will be generated:
+
+ partial class MyViewModel
+ {
+ public string Name
+ {
+ get => name;
+ set
+ {
+ if (SetProperty(ref name, value))
+ {
+ GreetUserCommand.NotifyCanExecuteChanged();
+ }
+ }
+ }
+ }
+
+
+
+
+
+ Initializes a new instance of the class.
+
+ The name of the command to also notify when the annotated property changes.
+
+
+
+ Initializes a new instance of the class.
+
+ The name of the property to also notify when the annotated property changes.
+
+ The other command names to also notify when the annotated property changes. This parameter can optionally
+ be used to indicate a series of dependent commands from the same attribute, to keep the code more compact.
+
+
+
+
+ Gets the command names to also notify when the annotated property changes.
+
+
+
+
+ An attribute that can be used to support in generated properties, when applied to
+ fields contained in a type that is inheriting from and using any validation attributes.
+ When this attribute is used, the generated property setter will also call .
+ This allows generated properties to opt-in into validation behavior without having to fallback into a full explicit observable property.
+
+ This attribute can be used as follows:
+
+ partial class MyViewModel : ObservableValidator
+ {
+ [ObservableProperty]
+ [NotifyDataErrorInfo]
+ [Required]
+ [MinLength(2)]
+ private string username;
+ }
+
+
+ And with this, code analogous to this will be generated:
+
+ partial class MyViewModel
+ {
+ [Required]
+ [MinLength(2)]
+ public string Username
+ {
+ get => username;
+ set => SetProperty(ref username, value, validate: true);
+ }
+ }
+
+
+
+
+
+ An attribute that can be used to support in generated properties. When this attribute is
+ used, the generated property setter will also call (or the equivalent
+ method in the target class) for the properties specified in the attribute data. This can be useful to keep the code compact when
+ there are one or more dependent properties that should also be reported as updated when the value of the annotated observable
+ property is changed. If this attribute is used in a field without , it is ignored.
+
+ In order to use this attribute, the containing type has to implement the interface
+ and expose a method with the same signature as . If the containing
+ type also implements the interface and exposes a method with the same signature as
+ , then this method will be invoked as well by the property setter.
+
+
+ This attribute can be used as follows:
+
+ partial class MyViewModel : ObservableObject
+ {
+ [ObservableProperty]
+ [NotifyPropertyChangedFor(nameof(FullName))]
+ private string name;
+
+ [ObservableProperty]
+ [NotifyPropertyChangedFor(nameof(FullName))]
+ private string surname;
+
+ public string FullName => $"{Name} {Surname}";
+ }
+
+
+ And with this, code analogous to this will be generated:
+
+ partial class MyViewModel
+ {
+ public string Name
+ {
+ get => name;
+ set
+ {
+ if (!EqualityComparer<string>.Default.Equals(name, value))
+ {
+ OnPropertyChanging(nameof(Name));
+ OnPropertyChanged(nameof(FullName));
+
+ name = value;
+
+ OnPropertyChanged(nameof(Name));
+ OnPropertyChanged(nameof(FullName));
+ }
+ }
+ }
+
+ public string Surname
+ {
+ get => surname;
+ set
+ {
+ if (!EqualityComparer<string>.Default.Equals(name, value))
+ {
+ OnPropertyChanging(nameof(Surname));
+ OnPropertyChanged(nameof(FullName));
+
+ surname = value;
+
+ OnPropertyChanged(nameof(Surname));
+ OnPropertyChanged(nameof(FullName));
+ }
+ }
+ }
+ }
+
+
+
+
+
+ Initializes a new instance of the class.
+
+ The name of the property to also notify when the annotated property changes.
+
+
+
+ Initializes a new instance of the class.
+
+ The name of the property to also notify when the annotated property changes.
+
+ The other property names to also notify when the annotated property changes. This parameter can optionally
+ be used to indicate a series of dependent properties from the same attribute, to keep the code more compact.
+
+
+
+
+ Gets the property names to also notify when the annotated property changes.
+
+
+
+
+ An attribute that can be used to support in generated properties, when applied to fields
+ contained in a type that is either inheriting from , or annotated with .
+ When this attribute is used, the generated property setter will also call .
+ This allows generated properties to opt-in into broadcasting behavior without having to fallback into a full explicit observable property.
+
+ This attribute can be used as follows:
+
+ partial class MyViewModel : ObservableRecipient
+ {
+ [ObservableProperty]
+ [NotifyPropertyChangedRecipients]
+ private string username;
+ }
+
+
+
+ And with this, code analogous to this will be generated:
+
+ partial class MyViewModel
+ {
+ public string Username
+ {
+ get => username;
+ set => SetProperty(ref username, value, broadcast: true);
+ }
+ }
+
+
+
+ This attribute can also be added to a class, and if so it will affect all generated properties in that type and inherited types.
+
+
+
+
+
+ An attribute that indicates that a given type should have all the members from
+ generated into it, as well as the and
+ interfaces. This can be useful when you want the same functionality from into a class
+ that already inherits from another one (since C# doesn't support multiple inheritance). This attribute will trigger
+ the source generator to just create the same APIs directly into the decorated class.
+
+ This attribute can be used as follows:
+
+ [ObservableObject]
+ partial class MyViewModel : SomeOtherClass
+ {
+ // Other members here...
+ }
+
+
+ And with this, the same APIs from will be available on this type as well.
+
+
+
+
+ An attribute that indicates that a given field should be wrapped by a generated observable property.
+ In order to use this attribute, the containing type has to inherit from , or it
+ must be using or .
+ If the containing type also implements the (that is, if it either inherits from
+ or is using ), then the generated code will
+ also invoke to signal that event.
+
+ This attribute can be used as follows:
+
+ partial class MyViewModel : ObservableObject
+ {
+ [ObservableProperty]
+ private string name;
+
+ [ObservableProperty]
+ private bool isEnabled;
+ }
+
+
+ And with this, code analogous to this will be generated:
+
+ partial class MyViewModel
+ {
+ public string Name
+ {
+ get => name;
+ set => SetProperty(ref name, value);
+ }
+
+ public bool IsEnabled
+ {
+ get => isEnabled;
+ set => SetProperty(ref isEnabled, value);
+ }
+ }
+
+
+
+ The generated properties will automatically use the UpperCamelCase format for their names,
+ which will be derived from the field names. The generator can also recognize fields using either
+ the _lowerCamel or m_lowerCamel naming scheme. Otherwise, the first character in the
+ source field name will be converted to uppercase (eg. isEnabled to IsEnabled).
+
+
+
+
+ An attribute that indicates that a given type should have all the members from
+ generated into it. This can be useful when you want the same functionality from into
+ a class that already inherits from another one (since C# doesn't support multiple inheritance). This attribute will trigger
+ the source generator to just create the same APIs directly into the decorated class. For instance, this attribute can be
+ used to easily combine the functionality from both and ,
+ by using as the base class and adding this attribute to the declared type.
+
+ This attribute can be used as follows:
+
+ [ObservableRecipient]
+ partial class MyViewModel : ObservableValidator
+ {
+ // Other members here...
+ }
+
+
+ And with this, the same APIs from will be available on this type as well.
+
+ To avoid conflicts with other APIs in types where the new members are being generated, constructors are only generated when the annotated
+ type doesn't have any explicit constructors being declared. If that is the case, the same constructors from
+ are emitted, with the accessibility adapted to that of the annotated type. Otherwise, they are skipped, so the type being annotated has the
+ responsibility of properly initializing the property. Additionally, if the annotated type inherits
+ from , the overloads will be skipped
+ as well, as they would conflict with the methods.
+
+
+
+ In order to work, needs to be applied to a type that inherits from
+ (either directly or indirectly), or to one decorated with .
+ This is because the methods rely on some of the inherited members to work.
+ If this condition is not met, the code will fail to build.
+
+
+
+
+ A base class for objects of which the properties must be observable.
+
+
+
+
+
+
+
+
+
+
+ Raises the event.
+
+ The input instance.
+ Thrown if is .
+
+
+
+ Raises the event.
+
+ The input instance.
+ Thrown if is .
+
+
+
+ Raises the event.
+
+ (optional) The name of the property that changed.
+
+
+
+ Raises the event.
+
+ (optional) The name of the property that changed.
+
+
+
+ Compares the current and new values for a given property. If the value has changed,
+ raises the event, updates the property with the new
+ value, then raises the event.
+
+ The type of the property that changed.
+ The field storing the property's value.
+ The property's value after the change occurred.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+
+ The and events are not raised
+ if the current and new value for the target property are the same.
+
+
+
+
+ Compares the current and new values for a given property. If the value has changed,
+ raises the event, updates the property with the new
+ value, then raises the event.
+ See additional notes about this overload in .
+
+ The type of the property that changed.
+ The field storing the property's value.
+ The property's value after the change occurred.
+ The instance to use to compare the input values.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+ Thrown if is .
+
+
+
+ Compares the current and new values for a given property. If the value has changed,
+ raises the event, updates the property with the new
+ value, then raises the event.
+ This overload is much less efficient than and it
+ should only be used when the former is not viable (eg. when the target property being
+ updated does not directly expose a backing field that can be passed by reference).
+ For performance reasons, it is recommended to use a stateful callback if possible through
+ the whenever possible
+ instead of this overload, as that will allow the C# compiler to cache the input callback and
+ reduce the memory allocations. More info on that overload are available in the related XML
+ docs. This overload is here for completeness and in cases where that is not applicable.
+
+ The type of the property that changed.
+ The current property value.
+ The property's value after the change occurred.
+ A callback to invoke to update the property value.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+
+ The and events are not raised
+ if the current and new value for the target property are the same.
+
+ Thrown if is .
+
+
+
+ Compares the current and new values for a given property. If the value has changed,
+ raises the event, updates the property with the new
+ value, then raises the event.
+ See additional notes about this overload in .
+
+ The type of the property that changed.
+ The current property value.
+ The property's value after the change occurred.
+ The instance to use to compare the input values.
+ A callback to invoke to update the property value.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+ Thrown if or are .
+
+
+
+ Compares the current and new values for a given nested property. If the value has changed,
+ raises the event, updates the property and then raises the
+ event. The behavior mirrors that of ,
+ with the difference being that this method is used to relay properties from a wrapped model in the
+ current instance. This type is useful when creating wrapping, bindable objects that operate over
+ models that lack support for notification (eg. for CRUD operations).
+ Suppose we have this model (eg. for a database row in a table):
+
+ public class Person
+ {
+ public string Name { get; set; }
+ }
+
+ We can then use a property to wrap instances of this type into our observable model (which supports
+ notifications), injecting the notification to the properties of that model, like so:
+
+ public class BindablePerson : ObservableObject
+ {
+ public Model { get; }
+
+ public BindablePerson(Person model)
+ {
+ Model = model;
+ }
+
+ public string Name
+ {
+ get => Model.Name;
+ set => Set(Model.Name, value, Model, (model, name) => model.Name = name);
+ }
+ }
+
+ This way we can then use the wrapping object in our application, and all those "proxy" properties will
+ also raise notifications when changed. Note that this method is not meant to be a replacement for
+ , and it should only be used when relaying properties to a model that
+ doesn't support notifications, and only if you can't implement notifications to that model directly (eg. by having
+ it inherit from ). The syntax relies on passing the target model and a stateless callback
+ to allow the C# compiler to cache the function, which results in much better performance and no memory usage.
+
+ The type of model whose property (or field) to set.
+ The type of property (or field) to set.
+ The current property value.
+ The property's value after the change occurred.
+ The model containing the property being updated.
+ The callback to invoke to set the target property value, if a change has occurred.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+
+ The and events are not
+ raised if the current and new value for the target property are the same.
+
+ Thrown if or are .
+
+
+
+ Compares the current and new values for a given nested property. If the value has changed,
+ raises the event, updates the property and then raises the
+ event. The behavior mirrors that of ,
+ with the difference being that this method is used to relay properties from a wrapped model in the
+ current instance. See additional notes about this overload in .
+
+ The type of model whose property (or field) to set.
+ The type of property (or field) to set.
+ The current property value.
+ The property's value after the change occurred.
+ The instance to use to compare the input values.
+ The model containing the property being updated.
+ The callback to invoke to set the target property value, if a change has occurred.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+ Thrown if , or are .
+
+
+
+ Compares the current and new values for a given field (which should be the backing
+ field for a property). If the value has changed, raises the
+ event, updates the field and then raises the event.
+ The behavior mirrors that of , with the difference being that
+ this method will also monitor the new value of the property (a generic ) and will also
+ raise the again for the target property when it completes.
+ This can be used to update bindings observing that or any of its properties.
+ This method and its overload specifically rely on the type, which needs
+ to be used in the backing field for the target property. The field doesn't need to be
+ initialized, as this method will take care of doing that automatically. The
+ type also includes an implicit operator, so it can be assigned to any instance directly.
+ Here is a sample property declaration using this method:
+
+ private TaskNotifier myTask;
+
+ public Task MyTask
+ {
+ get => myTask;
+ private set => SetAndNotifyOnCompletion(ref myTask, value);
+ }
+
+
+ The field notifier to modify.
+ The property's value after the change occurred.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+
+ The and events are not raised if the current
+ and new value for the target property are the same. The return value being only
+ indicates that the new value being assigned to is different than the previous one,
+ and it does not mean the new instance passed as argument is in any particular state.
+
+
+
+
+ Compares the current and new values for a given field (which should be the backing
+ field for a property). If the value has changed, raises the
+ event, updates the field and then raises the event.
+ This method is just like ,
+ with the difference being an extra parameter with a callback being invoked
+ either immediately, if the new task has already completed or is , or upon completion.
+
+ The field notifier to modify.
+ The property's value after the change occurred.
+ A callback to invoke to update the property value.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+
+ The and events are not raised
+ if the current and new value for the target property are the same.
+
+ Thrown if is .
+
+
+
+ Compares the current and new values for a given field (which should be the backing
+ field for a property). If the value has changed, raises the
+ event, updates the field and then raises the event.
+ The behavior mirrors that of , with the difference being that
+ this method will also monitor the new value of the property (a generic ) and will also
+ raise the again for the target property when it completes.
+ This can be used to update bindings observing that or any of its properties.
+ This method and its overload specifically rely on the type, which needs
+ to be used in the backing field for the target property. The field doesn't need to be
+ initialized, as this method will take care of doing that automatically. The
+ type also includes an implicit operator, so it can be assigned to any instance directly.
+ Here is a sample property declaration using this method:
+
+ private TaskNotifier<int> myTask;
+
+ public Task<int> MyTask
+ {
+ get => myTask;
+ private set => SetAndNotifyOnCompletion(ref myTask, value);
+ }
+
+
+ The type of result for the to set and monitor.
+ The field notifier to modify.
+ The property's value after the change occurred.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+
+ The and events are not raised if the current
+ and new value for the target property are the same. The return value being only
+ indicates that the new value being assigned to is different than the previous one,
+ and it does not mean the new instance passed as argument is in any particular state.
+
+
+
+
+ Compares the current and new values for a given field (which should be the backing
+ field for a property). If the value has changed, raises the
+ event, updates the field and then raises the event.
+ This method is just like ,
+ with the difference being an extra parameter with a callback being invoked
+ either immediately, if the new task has already completed or is , or upon completion.
+
+ The type of result for the to set and monitor.
+ The field notifier to modify.
+ The property's value after the change occurred.
+ A callback to invoke to update the property value.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+
+ The and events are not raised
+ if the current and new value for the target property are the same.
+
+ Thrown if is .
+
+
+
+ Implements the notification logic for the related methods.
+
+ The type of to set and monitor.
+ The field notifier.
+ The property's value after the change occurred.
+ (optional) A callback to invoke to update the property value.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+
+
+
+ An interface for task notifiers of a specified type.
+
+ The type of value to store.
+
+
+
+ Gets or sets the wrapped value.
+
+
+
+
+ A wrapping class that can hold a value.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+
+
+
+ Unwraps the value stored in the current instance.
+
+ The input instance.
+
+
+
+ A wrapping class that can hold a value.
+
+ The type of value for the wrapped instance.
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+
+
+
+ Unwraps the value stored in the current instance.
+
+ The input instance.
+
+
+
+ A base class for observable objects that also acts as recipients for messages. This class is an extension of
+ which also provides built-in support to use the type.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+ This constructor will produce an instance that will use the instance
+ to perform requested operations. It will also be available locally through the property.
+
+
+
+
+ Initializes a new instance of the class.
+
+ The instance to use to send messages.
+ Thrown if is .
+
+
+
+ Gets the instance in use.
+
+
+
+
+ Gets or sets a value indicating whether the current view model is currently active.
+
+
+
+
+ Invoked whenever the property is set to .
+ Use this method to register to messages and do other initialization for this instance.
+
+
+ The base implementation registers all messages for this recipients that have been declared
+ explicitly through the interface, using the default channel.
+ For more details on how this works, see the method.
+ If you need more fine tuned control, want to register messages individually or just prefer
+ the lambda-style syntax for message registration, override this method and register manually.
+
+
+
+
+ Invoked whenever the property is set to .
+ Use this method to unregister from messages and do general cleanup for this instance.
+
+
+ The base implementation unregisters all messages for this recipient. It does so by
+ invoking , which removes all registered
+ handlers for a given subscriber, regardless of what token was used to register them.
+ That is, all registered handlers across all subscription channels will be removed.
+
+
+
+
+ Broadcasts a with the specified
+ parameters, without using any particular token (so using the default channel).
+
+ The type of the property that changed.
+ The value of the property before it changed.
+ The value of the property after it changed.
+ The name of the property that changed.
+
+ You should override this method if you wish to customize the channel being
+ used to send the message (eg. if you need to use a specific token for the channel).
+
+
+
+
+ Compares the current and new values for a given property. If the value has changed,
+ raises the event, updates the property with
+ the new value, then raises the event.
+
+ The type of the property that changed.
+ The field storing the property's value.
+ The property's value after the change occurred.
+ If , will also be invoked.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+
+ This method is just like , just with the addition
+ of the parameter. As such, following the behavior of the base method,
+ the and events
+ are not raised if the current and new value for the target property are the same.
+
+
+
+
+ Compares the current and new values for a given property. If the value has changed,
+ raises the event, updates the property with
+ the new value, then raises the event.
+ See additional notes about this overload in .
+
+ The type of the property that changed.
+ The field storing the property's value.
+ The property's value after the change occurred.
+ The instance to use to compare the input values.
+ If , will also be invoked.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+ Thrown if is .
+
+
+
+ Compares the current and new values for a given property. If the value has changed,
+ raises the event, updates the property with
+ the new value, then raises the event. Similarly to
+ the method, this overload should only be
+ used when can't be used directly.
+
+ The type of the property that changed.
+ The current property value.
+ The property's value after the change occurred.
+ A callback to invoke to update the property value.
+ If , will also be invoked.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+
+ This method is just like , just with the addition
+ of the parameter. As such, following the behavior of the base method,
+ the and events
+ are not raised if the current and new value for the target property are the same.
+
+ Thrown if is .
+
+
+
+ Compares the current and new values for a given property. If the value has changed,
+ raises the event, updates the property with
+ the new value, then raises the event.
+ See additional notes about this overload in .
+
+ The type of the property that changed.
+ The current property value.
+ The property's value after the change occurred.
+ The instance to use to compare the input values.
+ A callback to invoke to update the property value.
+ If , will also be invoked.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+ Thrown if or are .
+
+
+
+ Compares the current and new values for a given nested property. If the value has changed,
+ raises the event, updates the property and then raises the
+ event. The behavior mirrors that of
+ , with the difference being that this
+ method is used to relay properties from a wrapped model in the current instance. For more info, see the docs for
+ .
+
+ The type of model whose property (or field) to set.
+ The type of property (or field) to set.
+ The current property value.
+ The property's value after the change occurred.
+ The model
+ The callback to invoke to set the target property value, if a change has occurred.
+ If , will also be invoked.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+ Thrown if or are .
+
+
+
+ Compares the current and new values for a given nested property. If the value has changed,
+ raises the event, updates the property and then raises the
+ event. The behavior mirrors that of
+ ,
+ with the difference being that this method is used to relay properties from a wrapped model in the
+ current instance. For more info, see the docs for
+ .
+
+ The type of model whose property (or field) to set.
+ The type of property (or field) to set.
+ The current property value.
+ The property's value after the change occurred.
+ The instance to use to compare the input values.
+ The model
+ The callback to invoke to set the target property value, if a change has occurred.
+ If , will also be invoked.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+ Thrown if , or are .
+
+
+
+ A base class for objects implementing the interface. This class
+ also inherits from , so it can be used for observable items too.
+
+
+
+
+ The instance used to track compiled delegates to validate entities.
+
+
+
+
+ The instance used to track display names for properties to validate.
+
+
+ This is necessary because we want to reuse the same instance for all validations, but
+ with the same behavior with respect to formatted names that new instances would have provided. The issue is that the
+ property is not refreshed when we set ,
+ so we need to replicate the same logic to retrieve the right display name for properties to validate and update that
+ property manually right before passing the context to and proceed with the normal functionality.
+
+
+
+
+ The cached for .
+
+
+
+
+ The instance currently in use.
+
+
+
+
+ The instance used to store previous validation results.
+
+
+
+
+ Indicates the total number of properties with errors (not total errors).
+ This is used to allow to operate in O(1) time, as it can just
+ check whether this value is not 0 instead of having to traverse .
+
+
+
+
+
+
+
+ Initializes a new instance of the class.
+ This constructor will create a new that will
+ be used to validate all properties, which will reference the current instance
+ and no additional services or validation properties and settings.
+
+
+
+
+ Initializes a new instance of the class.
+ This constructor will create a new that will
+ be used to validate all properties, which will reference the current instance.
+
+ A set of key/value pairs to make available to consumers.
+
+
+
+ Initializes a new instance of the class.
+ This constructor will create a new that will
+ be used to validate all properties, which will reference the current instance.
+
+ An instance to make available during validation.
+ A set of key/value pairs to make available to consumers.
+
+
+
+ Initializes a new instance of the class.
+ This constructor will store the input instance,
+ and it will use it to validate all properties for the current viewmodel.
+
+
+ The instance to use to validate properties.
+
+ This instance will be passed to all
+ calls executed by the current viewmodel, and its property will be updated every time
+ before the call is made to set the name of the property being validated. The property name will not be reset after that, so the
+ value of will always indicate the name of the last property that was validated, if any.
+
+
+ Thrown if is .
+
+
+
+
+
+
+ Compares the current and new values for a given property. If the value has changed,
+ raises the event, updates the property with
+ the new value, then raises the event.
+
+ The type of the property that changed.
+ The field storing the property's value.
+ The property's value after the change occurred.
+ If , will also be validated.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+
+ This method is just like , just with the addition
+ of the parameter. If that is set to , the new value will be
+ validated and will be raised if needed. Following the behavior of the base method,
+ the and events
+ are not raised if the current and new value for the target property are the same.
+
+ Thrown if is .
+
+
+
+ Compares the current and new values for a given property. If the value has changed,
+ raises the event, updates the property with
+ the new value, then raises the event.
+ See additional notes about this overload in .
+
+ The type of the property that changed.
+ The field storing the property's value.
+ The property's value after the change occurred.
+ The instance to use to compare the input values.
+ If , will also be validated.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+ Thrown if or are .
+
+
+
+ Compares the current and new values for a given property. If the value has changed,
+ raises the event, updates the property with
+ the new value, then raises the event. Similarly to
+ the method, this overload should only be
+ used when can't be used directly.
+
+ The type of the property that changed.
+ The current property value.
+ The property's value after the change occurred.
+ A callback to invoke to update the property value.
+ If , will also be validated.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+
+ This method is just like , just with the addition
+ of the parameter. As such, following the behavior of the base method,
+ the and events
+ are not raised if the current and new value for the target property are the same.
+
+ Thrown if or are .
+
+
+
+ Compares the current and new values for a given property. If the value has changed,
+ raises the event, updates the property with
+ the new value, then raises the event.
+ See additional notes about this overload in .
+
+ The type of the property that changed.
+ The current property value.
+ The property's value after the change occurred.
+ The instance to use to compare the input values.
+ A callback to invoke to update the property value.
+ If , will also be validated.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+ Thrown if , or are .
+
+
+
+ Compares the current and new values for a given nested property. If the value has changed,
+ raises the event, updates the property and then raises the
+ event. The behavior mirrors that of
+ , with the difference being that this
+ method is used to relay properties from a wrapped model in the current instance. For more info, see the docs for
+ .
+
+ The type of model whose property (or field) to set.
+ The type of property (or field) to set.
+ The current property value.
+ The property's value after the change occurred.
+ The model
+ The callback to invoke to set the target property value, if a change has occurred.
+ If , will also be validated.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+ Thrown if , or are .
+
+
+
+ Compares the current and new values for a given nested property. If the value has changed,
+ raises the event, updates the property and then raises the
+ event. The behavior mirrors that of
+ ,
+ with the difference being that this method is used to relay properties from a wrapped model in the
+ current instance. For more info, see the docs for
+ .
+
+ The type of model whose property (or field) to set.
+ The type of property (or field) to set.
+ The current property value.
+ The property's value after the change occurred.
+ The instance to use to compare the input values.
+ The model
+ The callback to invoke to set the target property value, if a change has occurred.
+ If , will also be validated.
+ (optional) The name of the property that changed.
+ if the property was changed, otherwise.
+ Thrown if , , or are .
+
+
+
+ Tries to validate a new value for a specified property. If the validation is successful,
+ is called, otherwise no state change is performed.
+
+ The type of the property that changed.
+ The field storing the property's value.
+ The property's value after the change occurred.
+ The resulting validation errors, if any.
+ (optional) The name of the property that changed.
+ Whether the validation was successful and the property value changed as well.
+ Thrown if is .
+
+
+
+ Tries to validate a new value for a specified property. If the validation is successful,
+ is called, otherwise no state change is performed.
+
+ The type of the property that changed.
+ The field storing the property's value.
+ The property's value after the change occurred.
+ The instance to use to compare the input values.
+ The resulting validation errors, if any.
+ (optional) The name of the property that changed.
+ Whether the validation was successful and the property value changed as well.
+ Thrown if or are .
+
+
+
+ Tries to validate a new value for a specified property. If the validation is successful,
+ is called, otherwise no state change is performed.
+
+ The type of the property that changed.
+ The current property value.
+ The property's value after the change occurred.
+ A callback to invoke to update the property value.
+ The resulting validation errors, if any.
+ (optional) The name of the property that changed.
+ Whether the validation was successful and the property value changed as well.
+ Thrown if or are .
+
+
+
+ Tries to validate a new value for a specified property. If the validation is successful,
+ is called, otherwise no state change is performed.
+
+ The type of the property that changed.
+ The current property value.
+ The property's value after the change occurred.
+ The instance to use to compare the input values.
+ A callback to invoke to update the property value.
+ The resulting validation errors, if any.
+ (optional) The name of the property that changed.
+ Whether the validation was successful and the property value changed as well.
+ Thrown if , or are .
+
+
+
+ Tries to validate a new value for a specified property. If the validation is successful,
+ is called, otherwise no state change is performed.
+
+ The type of model whose property (or field) to set.
+ The type of property (or field) to set.
+ The current property value.
+ The property's value after the change occurred.
+ The model
+ The callback to invoke to set the target property value, if a change has occurred.
+ The resulting validation errors, if any.
+ (optional) The name of the property that changed.
+ Whether the validation was successful and the property value changed as well.
+ Thrown if , or are .
+
+
+
+ Tries to validate a new value for a specified property. If the validation is successful,
+ is called, otherwise no state change is performed.
+
+ The type of model whose property (or field) to set.
+ The type of property (or field) to set.
+ The current property value.
+ The property's value after the change occurred.
+ The instance to use to compare the input values.
+ The model
+ The callback to invoke to set the target property value, if a change has occurred.
+ The resulting validation errors, if any.
+ (optional) The name of the property that changed.
+ Whether the validation was successful and the property value changed as well.
+ Thrown if , , or are .
+
+
+
+ Clears the validation errors for a specified property or for the entire entity.
+
+
+ The name of the property to clear validation errors for.
+ If a or empty name is used, all entity-level errors will be cleared.
+
+
+
+
+
+
+
+
+
+
+ Validates all the properties in the current instance and updates all the tracked errors.
+ If any changes are detected, the event will be raised.
+
+
+ Only public instance properties (excluding custom indexers) that have at least one
+ applied to them will be validated. All other
+ members in the current instance will be ignored. None of the processed properties
+ will be modified - they will only be used to retrieve their values and validate them.
+
+
+
+
+ Validates a property with a specified name and a given input value.
+ If any changes are detected, the event will be raised.
+
+ The value to test for the specified property.
+ The name of the property to validate.
+ Thrown when is .
+
+
+
+ Tries to validate a property with a specified name and a given input value, and returns
+ the computed errors, if any. If the property is valid, it is assumed that its value is
+ about to be set in the current object. Otherwise, no observable local state is modified.
+
+ The value to test for the specified property.
+ The name of the property to validate.
+ The resulting validation errors, if any.
+
+
+
+ Clears all the current errors for the entire entity.
+
+
+
+
+ Clears all the current errors for a target property.
+
+ The name of the property to clear errors for.
+
+
+
+ Gets the display name for a given property. It could be a custom name or just the property name.
+
+ The target property name being validated.
+ The display name for the property.
+
+
+
+ An internal helper to support the source generator APIs related to .
+ This type is not intended to be used directly by user code.
+
+
+
+
+ Invokes externally on a target instance.
+
+ The target instance.
+ The value to test for the specified property.
+ The name of the property to validate.
+
+
+
+ An internal helper used to support and generated code from its template.
+ This type is not intended to be used directly by user code.
+
+
+
+
+ Gets an awaitable object that skips end validation.
+
+ The input to get the awaitable for.
+ A object wrapping .
+
+
+
+ A custom task awaitable object that skips end validation.
+
+
+
+
+ The wrapped instance to create an awaiter for.
+
+
+
+
+ Creates a new instance with the specified parameters.
+
+ The wrapped instance to create an awaiter for.
+
+
+
+ Gets an instance for the current underlying task.
+
+ An instance for the current underlying task.
+
+
+
+ An awaiter object for .
+
+
+
+
+ The underlying instance.
+
+
+
+
+ Creates a new instance with the specified parameters.
+
+ The wrapped instance to create an awaiter for.
+
+
+
+ Gets whether the operation has completed or not.
+
+ This property is intended for compiler user rather than use directly in code.
+
+
+
+ Ends the await operation.
+
+ This method is intended for compiler user rather than use directly in code.
+
+
+
+
+
+
+
+
+
+ A type that facilitates the use of the type.
+ The provides the ability to configure services in a singleton, thread-safe
+ service provider instance, which can then be used to resolve service instances.
+ The first step to use this feature is to declare some services, for instance:
+
+ public interface ILogger
+ {
+ void Log(string text);
+ }
+
+
+ public class ConsoleLogger : ILogger
+ {
+ void Log(string text) => Console.WriteLine(text);
+ }
+
+ Then the services configuration should then be done at startup, by calling the
+ method and passing an instance with the services to use. That instance can
+ be from any library offering dependency injection functionality, such as Microsoft.Extensions.DependencyInjection.
+ For instance, using that library, can be used as follows in this example:
+
+ Ioc.Default.ConfigureServices(
+ new ServiceCollection()
+ .AddSingleton<ILogger, Logger>()
+ .BuildServiceProvider());
+
+ Finally, you can use the instance (which implements )
+ to retrieve the service instances from anywhere in your application, by doing as follows:
+
+ Ioc.Default.GetService<ILogger>().Log("Hello world!");
+
+
+
+
+
+ Gets the default instance.
+
+
+
+
+ The instance to use, if initialized.
+
+
+
+
+
+
+
+ Tries to resolve an instance of a specified service type.
+
+ The type of service to resolve.
+ An instance of the specified service, or .
+ Thrown if the current instance has not been initialized.
+
+
+
+ Resolves an instance of a specified service type.
+
+ The type of service to resolve.
+ An instance of the specified service, or .
+
+ Thrown if the current instance has not been initialized, or if the
+ requested service type was not registered in the service provider currently in use.
+
+
+
+
+ Initializes the shared instance.
+
+ The input instance to use.
+ Thrown if is .
+
+
+
+ Throws an when the property is used before initialization.
+
+
+
+
+ Throws an when the property is missing a type registration.
+
+
+
+
+ Throws an when a configuration is attempted more than once.
+
+
+
+
+ A command that mirrors the functionality of , with the addition of
+ accepting a returning a as the execute
+ action, and providing an property that notifies changes when
+ is invoked and when the returned completes.
+
+
+
+
+ The cached for .
+
+
+
+
+ The cached for .
+
+
+
+
+ The cached for .
+
+
+
+
+ The cached for .
+
+
+
+
+ The to invoke when is used.
+
+
+
+
+ The cancelable to invoke when is used.
+
+ Only one between this and is not .
+
+
+
+ The optional action to invoke when is used.
+
+
+
+
+ The options being set for the current command.
+
+
+
+
+ The instance to use to cancel .
+
+ This is only used when is not .
+
+
+
+
+
+
+
+
+
+ Initializes a new instance of the class.
+
+ The execution logic.
+ Thrown if is .
+
+
+
+ Initializes a new instance of the class.
+
+ The execution logic.
+ The options to use to configure the async command.
+ Thrown if is .
+
+
+
+ Initializes a new instance of the class.
+
+ The cancelable execution logic.
+ Thrown if is .
+
+
+
+ Initializes a new instance of the class.
+
+ The cancelable execution logic.
+ The options to use to configure the async command.
+ Thrown if is .
+
+
+
+ Initializes a new instance of the class.
+
+ The execution logic.
+ The execution status logic.
+ Thrown if or are .
+
+
+
+ Initializes a new instance of the class.
+
+ The execution logic.
+ The execution status logic.
+ The options to use to configure the async command.
+ Thrown if or are .
+
+
+
+ Initializes a new instance of the class.
+
+ The cancelable execution logic.
+ The execution status logic.
+ Thrown if or are .
+
+
+
+ Initializes a new instance of the class.
+
+ The cancelable execution logic.
+ The execution status logic.
+ The options to use to configure the async command.
+ Thrown if or are .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Awaits an input and throws an exception on the calling context, if the task fails.
+
+ The input instance to await.
+
+
+
+ Options to customize the behavior of and instances.
+
+
+
+
+ No option is specified. The and types will use their default behavior:
+
+ Concurrent execution is disallowed: a command is disabled if there is a pending asynchronous execution running.
+
+
+ Exceptions are thrown on the calling context: calling will await the
+ returned for the operation, and propagate the exception on the calling context.
+
+ This behavior is consistent with synchronous commands, where exceptions in behave the same.
+
+
+
+
+
+
+ Concurrent executions are allowed. This option makes it so that the same command can be invoked concurrently multiple times.
+
+ Note that additional considerations should be taken into account in this case:
+
+ If the command supports cancellation, previous invocations will automatically be canceled if a new one is started.
+ The property will always represent the operation that was started last.
+
+
+
+
+
+
+ Exceptions are not thrown on the calling context, and are propagated to instead.
+
+ This affects how calls to behave. When this option is used, if an operation fails, that exception will not
+ be rethrown on the calling context (as it is not awaited there). Instead, it will flow to .
+
+
+ This option enables more advanced scenarios, where the property can be used to inspect the state of an operation
+ that was queued. That is, even if the operation failed or was canceled, the details of that can be retrieved at a later time by accessing this property.
+
+
+
+
+
+ A generic command that provides a more specific version of .
+
+ The type of parameter being passed as input to the callbacks.
+
+
+
+ The to invoke when is used.
+
+
+
+
+ The cancelable to invoke when is used.
+
+
+
+
+ The optional action to invoke when is used.
+
+
+
+
+ The options being set for the current command.
+
+
+
+
+ The instance to use to cancel .
+
+
+
+
+
+
+
+
+
+
+ Initializes a new instance of the class.
+
+ The execution logic.
+ See notes in .
+ Thrown if is .
+
+
+
+ Initializes a new instance of the class.
+
+ The execution logic.
+ The options to use to configure the async command.
+ See notes in .
+ Thrown if is .
+
+
+
+ Initializes a new instance of the class.
+
+ The cancelable execution logic.
+ See notes in .
+ Thrown if is .
+
+
+
+ Initializes a new instance of the class.
+
+ The cancelable execution logic.
+ The options to use to configure the async command.
+ See notes in .
+ Thrown if is .
+
+
+
+ Initializes a new instance of the class.
+
+ The execution logic.
+ The execution status logic.
+ See notes in .
+ Thrown if or are .
+
+
+
+ Initializes a new instance of the class.
+
+ The execution logic.
+ The execution status logic.
+ The options to use to configure the async command.
+ See notes in .
+ Thrown if or are .
+
+
+
+ Initializes a new instance of the class.
+
+ The cancelable execution logic.
+ The execution status logic.
+ See notes in .
+ Thrown if or are .
+
+
+
+ Initializes a new instance of the class.
+
+ The cancelable execution logic.
+ The execution status logic.
+ The options to use to configure the async command.
+ See notes in .
+ Thrown if or are .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ An attribute that can be used to automatically generate properties from declared methods. When this attribute
+ is used to decorate a method, a generator will create a command property with the corresponding interface
+ depending on the signature of the method. If an invalid method signature is used, the generator will report an error.
+
+ In order to use this attribute, the containing type doesn't need to implement any interfaces. The generated properties will be lazily
+ assigned but their value will never change, so there is no need to support property change notifications or other additional functionality.
+
+
+ This attribute can be used as follows:
+
+ partial class MyViewModel
+ {
+ [RelayCommand]
+ private void GreetUser(User? user)
+ {
+ Console.WriteLine($"Hello {user.Name}!");
+ }
+ }
+
+ And with this, code analogous to this will be generated:
+
+ partial class MyViewModel
+ {
+ private RelayCommand? greetUserCommand;
+
+ public IRelayCommand GreetUserCommand => greetUserCommand ??= new RelayCommand(GreetUser);
+ }
+
+
+
+ The following signatures are supported for annotated methods:
+
+ void Method();
+
+ Will generate an property (using a instance).
+
+ void Method(T?);
+
+ Will generate an property (using a instance).
+
+ Task Method();
+ Task Method(CancellationToken);
+ Task<T> Method();
+ Task<T> Method(CancellationToken);
+
+ Will both generate an property (using an instance).
+
+ Task Method(T?);
+ Task Method(T?, CancellationToken);
+ Task<T> Method(T?);
+ Task<T> Method(T?, CancellationToken);
+
+ Will both generate an property (using an instance).
+
+
+
+
+
+ Gets or sets the name of the property or method that will be invoked to check whether the
+ generated command can be executed at any given time. The referenced member needs to return
+ a value, and has to have a signature compatible with the target command.
+
+
+
+
+ Gets or sets a value indicating whether or not to allow concurrent executions for an asynchronous command.
+
+ When set for an attribute used on a method that would result in an or an
+ property to be generated, this will modify the behavior of these commands
+ when an execution is invoked while a previous one is still running. It is the same as creating an instance of
+ these command types with a constructor such as
+ and using the value.
+
+
+ Using this property is not valid if the target command doesn't map to an asynchronous command.
+
+
+
+ Gets or sets a value indicating whether or not to exceptions should be propagated to .
+
+ When set for an attribute used on a method that would result in an or an
+ property to be generated, this will modify the behavior of these commands
+ in case an exception is thrown by the underlying operation. It is the same as creating an instance of
+ these command types with a constructor such as
+ and using the value.
+
+
+ Using this property is not valid if the target command doesn't map to an asynchronous command.
+
+
+
+ Gets or sets a value indicating whether a cancel command should also be generated for an asynchronous command.
+
+ When set to , this additional code will be generated:
+
+ partial class MyViewModel
+ {
+ private ICommand? loginUserCancelCommand;
+
+ public ICommand LoginUserCancelCommand => loginUserCancelCommand ??= LoginUserCommand.CreateCancelCommand();
+ }
+
+ Where LoginUserCommand is an defined in the class (or generated by this attribute as well).
+
+
+ Using this property is not valid if the target command doesn't map to a cancellable asynchronous command.
+
+
+
+ Extensions for the type.
+
+
+
+
+ Creates an instance that can be used to cancel execution on the input command.
+ The returned command will also notify when it can be executed based on the state of the wrapped command.
+
+ The input instance to create a cancellation command for.
+ An instance that can be used to monitor and signal cancellation for .
+ The returned instance is not guaranteed to be unique across multiple invocations with the same arguments.
+ Thrown if is .
+
+
+
+ An interface expanding to support asynchronous operations.
+
+
+
+
+ Gets the last scheduled , if available.
+ This property notifies a change when the completes.
+
+
+
+
+ Gets a value indicating whether a running operation for this command can currently be canceled.
+
+
+ The exact sequence of events that types implementing this interface should raise is as follows:
+
+
+ The command is initially not running: ,
+ and are .
+
+
+ The command starts running: and switch to
+ . is set to .
+
+
+ If the operation is canceled: switches to
+ and switches to .
+
+
+ The operation completes: and switch
+ to . The state of is undefined.
+
+
+ This only applies if the underlying logic for the command actually supports cancelation. If that is
+ not the case, then and will always remain
+ regardless of the current state of the command.
+
+
+
+
+ Gets a value indicating whether a cancelation request has been issued for the current operation.
+
+
+
+
+ Gets a value indicating whether the command currently has a pending operation being executed.
+
+
+
+
+ Provides a more specific version of ,
+ also returning the representing the async operation being executed.
+
+ The input parameter.
+ The representing the async operation being executed.
+ Thrown if is incompatible with the underlying command implementation.
+
+
+
+ Communicates a request for cancelation.
+
+
+ If the underlying command is not running, or if it does not support cancelation, this method will perform no action.
+ Note that even with a successful cancelation, the completion of the current operation might not be immediate.
+
+
+
+
+ A generic interface representing a more specific version of .
+
+ The type used as argument for the interface methods.
+ This interface is needed to solve the diamond problem with base classes.
+
+
+
+ Provides a strongly-typed variant of .
+
+ The input parameter.
+ The representing the async operation being executed.
+
+
+
+ An interface expanding with the ability to raise
+ the event externally.
+
+
+
+
+ Notifies that the property has changed.
+
+
+
+
+ A generic interface representing a more specific version of .
+
+ The type used as argument for the interface methods.
+
+
+
+ Provides a strongly-typed variant of .
+
+ The input parameter.
+ Whether or not the current command can be executed.
+ Use this overload to avoid boxing, if is a value type.
+
+
+
+ Provides a strongly-typed variant of .
+
+ The input parameter.
+ Use this overload to avoid boxing, if is a value type.
+
+
+
+ A implementation wrapping to support cancellation.
+
+
+
+
+ The wrapped instance.
+
+
+
+
+ Creates a new instance.
+
+ The instance to wrap.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A reusable instance that is always disabled.
+
+
+
+
+
+
+
+ Gets a shared, reusable instance.
+
+
+ This instance can safely be used across multiple objects without having
+ to worry about this static keeping others alive, as the event uses a
+ custom accessor that just discards items (as the event is known to never
+ be raised). As such, this instance will never act as root for other objects.
+
+
+
+
+
+
+
+
+
+
+ An interface for commands that know whether they support cancellation or not.
+
+
+
+
+ Gets whether or not the current command supports cancellation.
+
+
+
+
+ A command whose sole purpose is to relay its functionality to other
+ objects by invoking delegates. The default return value for the
+ method is . This type does not allow you to accept command parameters
+ in the and callback methods.
+
+
+
+
+ The to invoke when is used.
+
+
+
+
+ The optional action to invoke when is used.
+
+
+
+
+
+
+
+ Initializes a new instance of the class that can always execute.
+
+ The execution logic.
+ Thrown if is .
+
+
+
+ Initializes a new instance of the class.
+
+ The execution logic.
+ The execution status logic.
+ Thrown if or are .
+
+
+
+
+
+
+
+
+
+
+
+
+ A generic command whose sole purpose is to relay its functionality to other
+ objects by invoking delegates. The default return value for the CanExecute
+ method is . This class allows you to accept command parameters
+ in the and callback methods.
+
+ The type of parameter being passed as input to the callbacks.
+
+
+
+ The to invoke when is used.
+
+
+
+
+ The optional action to invoke when is used.
+
+
+
+
+
+
+
+ Initializes a new instance of the class that can always execute.
+
+ The execution logic.
+
+ Due to the fact that the interface exposes methods that accept a
+ nullable parameter, it is recommended that if is a reference type,
+ you should always declare it as nullable, and to always perform checks within .
+
+ Thrown if is .
+
+
+
+ Initializes a new instance of the class.
+
+ The execution logic.
+ The execution status logic.
+ See notes in .
+ Thrown if or are .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tries to get a command argument of compatible type from an input .
+
+ The input parameter.
+ The resulting value, if any.
+ Whether or not a compatible command argument could be retrieved.
+
+
+
+ Throws an if an invalid command argument is used.
+
+ The input parameter.
+ Thrown with an error message to give info on the invalid parameter.
+
+
+
+ An interface for a type providing the ability to exchange messages between different objects.
+ This can be useful to decouple different modules of an application without having to keep strong
+ references to types being referenced. It is also possible to send messages to specific channels, uniquely
+ identified by a token, and to have different messengers in different sections of an applications.
+ In order to use the functionalities, first define a message type, like so:
+
+ public sealed class LoginCompletedMessage { }
+
+ Then, register your a recipient for this message:
+
+ Messenger.Default.Register<MyRecipientType, LoginCompletedMessage>(this, (r, m) =>
+ {
+ // Handle the message here...
+ });
+
+ The message handler here is a lambda expression taking two parameters: the recipient and the message.
+ This is done to avoid the allocations for the closures that would've been generated if the expression
+ had captured the current instance. The recipient type parameter is used so that the recipient can be
+ directly accessed within the handler without the need to manually perform type casts. This allows the
+ code to be less verbose and more reliable, as all the checks are done just at build time. If the handler
+ is defined within the same type as the recipient, it is also possible to directly access private members.
+ This allows the message handler to be a static method, which enables the C# compiler to perform a number
+ of additional memory optimizations (such as caching the delegate, avoiding unnecessary memory allocations).
+ Finally, send a message when needed, like so:
+
+ Messenger.Default.Send<LoginCompletedMessage>();
+
+ Additionally, the method group syntax can also be used to specify the message handler
+ to invoke when receiving a message, if a method with the right signature is available
+ in the current scope. This is helpful to keep the registration and handling logic separate.
+ Following up from the previous example, consider a class having this method:
+
+ private static void Receive(MyRecipientType recipient, LoginCompletedMessage message)
+ {
+ // Handle the message there
+ }
+
+ The registration can then be performed in a single line like so:
+
+ Messenger.Default.Register(this, Receive);
+
+ The C# compiler will automatically convert that expression to a instance
+ compatible with .
+ This will also work if multiple overloads of that method are available, each handling a different
+ message type: the C# compiler will automatically pick the right one for the current message type.
+ It is also possible to register message handlers explicitly using the interface.
+ To do so, the recipient just needs to implement the interface and then call the
+ extension, which will automatically register
+ all the handlers that are declared by the recipient type. Registration for individual handlers is supported as well.
+
+
+
+
+ Checks whether or not a given recipient has already been registered for a message.
+
+ The type of message to check for the given recipient.
+ The type of token to check the channel for.
+ The target recipient to check the registration for.
+ The token used to identify the target channel to check.
+ Whether or not has already been registered for the specified message.
+ Thrown if or are .
+
+
+
+ Registers a recipient for a given type of message.
+
+ The type of recipient for the message.
+ The type of message to receive.
+ The type of token to use to pick the messages to receive.
+ The recipient that will receive the messages.
+ A token used to determine the receiving channel to use.
+ The to invoke when a message is received.
+ Thrown if , or are .
+ Thrown when trying to register the same message twice.
+
+
+
+ Unregisters a recipient from all registered messages.
+
+ The recipient to unregister.
+
+ This method will unregister the target recipient across all channels.
+ Use this method as an easy way to lose all references to a target recipient.
+ If the recipient has no registered handler, this method does nothing.
+
+ Thrown if is .
+
+
+
+ Unregisters a recipient from all messages on a specific channel.
+
+ The type of token to identify what channel to unregister from.
+ The recipient to unregister.
+ The token to use to identify which handlers to unregister.
+ If the recipient has no registered handler, this method does nothing.
+ Thrown if or are .
+
+
+
+ Unregisters a recipient from messages of a given type.
+
+ The type of message to stop receiving.
+ The type of token to identify what channel to unregister from.
+ The recipient to unregister.
+ The token to use to identify which handlers to unregister.
+ If the recipient has no registered handler, this method does nothing.
+ Thrown if or are .
+
+
+
+ Sends a message of the specified type to all registered recipients.
+
+ The type of message to send.
+ The type of token to identify what channel to use to send the message.
+ The message to send.
+ The token indicating what channel to use.
+ The message that was sent (ie. ).
+ Thrown if or are .
+
+
+
+ Performs a cleanup on the current messenger.
+ Invoking this method does not unregister any of the currently registered
+ recipient, and it can be used to perform cleanup operations such as
+ trimming the internal data structures of a messenger implementation.
+
+
+
+
+ Resets the instance and unregisters all the existing recipients.
+
+
+
+
+ Extensions for the type.
+
+
+
+
+
+ A class that acts as a container to load the instance linked to
+ the method.
+ This class is needed to avoid forcing the initialization code in the static constructor to run as soon as
+ the type is referenced, even if that is done just to use methods
+ that do not actually require this instance to be available.
+ We're effectively using this type to leverage the lazy loading of static constructors done by the runtime.
+
+
+
+
+ The instance associated with .
+
+
+
+
+ A non-generic version of .
+
+
+
+
+ The instance used to track the preloaded registration action for each recipient.
+
+
+
+
+ A class that acts as a static container to associate a instance to each
+ type in use. This is done because we can only use a single type as key, but we need to track
+ associations of each recipient type also across different communication channels, each identified by a token.
+ Since the token is actually a compile-time parameter, we can use a wrapping class to let the runtime handle a different
+ instance for each generic type instantiation. This lets us only worry about the recipient type being inspected.
+
+ The token indicating what channel to use.
+
+
+
+ The instance used to track the preloaded registration action for each recipient.
+
+
+
+
+ Checks whether or not a given recipient has already been registered for a message.
+
+ The type of message to check for the given recipient.
+ The instance to use to check the registration.
+ The target recipient to check the registration for.
+ Whether or not has already been registered for the specified message.
+ This method will use the default channel to check for the requested registration.
+ Thrown if or are .
+
+
+
+ Registers all declared message handlers for a given recipient, using the default channel.
+
+ The instance to use to register the recipient.
+ The recipient that will receive the messages.
+ See notes for for more info.
+ Thrown if or are .
+
+
+
+ Registers all declared message handlers for a given recipient.
+
+ The type of token to identify what channel to use to receive messages.
+ The instance to use to register the recipient.
+ The recipient that will receive the messages.
+ The token indicating what channel to use.
+
+ This method will register all messages corresponding to the interfaces
+ being implemented by . If none are present, this method will do nothing.
+ Note that unlike all other extensions, this method will use reflection to find the handlers to register.
+ Once the registration is complete though, the performance will be exactly the same as with handlers
+ registered directly through any of the other generic extensions for the interface.
+
+ Thrown if , or are .
+
+
+
+ Registers a recipient for a given type of message.
+
+ The type of message to receive.
+ The instance to use to register the recipient.
+ The recipient that will receive the messages.
+ Thrown when trying to register the same message twice.
+ This method will use the default channel to perform the requested registration.
+ Thrown if or are .
+
+
+
+ Registers a recipient for a given type of message.
+
+ The type of message to receive.
+ The type of token to identify what channel to use to receive messages.
+ The instance to use to register the recipient.
+ The recipient that will receive the messages.
+ The token indicating what channel to use.
+ Thrown when trying to register the same message twice.
+ This method will use the default channel to perform the requested registration.
+ Thrown if , or are .
+
+
+
+ Registers a recipient for a given type of message.
+
+ The type of message to receive.
+ The instance to use to register the recipient.
+ The recipient that will receive the messages.
+ The to invoke when a message is received.
+ Thrown when trying to register the same message twice.
+ This method will use the default channel to perform the requested registration.
+ Thrown if , or are .
+
+
+
+ Registers a recipient for a given type of message.
+
+ The type of recipient for the message.
+ The type of message to receive.
+ The instance to use to register the recipient.
+ The recipient that will receive the messages.
+ The to invoke when a message is received.
+ Thrown when trying to register the same message twice.
+ This method will use the default channel to perform the requested registration.
+ Thrown if , or are .
+
+
+
+ Registers a recipient for a given type of message.
+
+ The type of message to receive.
+ The type of token to use to pick the messages to receive.
+ The instance to use to register the recipient.
+ The recipient that will receive the messages.
+ A token used to determine the receiving channel to use.
+ The to invoke when a message is received.
+ Thrown when trying to register the same message twice.
+ Thrown if , or are .
+
+
+
+ Unregisters a recipient from messages of a given type.
+
+ The type of message to stop receiving.
+ The instance to use to unregister the recipient.
+ The recipient to unregister.
+
+ This method will unregister the target recipient only from the default channel.
+ If the recipient has no registered handler, this method does nothing.
+
+ Thrown if or are .
+
+
+
+ Sends a message of the specified type to all registered recipients.
+
+ The type of message to send.
+ The instance to use to send the message.
+ The message that has been sent.
+
+ This method is a shorthand for when the
+ message type exposes a parameterless constructor: it will automatically create
+ a new instance and send that to its recipients.
+
+ Thrown if is .
+
+
+
+ Sends a message of the specified type to all registered recipients.
+
+ The type of message to send.
+ The instance to use to send the message.
+ The message to send.
+ The message that was sent (ie. ).
+ Thrown if or are .
+
+
+
+ Sends a message of the specified type to all registered recipients.
+
+ The type of message to send.
+ The type of token to identify what channel to use to send the message.
+ The instance to use to send the message.
+ The token indicating what channel to use.
+ The message that has been sen.
+
+ This method will automatically create a new instance
+ just like , and then send it to the right recipients.
+
+ Thrown if or are .
+
+
+
+ Creates an instance that can be used to be notified whenever a message of a given type is broadcast by a messenger.
+
+ The type of message to use to receive notification for through the resulting instance.
+ The instance to use to register the recipient.
+ An instance to receive notifications for messages being broadcast.
+ Thrown if is .
+
+
+
+ Creates an instance that can be used to be notified whenever a message of a given type is broadcast by a messenger.
+
+ The type of message to use to receive notification for through the resulting instance.
+ The type of token to identify what channel to use to receive messages.
+ The instance to use to register the recipient.
+ A token used to determine the receiving channel to use.
+ An instance to receive notifications for messages being broadcast.
+ Thrown if or are .
+
+
+
+ An implementations for a given message type.
+
+ The type of messages to listen to.
+
+
+
+ The instance to use to register the recipient.
+
+
+
+
+ Creates a new instance with the given parameters.
+
+ The instance to use to register the recipient.
+
+
+
+
+
+
+ An implementation for .
+
+
+
+
+ The instance to use to register the recipient.
+
+
+
+
+ The target instance currently in use.
+
+
+
+
+ Creates a new instance with the specified parameters.
+
+ The instance to use to register the recipient.
+ The instance to use to create the recipient for.
+
+
+
+
+
+
+
+
+
+ An implementations for a given pair of message and token types.
+
+ The type of messages to listen to.
+ The type of token to identify what channel to use to receive messages.
+
+
+
+ The instance to use to register the recipient.
+
+
+
+
+ The token used to determine the receiving channel to use.
+
+
+
+
+ Creates a new instance with the given parameters.
+
+ The instance to use to register the recipient.
+ A token used to determine the receiving channel to use.
+
+
+
+
+
+
+ An implementation for .
+
+
+
+
+ The instance to use to register the recipient.
+
+
+
+
+ The target instance currently in use.
+
+
+
+
+ The token used to determine the receiving channel to use.
+
+
+
+
+ Creates a new instance with the specified parameters.
+
+ The instance to use to register the recipient.
+ The instance to use to create the recipient for.
+ A token used to determine the receiving channel to use.
+
+
+
+
+
+
+
+
+
+ A simple buffer writer implementation using pooled arrays.
+
+ The type of items to store in the list.
+
+ This type is a to avoid the object allocation and to
+ enable the pattern-based support. We aren't worried with consumers not
+ using this type correctly since it's private and only accessible within the parent type.
+
+
+
+
+ The default buffer size to use to expand empty arrays.
+
+
+
+
+ The underlying array.
+
+
+
+
+ The span mapping to .
+
+ All writes are done through this to avoid covariance checks.
+
+
+
+ The starting offset within .
+
+
+
+
+ Creates a new instance of the struct.
+
+ A new instance.
+
+
+
+ Gets a with the current items.
+
+
+
+
+ Adds a new item to the current collection.
+
+ The item to add.
+
+
+
+ Resets the underlying array and the stored items.
+
+
+
+
+ Resizes when there is no space left for new items, then adds one
+
+ The item to add.
+
+
+
+
+
+
+ A dispatcher type that invokes a given callback.
+
+
+ This type is used to avoid type aliasing with when the generic
+ arguments are not known. Additionally, this is an abstract class and not an interface so that when
+ is called, virtual dispatch will be used instead of interface
+ stub dispatch, which is much slower and with more indirections.
+
+
+
+
+ Invokes the current callback on a target recipient, with a specified message.
+
+ The target recipient for the message.
+ The message being broadcast.
+
+
+
+ A generic version of .
+
+ The type of recipient for the message.
+ The type of message to receive.
+
+
+
+ The underlying callback to invoke.
+
+
+
+
+ Initializes a new instance of the class.
+
+ The input instance.
+
+
+
+
+
+
+ A simple type representing an immutable pair of types.
+
+
+ This type replaces a simple as it's faster in its
+ and methods, and because
+ unlike a value tuple it exposes its fields as immutable. Additionally, the
+ and fields provide additional clarity reading
+ the code compared to and .
+
+
+
+
+ The type of registered message.
+
+
+
+
+ The type of registration token.
+
+
+
+
+ Initializes a new instance of the struct.
+
+ The type of registered message.
+ The type of registration token.
+
+
+
+
+
+
+
+
+
+
+
+
+ An empty type representing a generic token with no specific value.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ An interface for a recipient that declares a registration for a specific message type.
+
+ The type of message to receive.
+
+
+
+ Receives a given message instance.
+
+ The message being received.
+
+
+
+ A used to represent actions to invoke when a message is received.
+ The recipient is given as an input argument to allow message registrations to avoid creating
+ closures: if an instance method on a recipient needs to be invoked it is possible to just
+ cast the recipient to the right type and then access the local method from that instance.
+
+ The type of recipient for the message.
+ The type of message to receive.
+ The recipient that is receiving the message.
+ The message being received.
+
+
+
+ A for request messages that can receive multiple replies, which can either be used directly or through derived classes.
+
+ The type of request to make.
+
+
+
+ The collection of received replies. We accept both instance, representing already running
+ operations that can be executed in parallel, or instances, which can be used so that multiple
+ asynchronous operations are only started sequentially from and do not overlap in time.
+
+
+
+
+ The instance used to link the token passed to
+ and the one passed to all subscribers to the message.
+
+
+
+
+ Gets the instance that will be linked to the
+ one used to asynchronously enumerate the received responses. This can be used to cancel asynchronous
+ replies that are still being processed, if no new items are needed from this request message.
+ Consider the following example, where we define a message to retrieve the currently opened documents:
+
+ public class OpenDocumentsRequestMessage : AsyncCollectionRequestMessage<XmlDocument> { }
+
+ We can then request and enumerate the results like so:
+
+ await foreach (var document in Messenger.Default.Send<OpenDocumentsRequestMessage>())
+ {
+ // Process each document here...
+ }
+
+ If we also want to control the cancellation of the token passed to each subscriber to the message,
+ we can do so by passing a token we control to the returned message before starting the enumeration
+ ().
+ The previous snippet with this additional change looks as follows:
+
+ await foreach (var document in Messenger.Default.Send<OpenDocumentsRequestMessage>().WithCancellation(cts.Token))
+ {
+ // Process each document here...
+ }
+
+ When no more new items are needed (or for any other reason depending on the situation), the token
+ passed to the enumerator can be canceled (by calling ),
+ and that will also notify the remaining tasks in the request message. The token exposed by the message
+ itself will automatically be linked and canceled with the one passed to the enumerator.
+
+
+
+
+ Replies to the current request message.
+
+ The response to use to reply to the request message.
+
+
+
+ Replies to the current request message.
+
+ The response to use to reply to the request message.
+ Thrown if is .
+
+
+
+ Replies to the current request message.
+
+ The response to use to reply to the request message.
+ Thrown if is .
+
+
+
+ Gets the collection of received response items.
+
+ A value to stop the operation.
+ The collection of received response items.
+
+
+
+
+
+
+ A for async request messages, which can either be used directly or through derived classes.
+
+ The type of request to make.
+
+
+
+ Gets the message response.
+
+ Thrown when is .
+
+
+
+ Gets a value indicating whether a response has already been assigned to this instance.
+
+
+
+
+ Replies to the current request message.
+
+ The response to use to reply to the request message.
+ Thrown if has already been set.
+
+
+
+ Replies to the current request message.
+
+ The response to use to reply to the request message.
+ Thrown if is .
+ Thrown if has already been set.
+
+
+
+
+
+
+ Throws an when a response is not available.
+
+
+
+
+ Throws an when or are called twice.
+
+
+
+
+ A for request messages that can receive multiple replies, which can either be used directly or through derived classes.
+
+ The type of request to make.
+
+
+
+ Gets the message responses.
+
+
+
+
+ Replies to the current request message.
+
+ The response to use to reply to the request message.
+
+
+
+
+
+
+
+
+
+ A message used to broadcast property changes in observable objects.
+
+ The type of the property to broadcast the change for.
+
+
+
+ Initializes a new instance of the class.
+
+ The original sender of the broadcast message.
+ The name of the property that changed.
+ The value that the property had before the change.
+ The value that the property has after the change.
+ Thrown if is .
+
+
+
+ Gets the original sender of the broadcast message.
+
+
+
+
+ Gets the name of the property that changed.
+
+
+
+
+ Gets the value that the property had before the change.
+
+
+
+
+ Gets the value that the property has after the change.
+
+
+
+
+ A for request messages, which can either be used directly or through derived classes.
+
+ The type of request to make.
+
+
+
+ Gets the message response.
+
+ Thrown when is .
+
+
+
+ Gets a value indicating whether a response has already been assigned to this instance.
+
+
+
+
+ Replies to the current request message.
+
+ The response to use to reply to the request message.
+ Thrown if has already been set.
+
+
+
+ Implicitly gets the response from a given instance.
+
+ The input instance.
+ Thrown if is .
+ Thrown when is .
+
+
+
+ Throws an when a response is not available.
+
+
+
+
+ Throws an when is called twice.
+
+
+
+
+ A base message that signals whenever a specific value has changed.
+
+ The type of value that has changed.
+
+
+
+ Initializes a new instance of the class.
+
+ The value that has changed.
+
+
+
+ Gets the value that has changed.
+
+
+
+
+ A class providing a reference implementation for the interface.
+
+
+ This implementation uses strong references to track the registered
+ recipients, so it is necessary to manually unregister them when they're no longer needed.
+
+
+
+
+ The collection of currently registered recipients, with a link to their linked message receivers.
+
+
+ This collection is used to allow reflection-free access to all the existing
+ registered recipients from and other methods in this type,
+ so that all the existing handlers can be removed without having to dynamically create
+ the generic types for the containers of the various dictionaries mapping the handlers.
+
+
+
+
+ The and instance for types combination.
+
+
+ The values are just of type as we don't know the type parameters in advance.
+ Each method relies on to get the type-safe instance of the
+ or class for each pair of generic arguments in use.
+
+
+
+
+ Gets the default instance.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Registers a recipient for a given type of message.
+
+ The type of message to receive.
+ The type of token to use to pick the messages to receive.
+ The recipient that will receive the messages.
+ A token used to determine the receiving channel to use.
+ The input instance to register, or null.
+ Thrown when trying to register the same message twice.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tries to get the instance of currently
+ registered recipients for the input type.
+
+ The type of message to send.
+ The resulting instance, if found.
+ Whether or not the required instance was found.
+
+
+
+ Tries to get the instance of currently registered recipients
+ for the combination of types and .
+
+ The type of message to send.
+ The type of token to identify what channel to use to send the message.
+ The resulting instance, if found.
+ Whether or not the required instance was found.
+
+
+
+ Gets the instance of currently
+ registered recipients for the input type.
+
+ The type of message to send.
+ A instance with the requested type arguments.
+
+
+
+ Gets the instance of currently registered recipients
+ for the combination of types and .
+
+ The type of message to send.
+ The type of token to identify what channel to use to send the message.
+ A instance with the requested type arguments.
+
+
+
+ A mapping type representing a link to recipients and their view of handlers per communication channel.
+
+
+ This type is a specialization of for tokens.
+
+
+
+
+ Initializes a new instance of the class.
+
+ The message type being used.
+
+
+
+ Creates a new instance of the class.
+
+ The type of message to receive.
+ A new instance.
+
+
+
+
+
+
+ A mapping type representing a link to recipients and their view of handlers per communication channel.
+
+ The type of token to use to pick the messages to receive.
+
+ This type is defined for simplicity and as a workaround for the lack of support for using type aliases
+ over open generic types in C# (using type aliases can only be used for concrete, closed types).
+
+
+
+
+ Initializes a new instance of the class.
+
+ The message type being used.
+
+
+
+ Creates a new instance of the class.
+
+ The type of message to receive.
+ A new instance.
+
+
+
+
+
+
+ An interface for the and types which allows to retrieve
+ the type arguments from a given generic instance without having any prior knowledge about those arguments.
+
+
+
+
+ Gets the instance representing the current type arguments.
+
+
+
+
+ A simple type representing a recipient.
+
+
+ This type is used to enable fast indexing in each mapping dictionary,
+ since it acts as an external override for the and
+ methods for arbitrary objects, removing both
+ the virtual call and preventing instances overriding those methods in this context.
+ Using this type guarantees that all the equality operations are always only done
+ based on reference equality for each registered recipient, regardless of its type.
+
+
+
+
+ The registered recipient.
+
+
+
+
+ Initializes a new instance of the struct.
+
+ The target recipient instance.
+
+
+
+
+
+
+
+
+
+
+
+
+ Throws an when trying to add a duplicate handler.
+
+
+
+
+ A class providing a reference implementation for the interface.
+
+
+
+ This implementation uses weak references to track the registered
+ recipients, so it is not necessary to manually unregister them when they're no longer needed.
+
+
+ The type will automatically perform internal trimming when
+ full GC collections are invoked, so calling manually is not necessary to
+ ensure that on average the internal data structures are as trimmed and compact as possible.
+
+
+
+
+
+ The map of currently registered recipients for all message types.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+ Gets the default instance.
+
+
+
+
+
+
+
+
+
+
+ Registers a recipient for a given type of message.
+
+ The type of message to receive.
+ The type of token to use to pick the messages to receive.
+ The recipient that will receive the messages.
+ A token used to determine the receiving channel to use.
+ Thrown when trying to register the same message twice.
+
+ This method is a variation of
+ that is specialized for recipients implementing . See more comments at the top of this type, as well as
+ within and in the types.
+
+
+
+
+ Registers a recipient for a given type of message.
+
+ The type of message to receive.
+ The type of token to use to pick the messages to receive.
+ The recipient that will receive the messages.
+ A token used to determine the receiving channel to use.
+ The input instance to register, or null.
+ Thrown when trying to register the same message twice.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Implements the broadcasting logic for .
+
+
+
+
+
+
+ This method is not a local function to avoid triggering multiple compilations due to TToken
+ potentially being a value type, which results in specialized code due to reified generics. This is
+ necessary to work around a Roslyn limitation that causes unnecessary type parameters in local
+ functions not to be discarded in the synthesized methods. Additionally, keeping this loop outside
+ of the EH block (the block) can help result in slightly better codegen.
+
+
+
+
+
+
+
+
+
+
+ Executes a cleanup without locking the current instance. This method has to be
+ invoked when a lock on has already been acquired.
+
+
+
+
+ Executes a cleanup without locking the current instance. This method has to be
+ invoked when a lock on has already been acquired.
+
+
+
+
+ Throws an when trying to add a duplicate handler.
+
+
+
+
+ A container for all shared configuration switches for the MVVM Toolkit.
+
+
+
+ This type uses a very specific setup for configuration switches to ensure ILLink can work the best.
+ This mirrors the architecture of feature switches in the runtime as well, and it's needed so that
+ no static constructor is generated for the type.
+
+
+ For more info, see .
+
+
+
+
+
+ The configuration property name for .
+
+
+
+
+ The backing field for .
+
+
+
+
+ Gets a value indicating whether or not support for should be enabled (defaults to ).
+
+
+
+
+ Gets a configuration value for a specified property.
+
+ The property name to retrieve the value for.
+ The cached result for the target configuration value.
+ The default value for the feature switch, if not set.
+ The value of the specified configuration setting.
+
+
+
+ Internal polyfill for .
+
+
+
+
+ Throws an if is .
+
+ The reference type argument to validate as non-.
+ The name of the parameter with which corresponds.
+
+
+
+ A specialized version for generic values.
+
+ The type of values to check.
+
+ This type is needed because if there had been a generic overload with a generic parameter, all calls
+ would have just been bound by that by the compiler instead of the overload.
+
+
+
+
+ Throws an if is .
+
+ The reference type argument to validate as non-.
+ The name of the parameter with which corresponds.
+
+
+
+ Throws an .
+
+ The name of the parameter that failed validation.
+
+
+
+ A specialized implementation to be used with messenger types.
+
+ The type of keys in the dictionary.
+ The type of values in the dictionary.
+
+
+
+ The index indicating the start of a free linked list.
+
+
+
+
+ The array of 1-based indices for the items stored in .
+
+
+
+
+ The array of currently stored key-value pairs (ie. the lists for each hash group).
+
+
+
+
+ A coefficient used to speed up retrieving the target bucket when doing lookups.
+
+
+
+
+ The current number of items stored in the map.
+
+
+
+
+ The 1-based index for the start of the free list within .
+
+
+
+
+ The total number of empty items.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Checks whether or not the dictionary contains a pair with a specified key.
+
+ The key to look for.
+ Whether or not the key was present in the dictionary.
+
+
+
+ Gets the value if present for the specified key.
+
+ The key to look for.
+ The value found, otherwise .
+ Whether or not the key was present.
+
+
+
+
+
+
+ Gets the value for the specified key, or, if the key is not present,
+ adds an entry and returns the value by ref. This makes it possible to
+ add or update a value in a single look up operation.
+
+ Key to look for.
+ Reference to the new or existing value.
+
+
+
+
+
+
+ Enumerator for .
+
+
+
+
+ The entries being enumerated.
+
+
+
+
+ The current enumeration index.
+
+
+
+
+ The current dictionary count.
+
+
+
+
+ Creates a new instance.
+
+ The input dictionary to enumerate.
+
+
+
+
+
+
+ Gets the current key.
+
+
+
+
+ Gets the current value.
+
+
+
+
+ Gets the value for the specified key, or.
+
+ Key to look for.
+ Reference to the existing value.
+
+
+
+ Initializes the current instance.
+
+ The target capacity.
+
+
+
+
+ Resizes the current dictionary to reduce the number of collisions
+
+
+
+
+ Gets a reference to a target bucket from an input hashcode.
+
+ The input hashcode.
+ A reference to the target bucket.
+
+
+
+ A type representing a map entry, ie. a node in a given list.
+
+
+
+
+ The cached hashcode for ;
+
+
+
+
+ 0-based index of next entry in chain: -1 means end of chain
+ also encodes whether this entry this.itself_ is part of the free list by changing sign and subtracting 3,
+ so -2 means end of free list, -3 means index 0 but on free list, -4 means index 1 but on free list, etc.
+
+
+
+
+ The key for the value in the current node.
+
+
+
+
+ The value in the current node, if present.
+
+
+
+
+ Throws an when trying to load an element with a missing key.
+
+
+
+
+ A helper class for .
+
+
+
+
+ Maximum prime smaller than the maximum array length.
+
+
+
+
+ An arbitrary prime factor used in .
+
+
+
+
+ Table of prime numbers to use as hash table sizes.
+
+
+
+
+ Checks whether a value is a prime.
+
+ The value to check.
+ Whether or not is a prime.
+
+
+
+ Gets the smallest prime bigger than a specified value.
+
+ The target minimum value.
+ The new prime that was found.
+
+
+
+ Returns size of hashtable to grow to.
+
+ The previous table size.
+ The expanded table size.
+
+
+
+ Returns approximate reciprocal of the divisor: ceil(2**64 / divisor).
+
+ This should only be used on 64-bit.
+
+
+
+ Performs a mod operation using the multiplier pre-computed with .
+
+ This should only be used on 64-bit.
+
+
+
+ A base interface masking instances and exposing non-generic functionalities.
+
+
+
+
+ Gets the count of entries in the dictionary.
+
+
+
+
+ Clears the current dictionary.
+
+
+
+
+ An interface providing key type contravariant and value type covariant access
+ to a instance.
+
+ The contravariant type of keys in the dictionary.
+ The covariant type of values in the dictionary.
+
+
+
+ Gets the value with the specified key.
+
+ The key to look for.
+ The returned value.
+ Thrown if the key wasn't present.
+
+
+
+ An interface providing key type contravariant access to a instance.
+
+ The contravariant type of keys in the dictionary.
+
+
+
+ Tries to remove a value with a specified key, if present.
+
+ The key of the value to remove.
+ Whether or not the key was present.
+
+
+
+ Schedules a callback roughly every gen 2 GC (you may see a Gen 0 an Gen 1 but only once).
+ Ported from https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Gen2GcCallback.cs.
+
+
+
+
+ The callback to invoke at each GC.
+
+
+
+
+ A weak to the target object to pass to .
+
+
+
+
+ Initializes a new instance of the class.
+
+ The callback to invoke at each GC.
+ The target object to pass as argument to .
+
+
+
+ Schedules a callback to be called on each GC until the target is collected.
+
+ The callback to invoke at each GC.
+ The target object to pass as argument to .
+
+
+
+ Finalizes an instance of the class.
+ This finalizer is re-registered with as long as
+ the target object is alive, which means it will be executed again every time a generation 2
+ collection is triggered (as the instance itself would be moved to
+ that generation after surviving the generation 0 and 1 collections the first time).
+
+
+
+
+ A custom instance that is specifically optimized to be used
+ by . In particular, it offers zero-allocation enumeration of stored items.
+
+ Tke key of items to store in the table.
+ The values to store in the table.
+
+
+
+ Initial length of the table. Must be a power of two.
+
+
+
+
+ This lock protects all mutation of data in the table. Readers do not take this lock.
+
+
+
+
+ The actual storage for the table; swapped out as the table grows.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+
+
+
+ Tries to add a new pair to the table.
+
+ The key to add.
+ The value to associate with key.
+
+
+
+
+
+
+
+
+
+ Implements the functionality for under a lock.
+
+ The input key.
+ The callback to use to create a new item.
+ The new item to store.
+
+
+
+
+
+
+ Provides an enumerator for the current instance.
+
+
+
+
+ Parent table, set to null when disposed.
+
+
+
+
+ Last index in the container that should be enumerated.
+
+
+
+
+ The current index into the container.
+
+
+
+
+ The current key, if available.
+
+
+
+
+ The current value, if available.
+
+
+
+
+ Initializes a new instance of the class.
+
+ The input instance being enumerated.
+
+
+
+
+
+
+
+
+
+ Gets the current key.
+
+
+
+
+ Gets the current value.
+
+
+
+
+ Worker for adding a new key/value pair. Will resize the container if it is full.
+
+ The key for the new entry.
+ The value for the new entry.
+
+
+
+ A single entry within a instance.
+
+
+
+
+ Holds key and value using a weak reference for the key and a strong reference for the
+ value that is traversed only if the key is reachable without going through the value.
+
+
+
+
+ Cached copy of key's hashcode.
+
+
+
+
+ Index of next entry, -1 if last.
+
+
+
+
+ Container holds the actual data for the table. A given instance of Container always has the same capacity. When we need
+ more capacity, we create a new Container, copy the old one into the new one, and discard the old one. This helps enable
+ lock-free reads from the table, as readers never need to deal with motion of entries due to rehashing.
+
+
+
+
+ The with which this container is associated.
+
+
+
+
+ buckets[hashcode & (buckets.Length - 1)] contains index of the first entry in bucket (-1 if empty).
+
+
+
+
+ The table entries containing the stored dependency handles
+
+
+
+
+ firstFreeEntry < entries.Length => table has capacity, entries grow from the bottom of the table.
+
+
+
+
+ Flag detects if OOM or other background exception threw us out of the lock.
+
+
+
+
+ Set to true when initially finalized
+
+
+
+
+ Used to ensure the next allocated container isn't finalized until this one is GC'd.
+
+
+
+
+ Initializes a new instance of the class.
+
+ The input object associated with the current instance.
+
+
+
+ Initializes a new instance of the class.
+
+ The input object associated with the current instance.
+ The array of buckets.
+ The array of entries.
+ The index of the first free entry.
+
+
+
+ Gets the capacity of the current container.
+
+
+
+
+ Gets the index of the first free entry.
+
+
+
+
+ Worker for adding a new key/value pair. Container must NOT be full.
+
+
+
+
+ Worker for finding a key/value pair. Must hold lock.
+
+
+
+
+ Returns -1 if not found (if key expires during FindEntry, this can be treated as "not found.").
+ Must hold lock, or be prepared to retry the search while holding lock.
+
+ This method requires to be on the stack to be properly tracked.
+
+
+
+ Gets the entry at the specified entry index.
+
+
+
+
+ Removes the specified key from the table, if it exists.
+
+
+
+
+ Removes a given entry at a specified index.
+
+ The index of the entry to remove.
+
+
+
+ Resize, and scrub expired keys off bucket lists. Must hold .
+
+
+ is less than entries.Length on exit, that is, the table has at least one free entry.
+
+
+
+
+ Creates a new of a specified size with the current items.
+
+ The new requested size.
+ The new instance with the requested size.
+
+
+
+ Verifies that the current instance is valid.
+
+ Thrown if the current instance is invalid.
+
+
+
+ Finalizes the current instance.
+
+
+
+
diff --git a/_dist/nextcloud/DynamicData.dll b/_dist/nextcloud/DynamicData.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/ExCSS.dll b/_dist/nextcloud/ExCSS.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Fizzler.dll b/_dist/nextcloud/Fizzler.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/HtmlAgilityPack.dll b/_dist/nextcloud/HtmlAgilityPack.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Markdown.Avalonia.Full.dll b/_dist/nextcloud/Markdown.Avalonia.Full.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Markdown.Avalonia.Html.dll b/_dist/nextcloud/Markdown.Avalonia.Html.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Markdown.Avalonia.Svg.dll b/_dist/nextcloud/Markdown.Avalonia.Svg.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Markdown.Avalonia.SyntaxHigh.dll b/_dist/nextcloud/Markdown.Avalonia.SyntaxHigh.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Markdown.Avalonia.dll b/_dist/nextcloud/Markdown.Avalonia.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/MicroCom.Runtime.dll b/_dist/nextcloud/MicroCom.Runtime.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Newtonsoft.Json.dll b/_dist/nextcloud/Newtonsoft.Json.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Nextcloud.dll b/_dist/nextcloud/Nextcloud.dll
index f5dd0c3..fd446d3 100644
Binary files a/_dist/nextcloud/Nextcloud.dll and b/_dist/nextcloud/Nextcloud.dll differ
diff --git a/_dist/nextcloud/Nextcloud.pdb b/_dist/nextcloud/Nextcloud.pdb
index 1850043..ee4eb6c 100644
Binary files a/_dist/nextcloud/Nextcloud.pdb and b/_dist/nextcloud/Nextcloud.pdb differ
diff --git a/_dist/nextcloud/ReactiveUI.dll b/_dist/nextcloud/ReactiveUI.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/RestSharp.dll b/_dist/nextcloud/RestSharp.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/ShimSkiaSharp.dll b/_dist/nextcloud/ShimSkiaSharp.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Splat.dll b/_dist/nextcloud/Splat.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Svg.Custom.dll b/_dist/nextcloud/Svg.Custom.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/Svg.Model.dll b/_dist/nextcloud/Svg.Model.dll
old mode 100644
new mode 100755
diff --git a/_dist/nextcloud/System.Reactive.dll b/_dist/nextcloud/System.Reactive.dll
old mode 100644
new mode 100755