Skip to content
This repository has been archived by the owner on Dec 19, 2022. It is now read-only.

Commit

Permalink
Add More Tools
Browse files Browse the repository at this point in the history
  • Loading branch information
drasticactions committed Jan 2, 2022
1 parent 6d66f56 commit e1d1dab
Show file tree
Hide file tree
Showing 8 changed files with 490 additions and 0 deletions.
109 changes: 109 additions & 0 deletions DrasticMaui/Tools/AsyncCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// <copyright file="AsyncCommand.cs" company="Drastic Actions">
// Copyright (c) Drastic Actions. All rights reserved.
// </copyright>

using System;
using System.Threading.Tasks;
using System.Windows.Input;
using DrasticMaui.Services;
using Microsoft.Maui.Essentials;

namespace DrasticMaui.Tools
{
/// <summary>
/// Async Command.
/// </summary>
public class AsyncCommand : IAsyncCommand
{
private readonly Func<Task>? execute;
private readonly Func<bool>? canExecute;
private readonly IErrorHandlerService? errorHandler;
private bool isExecuting;

/// <summary>
/// Initializes a new instance of the <see cref="AsyncCommand"/> class.
/// </summary>
/// <param name="execute">Command to execute.</param>
/// <param name="canExecute">Can execute command.</param>
/// <param name="errorHandler">Error handler.</param>
public AsyncCommand(
Func<Task> execute,
Func<bool>? canExecute = null,
IErrorHandlerService? errorHandler = null)
{
this.execute = execute;
this.canExecute = canExecute;
this.errorHandler = errorHandler;
}

/// <summary>
/// Can Execute Changed.
/// </summary>
public event EventHandler? CanExecuteChanged;

/// <summary>
/// Gets or sets a value indicating whether the command is executing.
/// </summary>
protected bool IsExecuting
{
get
{
return this.isExecuting;
}

set
{
this.isExecuting = value;
this.RaiseCanExecuteChanged();
}
}

/// <inheritdoc/>
public bool CanExecute()
{
return !this.IsExecuting && (this.canExecute?.Invoke() ?? true);
}

/// <inheritdoc/>
public async Task ExecuteAsync()
{
if (this.CanExecute())
{
if (this.execute is not null)
{
try
{
this.IsExecuting = true;
await this.execute().ConfigureAwait(false);
}
finally
{
this.IsExecuting = false;
}
}
}
}

/// <summary>
/// Raises Can Execute Changed.
/// </summary>
#pragma warning disable CA1030 // Use events where appropriate
public void RaiseCanExecuteChanged()
#pragma warning restore CA1030 // Use events where appropriate
{
Microsoft.Maui.Controls.Application.Current?.Dispatcher.Dispatch(() => this.CanExecuteChanged?.Invoke(this, EventArgs.Empty));
}

/// <inheritdoc/>
bool ICommand.CanExecute(object? parameter)
{
return this.CanExecute();
}

/// <inheritdoc/>
void ICommand.Execute(object? parameter)
{
this.ExecuteAsync().FireAndForgetSafeAsync(this.errorHandler);
}
}
}
110 changes: 110 additions & 0 deletions DrasticMaui/Tools/AsyncCommandT.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// <copyright file="AsyncCommandT.cs" company="Drastic Actions">
// Copyright (c) Drastic Actions. All rights reserved.
// </copyright>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using DrasticMaui.Services;

