Skip to content

Instantly share code, notes, and snippets.

@maraf
Created October 17, 2018 13:32
Show Gist options
  • Save maraf/4f4047a7440ad0709099acc525c1a364 to your computer and use it in GitHub Desktop.
Save maraf/4f4047a7440ad0709099acc525c1a364 to your computer and use it in GitHub Desktop.
Blueprint of navigation framework
using Neptuo.Features;
using Neptuo.Navigation;
using Neptuo.Navigation.Awaitable;
using Neptuo.Navigation.Awaitable.Executing;
using Neptuo.Navigation.Closeable;
using Neptuo.Navigation.Executing;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Neptuo
{
namespace Navigation
{
namespace Executing
{
public interface ISerialNavigator
{
void Open(object model);
}
}
public interface INavigator
{
IFeatureProvider Features { get; }
}
public static class NavigatorExtensions
{
public static void Open(this INavigator navigator, object model)
=> navigator.Features.With<ISerialNavigator>().Open(model);
}
}
namespace Navigation.Closeable
{
public interface ICallback
{
event Action Closed;
}
public interface ICallback<T>
{
event Action<T> Closed;
}
public static class NavigationExtensions
{
public static ICallback Callback(this ICallback navigation, Action handler)
{
navigation.Closed += handler;
return navigation;
}
public static ICallback<TResult> Callback<TResult>(this ICallback<TResult> navigation, Action<TResult> handler)
{
navigation.Closed += handler;
return navigation;
}
}
}
namespace Navigation.Awaitable
{
namespace Executing
{
public interface IAsyncNavigator
{
Task OpenAsync(IAsyncResult model);
Task<TResult> OpenAsync<TResult>(IAsyncResult<TResult> model);
}
}
public interface IAsyncResult
{ }
public interface IAsyncResult<T>
{ }
public static class NavigatorExtensions
{
public static Task OpenAsync(this INavigator navigator, IAsyncResult model)
=> navigator.Features.With<IAsyncNavigator>().OpenAsync(model);
public static Task<TResult> OpenAsync<TResult>(this INavigator navigator, IAsyncResult<TResult> model)
=> navigator.Features.With<IAsyncNavigator>().OpenAsync(model);
}
}
namespace Navigation.Wpf
{
internal class Window
{
public event EventHandler Closed;
public void Show()
{ }
}
public interface IAsyncResultContainer<T>
{
T Result { get; }
}
public class NavigationRuleCollection : Dictionary<Type, Type>
{ }
public class Navigator : INavigator, IAsyncNavigator, ISerialNavigator
{
private readonly NavigationRuleCollection rules;
public IFeatureProvider Features { get; }
public Navigator(NavigationRuleCollection rules)
{
Features = new FeatureObject(this);
this.rules = rules;
}
public void Open(object model)
{
Window window = GetWindow(model);
window.Show();
}
private Window GetWindow(object model)
{
if (rules.TryGetValue(model.GetType(), out Type windowType))
return (Window)Activator.CreateInstance(windowType);
throw Ensure.Exception.InvalidOperation("Missing");
}
public Task OpenAsync(Awaitable.IAsyncResult model)
{
TaskCompletionSource<bool> taskCompletion = new TaskCompletionSource<bool>();
Window window = GetWindow(model);
window.Closed += (sender, e) => taskCompletion.SetResult(true);
window.Show();
return taskCompletion.Task;
}
public Task<TResult> OpenAsync<TResult>(IAsyncResult<TResult> model)
{
TaskCompletionSource<TResult> taskCompletion = new TaskCompletionSource<TResult>();
Window window = GetWindow(model);
IAsyncResultContainer<TResult> windowContainer = (IAsyncResultContainer<TResult>)window;
window.Closed += (sender, e) => taskCompletion.SetResult(windowContainer.Result);
window.Show();
return taskCompletion.Task;
}
}
}
class Program
{
public class ProductList
{ }
public class ProductEdit : IAsyncResult<int>
{ }
public class ServiceList : ICallback<List<int>>
{
public event Action<List<int>> Closed;
}
private static async Task TestCase(INavigator navigator)
{
navigator.Open(new ProductList());
navigator.Open(new ServiceList().Callback(OnServiceListClosed));
int newId = await navigator.OpenAsync(new ProductEdit());
}
private static void OnServiceListClosed(List<int> selectedIds)
{
Console.WriteLine(selectedIds);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment