Skip to content

Instantly share code, notes, and snippets.

@kristijankralj
Last active June 28, 2020 12:38
Show Gist options
  • Save kristijankralj/c876d31b0bbc2730ece4b7565c3a04a5 to your computer and use it in GitHub Desktop.
Save kristijankralj/c876d31b0bbc2730ece4b7565c3a04a5 to your computer and use it in GitHub Desktop.
Snippets for MVVM
using Autofac;
using System;
using System.Reflection;
using Xamarin.Forms;
namespace Navigation
{
public partial class App : Application
{
public App()
{
InitializeComponent();
//class used for registration
var builder = new ContainerBuilder();
//scan and register all classes in the assembly
var dataAccess = Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(dataAccess)
.AsImplementedInterfaces()
.AsSelf();
//register navigation service
NavigationPage navigationPage = null;
Func<INavigation> navigationFunc = () => {
return navigationPage.Navigation;
};
builder.RegisterType<NavigationService>().As<INavigationService>()
.WithParameter("navigation", navigationFunc)
.SingleInstance();
//get container
var container = builder.Build();
//set first page
navigationPage = new NavigationPage(container.Resolve<MainView>());
MainPage = navigationPage;
}
}
}
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace SampleNamespace
{
public abstract class BaseViewModel : BindableObject
{
public virtual Task InitializeAsync(object parameter)
{
return Task.CompletedTask;
}
private bool _isBusy;
public bool IsBusy
{
get => _isBusy;
set
{
if(SetProperty(ref _isBusy, value))
{
IsNotBusy = !_isBusy;
}
}
}
private bool _isNotBusy = true;
public bool IsNotBusy
{
get => _isNotBusy;
set
{
if (SetProperty(ref _isNotBusy, value))
{
IsBusy = !_isNotBusy;
}
}
}
protected bool SetProperty<T>(ref T backingStore, T value,
[CallerMemberName]string propertyName = "",
Action onChanged = null)
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
{
return false;
}
backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
return true;
}
}
}
using System;
using System.IO;
namespace SampleNamespace
{
public static class DatabaseConstants
{
public const string DatabaseFilename = "AppSQLite.db3";
public const SQLite.SQLiteOpenFlags Flags =
// open the database in read/write mode
SQLite.SQLiteOpenFlags.ReadWrite |
// create the database if it doesn't exist
SQLite.SQLiteOpenFlags.Create |
// enable multi-threaded database access
SQLite.SQLiteOpenFlags.SharedCache;
public static string DatabasePath
{
get
{
var basePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
return Path.Combine(basePath, DatabaseFilename);
}
}
}
}
using System.Threading.Tasks;
using Xamarin.Forms;
namespace SampleNamespace
{
public interface IDialogMessage
{
Task DisplayAlert(string title, string message, string cancel);
Task<string> DisplayPrompt(string title, string message);
Task<string> DisplayActionSheet(string title, string destruction, params string[] buttons);
}
public class DialogMessage : IDialogMessage
{
public async Task DisplayAlert(string title, string message, string cancel)
{
await Application.Current.
MainPage.DisplayAlert(title, message, cancel);
}
public Task<string> DisplayPrompt(string title, string message)
{
return Application.Current
.MainPage.DisplayPromptAsync(title, message);
}
public Task<string> DisplayActionSheet(string title, string destruction, params string[] buttons)
{
return Application.Current.MainPage.DisplayActionSheet(title, "Cancel", destruction, buttons);
}
}
}
using Autofac;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace SampleNamespace
{
public interface INavigationService
{
Task PushAsync<TViewModel>(object parameter = null) where TViewModel : BaseViewModel;
Task PopAsync();
}
class NavigationService : INavigationService
{
private Func<INavigation> _navigation;
private IComponentContext _container;
private readonly Dictionary<Type, Type> _pageMap = new Dictionary<Type, Type>
{
// TODO: URL mapping goes here
// { typeof(HistoryViewModel), typeof(HistoryView) },
};
public NavigationService(Func<INavigation> navigation, IComponentContext container)
{
_navigation = navigation;
_container = container;
}
public async Task PopAsync()
{
await _navigation().PopAsync();
}
public async Task PushAsync<TViewModel>(object parameter = null) where TViewModel : BaseViewModel
{
var pageType = _pageMap[typeof(TViewModel)];
Page page = _container.Resolve(pageType) as Page;
await _navigation().PushAsync(page);
await (page.BindingContext as BaseViewModel).InitializeAsync(parameter);
}
}
}
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace SampleNamespace
{
public interface INetworkService
{
Task<TResult> GetAsync<TResult>(string uri);
Task<TResult> PostAsync<TResult>(string uri, string jsonData);
Task<TResult> PutAsync<TResult>(string uri, string jsonData);
Task DeleteAsync(string uri);
}
public class NetworkService : INetworkService
{
private HttpClient _httpClient;
public NetworkService()
{
_httpClient = new HttpClient();
}
public async Task<TResult> GetAsync<TResult>(string uri)
{
HttpResponseMessage response = await _httpClient.GetAsync(uri);
string serialized = await response.Content.ReadAsStringAsync();
TResult result = JsonConvert.DeserializeObject<TResult>(serialized);
return result;
}
public async Task<TResult> PostAsync<TResult>(string uri, string jsonData)
{
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
HttpResponseMessage response = await _httpClient.PostAsync(uri, content);
string serialized = await response.Content.ReadAsStringAsync();
TResult result = JsonConvert.DeserializeObject<TResult>(serialized);
return result;
}
public async Task<TResult> PutAsync<TResult>(string uri, string jsonData)
{
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
HttpResponseMessage response = await _httpClient.PutAsync(uri, content);
string serialized = await response.Content.ReadAsStringAsync();
TResult result = JsonConvert.DeserializeObject<TResult>(serialized);
return result;
}
public async Task DeleteAsync(string uri)
{
await _httpClient.DeleteAsync(uri);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Movies.Common.Extensions;
using SQLite;
namespace SampleNamespace
{
public interface IDatabaseItem
{
int Id { get; set; }
}
public interface IRepository<T> where T: IDatabaseItem, new()
{
Task<T> GetById(int id);
Task<int> DeleteAsync(T item);
Task<List<T>> GetAllAsync();
Task<int> SaveAsync(T item);
}
public class Repository<T> : IRepository<T> where T:IDatabaseItem, new()
{
readonly Lazy<SQLiteAsyncConnection> lazyInitializer = new Lazy<SQLiteAsyncConnection>(() =>
{
return new SQLiteAsyncConnection(DatabaseConstants.DatabasePath, DatabaseConstants.Flags);
});
private SQLiteAsyncConnection Database => lazyInitializer.Value;
public Repository()
{
InitializeAsync().SafeFireAndForget(false);
}
async Task InitializeAsync()
{
if (!Database.TableMappings.Any(m => m.MappedType.Name == typeof(T).Name))
{
await Database.CreateTableAsync(typeof(T)).ConfigureAwait(false);
}
}
public Task<T> GetById(int id)
{
return Database.Table<T>().Where(x => x.Id == id).FirstOrDefaultAsync();
}
public Task<int> DeleteAsync(T item)
{
return Database.DeleteAsync(item);
}
public Task<List<T>> GetAllAsync()
{
return Database.Table<T>().ToListAsync();
}
public Task<int> SaveAsync(T item)
{
if (item.Id != 0)
{
return Database.UpdateAsync(item);
}
else
{
return Database.InsertAsync(item);
}
}
}
}
using System;
using System.Threading.Tasks;
namespace SampleNamespace
{
public static class TaskExtensions
{
// NOTE: Async void is intentional here. This provides a way
// to call an async method from the constructor while
// communicating intent to fire and forget, and allow
// handling of exceptions
public static async void SafeFireAndForget(this Task task,
bool returnToCallingContext,
Action<Exception> onException = null)
{
try
{
await task.ConfigureAwait(returnToCallingContext);
}
// if the provided action is not null, catch and
// pass the thrown exception
catch (Exception ex) when (onException != null)
{
onException(ex);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment