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 @@ - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - { - "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.cs 13 - - - - - - + @@ -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.cs 29 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.0 enable true + 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