TinyMvvm 2.4.1

Today, I released a new version of TinyMvvm, 2.4.1.

The release contains this:

  • Added ShellViewBase to optimize how ViewModels are created. Before the ViewModel was created during OnAppearing when using Shell navigation. It also ran Initialize during OnAppearing. But there are cases where you want it to run earlier, so I added a new class that you can use to achieve that. You can also pass trueto the constructor of ViewBase to achieve the same thing.

    In XAML and ShellViewBase:

    <mvvm:ShellViewBase
    xmlns:mvvm="clr-namespace:TinyMvvm.Forms;assembly=TinyMvvm.Forms"
    xmlns:vm="clr-namespace:SampleApp.ViewModels"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="SampleApp.Views.MainView" 
    x:TypeArguments="vm:MainViewModel">
    
    </mvvm:ViewBase>

    With a parameter to the constructor of ViewBase:

    public partial class MainView
    {
    public MainView() : base(true)
    }
    <mvvm:ViewBase
    xmlns:mvvm="clr-namespace:TinyMvvm.Forms;assembly=TinyMvvm.Forms"
    xmlns:vm="clr-namespace:SampleApp.ViewModels"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="SampleApp.Views.MainView" 
    x:TypeArguments="vm:MainViewModel">
    
    </mvvm:ViewBase>
  • Removed the need of TinyMvvm.Initialize(); It now marked as obsolete, so it will not break your code. The big win by removing the need for it is that it is easier to get started with TinyMvvm.

  • Refactored so that ViewModelBase implements the new IViewModelBase interface. The ViewBase is refactored so IViewModelBase is used instead of ViewModelBase. This is a request from a developer that uses TinyMvvm and it makes the library more flexible.

Read more

If you want to read more about TinyMvvm, I recommend the Get Started Tutorial, and also these blog posts:

Contribute

The full source code and documentation can be found on GitHub. Feedback and contributions are very welcome.

Improvments to TinyInsights

Today I released TinyInsights 1.1.7 with some improvements.

I have removed so it will not await when sending events to providers anymore. The reason is that it affected one of my apps in a negative way when I was tracking page views in the OnAppearing (when using Xamarin.Forms) method for a view. Also, users experienced navigation to be very slow. When I wrapped the call in Task.Run it worked like a charm again, so now I decided to build-in that behavior into TinyInsight.

The second change I have done is that I had wrapped all calls to external providers in a try/catch statement, except for methods that tracking error. This because that if a call failed it maybe can be tracked if you are using another provider for tracking error than the one that failed.

And I also want to say thank you to JTOne123 for a PR that enables SourceLink.

Contribute

The full source code and documentation for TinyInsights can be found on GitHub. Feedback and contributions are very welcome.

Autofac vs TinyIoC

I recently added a resolver that is powered by TinyIoC to TinyMvvm because I got a request to do so because they said that performance was better. I have used Autofac for many years and I have never had any problems with it. But I decided to replace Autofac with TinyIoC in one app that I am working with right now, just to try to measure the difference.

What I did is that I logged 4 runs of the initializing code of the app for each IoC provider. I used the iOS simulator in debug mode. Here is the result:

Autofac (ms) TinyIoC (ms)
136 16
91 14
83 13
91 14

I was surprised that the difference was so big, we will probably have other numbers when running it in release mode, but I think that this test gives us a pretty good indication of what the performance is. I will definitely continue with TinyIoC in this app and I will also use it for new apps.

TinyIoC for TinyMvvm

There was an issue created for TinyMvvm regarding to use TinyIoC as the IoC-container. I had created an implementation of IResolver for Autofac. But now I decided to create one for TinyIoC too.

The implementation for it can be installed via the NuGet package, TinyMvvm.TinyIoC, https://www.nuget.org/packages/TinyMvvm.TinyIoC.

The code for setting up the container and the Resolver for the Sample project will look like this if you want to use TinyIoC:

TinyIoCContainer.Current.Register<INavigationHelper>(navigationHelper);

foreach (var type in appAssembly.ExportedTypes.Where(x => x.IsSubclassOf(typeof(ViewModelBase))))
{
    TinyIoCContainer.Current.Register(type);
}