namespace DrasticMaui.Tools
{
/// <summary>
/// Async Command.
/// </summary>
/// <typeparam name="T">Generic Parameter.</typeparam>
#pragma warning disable SA1649 // File name should match first type name
public class AsyncCommand<T> : IAsyncCommand<T>
#pragma warning restore SA1649 // File name should match first type name
{
private readonly Func<T, Task>? execute;
private readonly Func<T, bool>? canExecute;
private readonly IErrorHandlerService? errorHandler;
private bool isExecuting;

/// <summary>
/// Initializes a new instance of the <see cref="AsyncCommand{T}"/> class.
/// </summary>
/// <param name="execute">Task to Execute.</param>
/// <param name="canExecute">Can Execute Function.</param>
/// <param name="errorHandler">Error Handler.</param>
public AsyncCommand(Func<T, Task>? execute, Func<T, bool>? canExecute = null, IErrorHandlerService? errorHandler = null)
{
this.execute = execute;
this.canExecute = canExecute;
this.errorHandler = errorHandler;
}

/// <summary>
/// Can Execute Event.
/// </summary>
public event EventHandler? CanExecuteChanged;

/// <summary>
/// Returns a value if the given command can be executed.
/// </summary>
/// <param name="parameter">Can Execute Function.</param>
/// <returns>Boolean.</returns>
public bool CanExecute(T parameter)
{
return !this.isExecuting && (this.canExecute?.Invoke(parameter) ?? true);
}

/// <summary>
/// Executes Command Async.
/// </summary>
/// <param name="parameter">Command to be Executed.</param>
/// <returns>Task.</returns>
public async Task ExecuteAsync(T parameter)
{
if (this.CanExecute(parameter))
{
if (this.execute is not null)
{
try
{
this.isExecuting = true;
await this.execute(parameter).ConfigureAwait(false);
}
finally
{
this.isExecuting = false;
}
}
}

this.RaiseCanExecuteChanged();
}

/// <summary>
/// Raise Can Execute Changed.
/// </summary>
public void RaiseCanExecuteChanged()
{
this.CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}

/// <inheritdoc/>
bool ICommand.CanExecute(object? parameter)
{
if (parameter is not null)
{
return this.CanExecute((T)parameter);
}

return false;
}

/// <inheritdoc/>
void ICommand.Execute(object? parameter)
{
if (parameter is not null)
{
this.ExecuteAsync((T)parameter).FireAndForgetSafeAsync(this.errorHandler);
}
}
}
}
37 changes: 37 additions & 0 deletions DrasticMaui/Tools/ExtendedBindableObject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// <copyright file="ExtendedBindableObject.cs" company="Drastic Actions">
// Copyright (c) Drastic Actions. All rights reserved.
// </copyright>

using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Microsoft.Maui.Controls;

namespace DrasticMaui.Tools
{
/// <summary>
/// Extended Bindable Object.
/// </summary>
public class ExtendedBindableObject : BindableObject
{
/// <summary>
/// Set Property.
/// </summary>
/// <typeparam name="T">Generic Type.</typeparam>
/// <param name="backingStore">Backing Store.</param>
/// <param name="value">Value.</param>
/// <param name="propertyName">Property Name.</param>
/// <returns>Boolean.</returns>
protected bool SetProperty<T>(ref T backingStore, T value, [CallerMemberName] string propertyName = "")
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
{
return false;
}

backingStore = value;
this.OnPropertyChanged(propertyName);

return true;
}
}
}
31 changes: 31 additions & 0 deletions DrasticMaui/Tools/IAsyncCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// <copyright file="IAsyncCommand.cs" company="Drastic Actions">
// Copyright (c) Drastic Actions. All rights reserved.
// </copyright>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace DrasticMaui.Tools
{
/// <summary>
/// IAsyncCommand.
/// </summary>
public interface IAsyncCommand : ICommand
{
/// <summary>
/// Execute Async.
/// </summary>
/// <returns><see cref="Task"/>.</returns>
Task ExecuteAsync();

/// <summary>
/// Can execute Command.
/// </summary>
/// <returns>Boolean.</returns>
bool CanExecute();
}
}
36 changes: 36 additions & 0 deletions DrasticMaui/Tools/IAsyncCommandT.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// <copyright file="IAsyncCommandT.cs" company="Drastic Actions">
// Copyright (c) Drastic Actions. All rights reserved.
// </copyright>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace DrasticMaui.Tools
{
/// <summary>
/// IAsyncCommand.
/// </summary>
/// <typeparam name="T">Type of Command.</typeparam>
#pragma warning disable SA1649 // File name should match first type name
public interface IAsyncCommand<T> : ICommand
#pragma warning restore SA1649 // File name should match first type name
{
/// <summary>
/// Execute Async.
/// </summary>
/// <param name="parameter">parameter.</param>
/// <returns><see cref="Task"/>.</returns>
Task ExecuteAsync(T parameter);

/// <summary>
/// Can Execute.
/// </summary>
/// <param name="parameter">parameter.</param>
/// <returns>Bool.</returns>
bool CanExecute(T parameter);
}
}
30 changes: 30 additions & 0 deletions DrasticMaui/Tools/ServiceProviderExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// <copyright file="ServiceProviderExtensions.cs" company="Drastic Actions">
// Copyright (c) Drastic Actions. All rights reserved.
// </copyright>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;

namespace DrasticMaui.Tools
{
/// <summary>
/// Service Provider Extensions.
/// </summary>
public static class ServiceProviderExtensions
{
/// <summary>
/// Resolve With.
/// </summary>
/// <typeparam name="T">T.</typeparam>
/// <param name="provider">Provider.</param>
/// <param name="parameters">Parameters.</param>
/// <returns>T Value.</returns>
public static T ResolveWith<T>(this IServiceProvider provider, params object[] parameters)
where T : class =>
ActivatorUtilities.CreateInstance<T>(provider, parameters);
}
}
Loading

0 comments on commit e1d1dab

Please sign in to comment.