Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions src/ReactiveUI/Activation/CanActivateViewFetcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,27 @@ namespace ReactiveUI;
public class CanActivateViewFetcher : IActivationForViewFetcher
{
/// <summary>
/// Returns a positive integer for derived instances of the <see cref="ICanActivate"/> interface.
/// Determines the affinity score for the specified view type based on whether it implements the ICanActivate
/// interface.
/// </summary>
/// <param name="view">The source type to check.</param>
/// <returns>
/// A positive integer if <see cref="GetActivationForView(IActivatableView)"/> is supported,
/// zero otherwise.
/// </returns>
/// <remarks>Use this method to assess whether a view type is suitable for activation scenarios that
/// require the ICanActivate interface. A higher affinity score indicates a stronger match.</remarks>
/// <param name="view">The type of the view to evaluate for activation capability. Cannot be null.</param>
/// <returns>An integer affinity score: 10 if the view type implements ICanActivate; otherwise, 0.</returns>
public int GetAffinityForView(Type view) =>
typeof(ICanActivate).GetTypeInfo().IsAssignableFrom(view.GetTypeInfo()) ? 10 : 0;

/// <summary>
/// Get an observable defining whether the view is active.
/// Returns an observable sequence that indicates the activation state of the specified view.
/// </summary>
/// <param name="view">The view to observe.</param>
/// <returns>An observable tracking whether the view is active.</returns>
/// <remarks>If the provided view does not implement <see cref="ICanActivate"/>, the returned observable
/// emits <see langword="false"/> and completes immediately. Otherwise, the observable reflects the view's
/// activation and deactivation events as they occur.</remarks>
/// <param name="view">The view for which to observe activation and deactivation events. If the view does not support activation, the
/// observable will emit a single value of <see langword="false"/>.</param>
/// <returns>An observable sequence of <see langword="true"/> and <see langword="false"/> values that reflect the activation
/// and deactivation state of the view. The sequence emits <see langword="true"/> when the view is activated and
/// <see langword="false"/> when it is deactivated.</returns>
public IObservable<bool> GetActivationForView(IActivatableView view) =>
view is not ICanActivate canActivate
? Observable.Return(false)
Expand Down
204 changes: 112 additions & 92 deletions src/ReactiveUI/Activation/ViewForMixins.cs

Large diffs are not rendered by default.

69 changes: 38 additions & 31 deletions src/ReactiveUI/Bindings/BindingTypeConverterDispatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,19 @@ namespace ReactiveUI;
internal static class BindingTypeConverterDispatch
{
/// <summary>
/// Attempts conversion via the converter's type-only metadata (<see cref="IBindingTypeConverter.FromType"/> and
/// <see cref="IBindingTypeConverter.ToType"/>) and object shim (<see cref="IBindingTypeConverter.TryConvertTyped"/>).
/// Attempts to convert a value to the specified target type using the provided binding type converter.
/// </summary>
/// <param name="converter">The converter.</param>
/// <param name="from">The source value.</param>
/// <param name="toType">The target type requested by the caller.</param>
/// <param name="conversionHint">Implementation-defined hint.</param>
/// <param name="result">The converted result.</param>
/// <returns><see langword="true"/> if conversion succeeded; otherwise <see langword="false"/>.</returns>
/// <remarks>The conversion will only be attempted if the converter's ToType matches the specified toType
/// and the runtime type of from matches the converter's FromType (or is compatible with a nullable value type). No
/// exceptions are thrown for conversion failures; instead, the method returns false.</remarks>
/// <param name="converter">The binding type converter to use for the conversion. Cannot be null.</param>
/// <param name="from">The value to convert. May be null if the target type accepts null values.</param>
/// <param name="toType">The target type to convert the value to. Must match the converter's ToType. Cannot be null.</param>
/// <param name="conversionHint">An optional hint object that may influence the conversion process. The meaning of this parameter is determined
/// by the converter implementation.</param>
/// <param name="result">When this method returns, contains the converted value if the conversion succeeded; otherwise, null. This
/// parameter is passed uninitialized.</param>
/// <returns>true if the value was successfully converted; otherwise, false.</returns>
internal static bool TryConvert(
IBindingTypeConverter converter,
object? from,
Expand Down Expand Up @@ -64,15 +68,19 @@ internal static bool TryConvert(
}

/// <summary>
/// Attempts conversion using a fallback converter.
/// Attempts to convert an object to a specified type using the provided fallback converter.
/// </summary>
/// <param name="converter">The fallback converter.</param>
/// <param name="fromType">The source runtime type.</param>
/// <param name="from">The source value (guaranteed non-null by caller).</param>
/// <param name="toType">The target type.</param>
/// <param name="conversionHint">Implementation-defined hint.</param>
/// <param name="result">The converted result.</param>
/// <returns><see langword="true"/> if conversion succeeded; otherwise, <see langword="false"/>.</returns>
/// <remarks>This method delegates the conversion to the specified fallback converter. The result is
/// guaranteed to be non-null only if the conversion succeeds. Callers should check the return value to determine
/// whether the conversion was successful before using the result.</remarks>
/// <param name="converter">The fallback converter to use for the conversion operation. Cannot be null.</param>
/// <param name="fromType">The type of the source object to convert. Used to inform the converter of the input type.</param>
/// <param name="from">The source object to convert. Cannot be null.</param>
/// <param name="toType">The target type to convert the object to. Cannot be null.</param>
/// <param name="conversionHint">An optional hint or context object that may influence the conversion process. May be null.</param>
/// <param name="result">When this method returns, contains the converted object if the conversion succeeded; otherwise, null. This
/// parameter is passed uninitialized.</param>
/// <returns>true if the conversion was successful and the result is non-null; otherwise, false.</returns>
internal static bool TryConvertFallback(
IBindingFallbackConverter converter,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type fromType,
Expand Down Expand Up @@ -103,22 +111,21 @@ internal static bool TryConvertFallback(
}

/// <summary>
/// Unified dispatch method that handles both typed and fallback converters.
/// Attempts to convert an object to a specified target type using the provided converter.
/// </summary>
/// <param name="converter">The converter (either <see cref="IBindingTypeConverter"/> or <see cref="IBindingFallbackConverter"/>).</param>
/// <param name="fromType">The source runtime type.</param>
/// <param name="from">The source value.</param>
/// <param name="toType">The target type.</param>
/// <param name="conversionHint">Implementation-defined hint.</param>
/// <param name="result">The converted result.</param>
/// <returns><see langword="true"/> if conversion succeeded; otherwise, <see langword="false"/>.</returns>
/// <remarks>
/// This method automatically dispatches to the appropriate converter type:
/// <list type="bullet">
/// <item><description><see cref="IBindingTypeConverter"/> - uses exact pair matching</description></item>
/// <item><description><see cref="IBindingFallbackConverter"/> - requires non-null input</description></item>
/// </list>
/// </remarks>
/// <remarks>This method supports both type-based and fallback converters. If the provided converter does
/// not implement a supported interface or is null, the method returns false and result is set to null. The method
/// does not throw exceptions for failed conversions; instead, it returns false to indicate failure.</remarks>
/// <param name="converter">The converter instance to use for the conversion. Must implement either IBindingTypeConverter or
/// IBindingFallbackConverter. If null or of an unsupported type, the conversion will not be performed.</param>
/// <param name="fromType">The type of the source object to convert. Used to determine the appropriate conversion logic.</param>
/// <param name="from">The source object to convert. May be null if the converter supports null values.</param>
/// <param name="toType">The target type to convert the source object to. Cannot be null.</param>
/// <param name="conversionHint">An optional hint or context object that may influence the conversion process. The interpretation of this value
/// depends on the converter implementation.</param>
/// <param name="result">When this method returns, contains the converted value if the conversion succeeded; otherwise, null. This
/// parameter is passed uninitialized.</param>
/// <returns>true if the conversion was successful and result contains the converted value; otherwise, false.</returns>
internal static bool TryConvertAny(
object? converter,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type fromType,
Expand Down
Loading
Loading