foreach (var type in appAssembly.ExportedTypes.Where(x => x.IsSubclassOf(typeof(Page))))
{
    TinyIoCContainer.Current.Register(type);
}

Resolver.SetResolver(new TinyIoCResolver());

Snippets for TinyMvvm

This blog post is a part of the Xamarin Month, a great initiative by Luis Matos. The theme for this Xamarin Month is code snippets. Here is my contribution to the Xamarin Month.

TinyMvvm is a library that I created to make me more productive when I developing apps with Xamarin.Forms.

Snippets

All snippets are available in the repository for TinyMvvm.

TinyCommand (tmcmd)

TinyMvvm has its own implementation of ICommand. You can use Xamarin.Forms Command, but if you use the TinyCommand you don't have to add references to Xamarin.Forms in your ViewModels.

Shortcut: tmcmd

private ICommand? command;
public ICommand Command => command ??= new TinyCommand(async() => {

}

TinyCommand<T> (tmcmdt)

TinyCommand<T> is a generic TinyCommand that is able to handle a parameter.

Shortcut: tmcmdt

private ICommand? command;
public ICommand Command => command ??= new TinyCommand<object>(async(parameter) => {

}

TinyMvvm property (tmprop)

I often use PropertyChanged.Fody so I don't need this snippet, but if you don't use it, this snippet can be very useful.

Shortcut: tmprop

private string propertyName;
public string PropertyName
{
    get => propertyName;
    set => Set(ref propertyName, value);
}

Override Initialize (tminit)

In the ViewModel you can override Initialize if you have ViewModelBase as your base class. It will run when the ViewModel is created.

Shortcut: tminit

public async override Task Initialize()
{
    await base.Initialize();
}

Override OnAppearing (tmapp)

In the ViewModel you can override OnAppearing if you have ViewModelBase as your base class. It will be triggered by when the View is appearing.

Shortcut: tmapp

public async override Task OnAppearing()
{
    await base.OnAppearing();
}

Override OnDisappearing (tmdis)

In the ViewModel you can override OnDisappearing if you have ViewModelBase as your base class. It will be triggered by when the View is disappearing.

Shortcut: tmdis

public async override Task OnDisappearing()
{
    await base.OnDisappearing();
}

IsBusy (IsBusy)

In the ViewModelBase there is a property with the name IsBusy. I use to set it to true when I loading data so I can bind an ActivityIndicator to it. There is also a property with the name IsNotBusy that always will have the opposite value of IsBusy. This snippet can be used to surround your code with IsBusy.

Shortcut: IsBusy

IsBusy = true;
//Your code
IsBusu = false;

Import snippets

For Visual Studio on Windows, snippets are imported with the Code Snippets Manager that you will find in the Tools menu. Read more here, https://docs.microsoft.com/en-us/visualstudio/ide/walkthrough-creating-a-code-snippet?view=vs-2019#import-a-code-snippet

For Visual Studio for Mac, add them in the ~/Library/VisualStudio/8.0/Snippets folder.

Read more

If you want to read more about TinyMvvm, I recommend the Get Started Tutorial, and also these blog posts:

Contribute

The full source code and documentation for TinyMvvm can be found on GitHub. Feedback and contributions are very welcome.

Get started with TinyMvvm

This is a tutorial that will guide you through how to get started building an app using Xamarin.Forms and TinyMvvm.

  1. Create a new project based on the template for a blank Xamarin.Forms app. In this example, the name of the project will be SampleApp. The template will generate one project for shared code and one project per target platform.

  2. Install the following NuGet packages into all projects:

    • TinyMvvm.Forms
    • TinyMvvm.Autofac
  3. Create a new ContentPage XAML in the SampleApp project and give it the name AppShell. And add the following content to it.

    <Shell xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:views="clr-namespace:SampleApp.Views" x:Class="SampleApp.AppShell">
        <TabBar>
            <ShellContent Title="Home" Route="home" >
                <views:MainView />
             </ShellContent>
            <ShellContent Title="About" Route="about">
                <views:AboutView />
             </ShellContent>
        </TabBar>
    </Shell>
  4. Remove the base class in the AppShell.xaml.cs so it will look like this:

    public partial class AppShell
    {
        public AppShell()
        {
            InitializeComponent();
        }
    }
  5. Navigate to App.xaml.cs and set MainPage to AppShell. You can also delete the MainPage.xaml- and MainPage.xaml.cs files.

    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
    
            MainPage = new AppShell();
        }
    }
  6. On the rows before you set MainPage to AppShell write the initialization code for TinyMvvm:

    • Use ShellNavigationHelper and register all views in the current Assembly. This register all views so we can use the class name as the key if we use the classic (non-Shell) navigation or we can use ViewModelNavigation that is powered by the Shell navigation.
    • The sample is using Autofac as it's IoC container, but you can use whatever container you want. The only thing you need to do to use another is to create an implementation of IResolver that uses it. Register all classes that is a subType of Page (Xamarin.Forms) and ViewModelBase (TinyMvvm).
    • Register the container to the Resolver, the Resolver is used internally by TinyMvvm, but you can also use it in your code.
    • The last thing to do is to call the *Initialize method for TinyMvvm.

      public App()
      {
          InitializeComponent();
      
          var navigationHelper = new ShellNavigationHelper();
      
          var currentAssembly = Assembly.GetExecutingAssembly();
          navigationHelper.RegisterViewsInAssembly(currentAssembly);
      
          var containerBuilder = new ContainerBuilder();
      
          containerBuilder.RegisterInstance<INavigationHelper>(navigationHelper);
      
          var appAssembly = typeof(App).GetTypeInfo().Assembly;
          containerBuilder.RegisterAssemblyTypes(appAssembly)
                 .Where(x => x.IsSubclassOf(typeof(Page)));
      
          containerBuilder.RegisterAssemblyTypes(appAssembly)
                 .Where(x => x.IsSubclassOf(typeof(ViewModelBase)));
      
          var container = containerBuilder.Build();
      
          Resolver.SetResolver(new AutofacResolver(container));
      
          TinyMvvm.Forms.TinyMvvm.Initialize();
      
          MainPage = new AppShell();
      }
  7. Create a new folder called ViewModels in the SampleApp project.

  8. Create two classes in the ViewModels folder, MainViewModel and AboutViewModel.

  9. Add ViewModelBase as the base class for MainViewModel and AboutViewModel:

    public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
        }
    }
    public class AboutViewModel : ViewModelBase
    {
        public AboutViewModel()
        {
        }
    }
  10. Edit MainView.xaml and AboutView.xaml to have ViewBase as it's base class. To set BindingContext to the the ViewModel, use the x:TypeArguments for the View.

    <mvvm:ViewBase
    xmlns:mvvm="clr-namespace:TinyMvvm.Forms;assembly=TinyMvvm.Forms"
    xmlns:vm="clr-namespace:SampleApp.ViewModels"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="SampleApp.Views.MainView" 
    x:TypeArguments="vm:MainViewModel">
    
    </mvvm:ViewBase>
    <mvvm:ViewBase
    xmlns:mvvm="clr-namespace:TinyMvvm.Forms;assembly=TinyMvvm.Forms"
    xmlns:vm="clr-namespace:SampleApp.ViewModels"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="SampleApp.Views.AboutView" 
    x:TypeArguments="vm:AboutViewModel">
    
    </mvvm:ViewBase>
  11. Remove the base class from MainView.xaml.cs and AboutView.xaml.cs. Because is it a partial class you don't have to specify it both in the XAML-file and in the code-behind file.

  12. Create a new View, DetailsView, and a new ViewModel, DetailsViewModel as in the same style as above.

  13. In MainViewModel, add the following below. The override of Initialize is running when BindingContext for the view has been set. You can also override OnAppearing to run code when the view will appear and OnDisappearing to run code when the view will disappear. IsBusy can be used to bind an ActivityIndicator to. For Commands, use TinyCommand instead of Xamarin.Forms.Command to keep the ViewModel clean from Xamarin.Forms references. To navigate, use the Navigation property from ViewModelBase. Here you can use the name of a ViewModel as a part of a URL to navigate to a route. With TinyMvvm you can also specify a parameter to pass to the target ViewModel.

    public class MainViewModel : ViewModelBase
    {
        private ObservableCollection<string> names;
        public ObservableCollection<string> Names
        {
            get => names;
            set => Set(ref names, value);
        }
    
        public async override Task Initialize()
        {
            IsBusy = true;            
            await base.Initialize();
    
            Names = new ObservableCollection<string>(new List<string>()
            {
                "Daniel",
                "Ella",
                "Willner"
            });
    
            IsBusy = false;
        }
    
        public override Task OnAppearing()
        {
            return base.OnAppearing();
        }
    
        public override Task OnDisappearing()
        {
            return base.OnDisappearing();
        }
    
        private ICommand details;
        private ICommand Details => details ??= new TinyCommand<string>(async(name) =>
        {
            await Navigation.NavigateToAsync($"{nameof(DetailsViewModel)}?name={name}", DateTimeOffset.Now);
        });
    }
  14. To MainView.xaml add the following code to show the bind a CollectionView to the data in the ViewModel:

     <Grid>
        <ActivityIndicator HorizontalOptions="Center" VerticalOptions="Center" IsRunning="False" IsVisible="{Binding IsBusy}" />
        <CollectionView x:Name="Names" ItemsSource="{Binding Names}" IsVisible="{Binding IsNotBusy}">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <ContentView Padding=" 10">
                        <ContentView.GestureRecognizers>
                            <TapGestureRecognizer Command="{Binding Source={x:Reference Names}, Path=BindingContext.Details}" CommandParameter="{Binding}" />
                        </ContentView.GestureRecognizers>
                        <Label Text="{Binding }" />
                    </ContentView>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </Grid>
  15. Go to DetailsViewModel.cs and add the code below to receive the parameters sent to it. QueryParameters will be a Dictionary<string, string> and contains the query parameters specified in the navigation URL. If you also specified a parameter you can access it via the NavigationParameter property.

    
    public class DetailsViewModel : ViewModelBase
    {
        public async override Task Initialize()
        {
            await base.Initialize();
    
            Name = QueryParameters["name"];
            var dateParameter = (DateTimeOffset)NavigationParameter;
    
            Date = dateParameter.ToString();
        }
    
        private string name;
        public string Name
        {
            get => name;
            set => Set(ref name, value);
        }
    
        private string date;
        public string Date
        {
            get => date;
            set => Set(ref date, value);
        }
    }
  16. In the DetailsView.cs add the following code to show the data passed from MainViewModel:

    <mvvm:ViewBase
        xmlns:mvvm="clr-namespace:TinyMvvm.Forms;assembly=TinyMvvm.Forms"
        xmlns:vm="clr-namespace:SampleApp.ViewModels"
        xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="SampleApp.Views.DetailsView" x:TypeArguments="vm:DetailsViewModel">
        <StackLayout Padding="10">
            <Label Text="{Binding Name}" />
            <Label Text="{Binding Date}" />
        </StackLayout>
    </mvvm:ViewBase>
  17. Navigate to AboutViewModel.cs and add the following code to use with a button to navigate to the MainView using the route specified in the Shell.

    public class AboutViewModel : ViewModelBase
    {
        private ICommand home;
        public ICommand Home => home ?? new TinyCommand(async () =>
        {
            await Navigation.NavigateToAsync("//home");
        });
    }
  18. Go to AboutView.xaml and create a Button to use with the Command in AboutViewModel.

    <mvvm:ViewBase
        xmlns:mvvm="clr-namespace:TinyMvvm.Forms;assembly=TinyMvvm.Forms"
        xmlns:vm="clr-namespace:SampleApp.ViewModels"
        xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="SampleApp.Views.AboutView" x:TypeArguments="vm:AboutViewModel">
     <Grid>
         <Button Text="Go home!" Command="{Binding Home}" />
     </Grid>
    </mvvm:ViewBase>

The complete code for this sample can be found here: https://github.com/TinyStuff/TinyMvvm/tree/master/src/Samples

TinyMvvm 2.2 – Shell Navigation Updates

Today I released TinyMvvm 2.2 (2.2.2).

In this version I have added support for passing parameters when navigating with ShellNavigationHandler. You can now use both query parameters and passing a object as a parameter.

So in your ViewModel with ViewModelBase as the base class you can use it like this:

var persons = new List<string>()
{
   "Daniel",
   "Johan"
};

Navigation.NavigateToAsync($"{nameof(ContactViewModel)}?id=1", persons);

You can also use the NavigationHelper class to navigate.

NavigationHelper.Current.NavigateToAsync($"{nameof(ContactViewModel)}?id=1", persons);

In the receiving ViewModel, you can access the parameters via the QueryParameters- and NavigationParameter properties.

public class ContactViewModel : ViewModelBase
{
    public async override Task Initialize()
    {
        await base.Initialize();

        var id = (int)QueryParameters["id"];
        var persons = (List<string>)NavigationParameter;
    }
}

Read more

If you want to read more about TinyMvvm, I can recommend theese blog posts:
TinyMvvm 2.1.1 – Introducing ViewModel navigation
Introducing TinyMvvm 2.0
TinyMvvm – The best MVVM library for Xamarin.Forms!?

Contribute

The full source code and documentation can be found on GitHub. Feedback and contribtions are very welcome.

TinyMvvm 2.1.1 – Introducing ViewModel navigation

Today I released TinyMvvm 2.1.1. The release contains the following:

  • Updated Xamarin.Forms dependency so it has dependency on the lastest stable version of Xamarin.Forms.
  • ViewModel navigation

ViewModel navigation

The idea about ViewModel navigation is from Shane Neuville from the Xamarin.Forms team, he reviewed TInyMvvm in one of his live streams on Twitch. During the stream he walktrough the code and he also wrote code for ViewModel Navigation. After the stream he sent me the code. For the 2.1.1 release I have added his code to the repopsitory. Thank you Shane for contributing to TinyMvvm!

To use ViewModel Navigation you need to register view by running the RegisterViewInAssembly method and pass the Assembly where your views are located. ViewModel navigation can only be used with the ShellNavigationHelper and for Views that has ViewBase<TViewModel> as its base class.

var navigationHelper = new ShellNavigationHelper();
navigationHelper.RegisterViewsInAssembly(Assembly.GetExecutingAssembly());

Then you can navigate like this in your ViewModel to navigate to for example the AboutView with that uses AboutViewModel:

await Navigation.NavigateToAsync(nameof(AboutViewModel));
//or with query parameter,
await Navigation.NavigateToAsync($"{nameof(AboutViewModel)}?id=1");

The pros by using this is that you don't need to handle keys in your ViewModel and you don't either need to reference the views to use nameof(AboutView) as the key.

Read more

If you don't have used TinyMvvm before I recomend you to read this blog post.

Introducing TinyMvvm 2.0

TinyMvvm is a library that I created a couple of years ago. The idea was to build a small (tiny) MVVM library that made me more productive. I first released TinyNavigationHelper that helped med to abstract the Xamarin.Forms navigation, because I do not want my ViewModels to have references to Xamarin.Forms.

Last time I updated TinyMvvm was about one and a half year ago, the reason I have not updated it since then is that it has been stable and worked very well for me in multiple apps I have worked with for multiple clients.

When Xamarin.Forms Shell was released I started to work with some improvements to make TinyMvvm work with Xamarin.Forms Shell. But I never finished them, because the current version worked very well together with Shell. The only thing not supported was URL navigation.

But in the current app, I work with I had a use case where URL navigation would be very nice to use. Of course, I could have used it without using the navigation in TinyMvmm. But there are some great features of TinyMvvm that I missed then. For example to get navigation parameters in the ViewModel without having to pass them manually from the view and if I wanted to navigate from the ViewModel I had to add references to Xamarin.Forms inside of them.

New features

There is a couple of new stuff added to TinyMvvm in this release.

ShellNavigationHelper

If you want to use URL navigation together with TinyMvvm you have to use the ShellNavigtionHelper. ShellNavigationHelper is a subclass of FormsNavigationHelper.

var navigationHelper = new TinyNavigationHelper.Forms.ShellNavigationHelper();
navigationHelper.RegisterViewsInAssembly(appAssembly);
navigationHelper.RegisterView("MainView", typeof(MainView));

