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.