The method that is supporting URL navigation is the NavigateTo(string key) method. All other methods of INavigationHelper will use traditional Xamarin.Forms NavigationService. To NavigateTo you can either specify a URL or a key to a view. If it got a key that you have registered as in the code about it will use the traditional NavigationService, otherwise, it will use Shell navigation with URL.

await NavigationHelper.Current.NavigateTo("//home/messages?id=1");

If you are in a ViewModel with ViewModelBase as parent you can use the Navigation property of of the ViewModelBase,

await Navigation.NavigateTo("//home/messages?id=1");

QueryParameters in ViewModelBase

With URL navigation you can pass query parameters. With TinyMvvm you can access them from the ViewModel via the QueryParameters property of ViewModelBase. QueryParameters is of type Dictionary<string, string>.

public override async Task Initialize()
{
    await base.Initialize();

    var id = QueryParameters["id"];
}

Optimization

In TinyMvvm 1.x there was a dependency on TinyNavigationHelper, in 2.0 is TinyNavigationHelper added as a submodule and compiled into the same assembly as TinyMvvm. This reduces the amount of referenced assemblies that Xamarin.Forms have to search for custom renderers in.

Breaking changes

The constructor to FormsNavigationHelper has changed. You can not pass an instance of Xamarin.Forms.Application anymore, the reason is that it not is necessary to provide the navigation helper with it.

Obsolete fetures

The BeginInvokeOnMainThread future of ViewModelBase has been marked as obsolete, the recommendation is to use Xamarin.Essentials.MainThread.BeginInvokeOnMainThread instead.

TinyMvvm basics

Here are some of the basics of TinyMvvm, you will find the full docs and a sample project here, https://github.com/TinyStuff/TinyMvvm.

Initiation

TinyMvvm.Forms.TinyMvvm.Initialize();

ViewBase<T>

Features (or drawbacks) of the ViewBase

  • It creates the ViewModel for you if you inherit the ViewModel from ViewModelBase

The view should inherit from ViewBase<T> where T is the ViewModel. The ViewModel can be any class that has ViewModelBase as the base class.

ViewBase<T> itself inherits from Xamarin.Forms.ContentPage and can be treated by Xamarin Forms as any page.

If you decide to use ViewModelBase as the base class for your view model and at the same time have the IoC resolver enabled, the view will automatically create the view model for you when the view is created. Hence no need to inject the view model in the constructor and assign it manually. Feature or not, you decide.

An example of a typical page in TinyMvvm would look like this:

<tinymvvm:ViewBase x:TypeArguments="viewmodels:MainViewModel" 
    xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:viewmodels="clr-namespace:TinyMvvm.Forms.Sample.ViewModels;assembly=TinyMvvm.Forms.Samples"
    xmlns:tinymvvm="clr-namespace:TinyMvvm.Forms;assembly=TinyMvvm.Forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    x:Class="TinyMvvm.Forms.Sample.Views.MainView">

</tinymvvm:ViewBase>

What you need to do is:

  • Define two namespaces (viewmodels and tinymvvm)
  • Change the view base type to tinymvvm:ViewBase
  • Add a type argument pointing to your ViewModel

### ViewModelBase

TinyMvvm also defines a base class for the view model called `ViewModelBase`.

Features of the ViewModelBase

* Wraps navigation for you through the INavigation interface (Implemented in TinyNavigation)
* Implements INotifyPropertyChanged for you
* Propagates life cycle events to the view (Initialize, OnAppearing, OnDisapparing)

### IoC
Tiny Mvvm is not bound to any specific IoC provider. There is a provider for Autofac that you can install with the "TinyMvvm.Autofac" package.

Install-Package TinyMvvm.Autofac

TinyMvvm has a Resolver in its core project. To use it you need to add on a provider to it that implements the IResolver interface, for example, our Autofac provider.

```csharp
var container = builder.Build();
var resolver = new AutofacResolver(container);
Resolver.SetResolver(resolver);
var navigationHelper = Resolver.Resolve();

TinyCommand

TinyMvvm has its own implementation of ICommand that not has any references to Xamarin.Forms so you can use it in a library without reference Xamarin.Forms.

public ICommand WithParameter
{
      get
      {
                return new TinyCommand(async() =>
                {
                   //Do stuff
                });
      }
}