After downloading the newest Version of mvvmcross (V3) I had some work to do, to upgrade some of my projects to the new state. Last thing I'm not able to fulfill is to pass a parameter to the viewmodel from the tabhost. In the older versions it worked fine (but it was different) and now I got an error.
But First here the Code (Line 19 makes trouble (watch comment in code), Line 18 works but only without Parameters):
[Activity]
public class MainActivity : MvxTabActivity
{
public new MainViewModel ViewModel
{
get { return (MainViewModel)base.ViewModel; }
set { base.ViewModel = value; }
}
protected override void OnViewModelSet()
{
SetContentView(Resource.Layout.Main);
TabHost.TabSpec spec;
Intent intent;
spec = TabHost.NewTabSpec("listeaktiv");
spec.SetIndicator(App.indicatorActive, Resources.GetDrawable(Resource.Drawable.green));
//spec.SetContent(this.CreateIntentFor(ViewModel.ListViewModel)); -> It works (But only without Parameters! How could I pass them here?)
spec.SetContent(this.CreateIntentFor<ListViewModel>(new { parameter = App.indicatorActive })); //Exception (on the next Line)
TabHost.AddTab(spec);
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
}
}
(App.indicatorActive is the Parameter I want to pass, its in the App.cs: (public static string indicatorActive = "Active";)
My ListViewModel looks like that:
public class ListViewModel : BaseViewModel
{
public ListViewModel(string parameter)
{
}
}
Error:
Unhandled Exception:
Cirrious.CrossCore.Exceptions.MvxException: Failed to load ViewModel for type
INApplikationsMonitor.Core.ViewModels.ListViewModel from locator MvxDefaultViewModelLocator
My guess is that this is just because you are using the old ViewModel lifecycle.
In v3:
the ViewModel constructor parameters are used for IoC - for Dependency Injection of services.
for passing parameters you need to instead use an Init method within the ViewModel
For more on this, see: http://slodge.blogspot.co.uk/2013/03/v3-new-viewmodel-lifecycle.html :
The default ViewModelLocator in v3 builds new ViewModel instances using a 4-step process - CIRS:
Construction - using IoC for Dependency Injection
Init() - initialisation of navigation parameters
ReloadState() - rehydration after tombstoning
Start() - called when initialisation and rehydration are complete
Related
I am in the process of transforming my entire application to MVVM and adding Dependency
Injection. for the navigation I have used
Navigation.PushAsync(new date());
it which worked but now its no longer works. do you have some solutions.
inside date.xaml.cs
public partial class date : ContentPage
{
public date(dateViewModel vm)
{
InitializeComponent();
BindingContext = vm;
}
private void GoNav(object sender, EventArgs e)
{
Navigation.PopAsync();
}
}
the C# compile error is
CS7036 There is no argument given that corresponds to the required formal parameter 'vm' of 'date.date(dateViewModel)' dateCalculator (net6.0-android), dateCalculator (net6.0-ios), dateCalculator (net6.0-maccatalyst), dateCalculator (net6.0-windows10.0.19041.0) C:\Users\source\repos\dateCalculator\dateCalculator\MainPage.xaml.cs 12
Cause
It is because you remove the default class constructor and create a new one with parameter, so when you call new date() it can't be able to find the constructor without parameter(the default one) , that's why the error comes.
Solution
Remove the new constructor .
Or
Give the value on the parameter when creating the class .
Navigation.PushAsync(new date(YourVm));
In the ViewModel, I have Save method where I check isValid property.
If isValid is false, then I want to display an error message.
Since AlertDialog is platform specific, I wonder how do you handle that situation in the ViewModel?
public void Save()
{
if (isValid)
{
OnExit(this, null);
}
else
{
//issue an alert dialog here
}
}
Update
I have used the following plugin and added the following line of code as follows, but it throws an error.
else
{
Mvx.Resolve<IUserInteraction>().Alert("it is not valid");
}
Update 2
Chance.MvvmCross.Plugins.UserInteraction is a namespace but it is used as a type error.
Update 3
I have added Acr.UserDialogs plugin and called as follows, but I have got the same error.
Mvx.Resolve<IUserDialogs>().Alert("it is not valid");
Using ACR User Dialogs is the simplest approach.
In your App.cs (Core/PCL) you will need to register the interface:
public class App : MvxApplication
{
public override void Initialize()
{
// Example Other registrations
CreatableTypes()
.EndingWith("Service")
.AsInterfaces()
.RegisterAsLazySingleton();
Mvx.RegisterSingleton<IUserDialogs>(() => UserDialogs.Instance);
}
}
Then you can call your alert form your ViewModel.
Mvx.Resolve<IUserDialogs>().Alert("it is not valid");
Note for Android Platform support
Then if you are supporting Android you will need to initialize UserDialog with an instance of the activity context. This will have to be done in each activity that you will be making use of UserDialogs or if you have a shared base activity you can do it there.
[Activity]
public class MainActivity : MvxActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.activity_main);
// Initialize Acr UserDialogs
UserDialogs.Init(this);
}
}
Alternatively
You can follow the Mvvmcross document on using platform specific implementations of an interface if you need a more custom modal implementation.
This is how I handle the Alert messages in the viewmodel. Try this.
await App.Current.MainPage.DisplayAlert("Active subscription required", "You do not have an active subscription for Part 2 exams", "OK");
There is an existing MvvmCross plugin called User Interaction that allows displaying alerts and collecting inputs from ViewModels.
From the author BrianChance:
Really simple, easy, beautiful ways to show a message box or to collect user input from your ViewModels
Check it out here and NuGet Link Here.
To install the plugin, make sure you override LoadPlugins in your SetUp Class on iOS and Android (and windows phone) like so:
public override void LoadPlugins(MvvmCross.Platform.Plugins.IMvxPluginManager pluginManager)
{
base.LoadPlugins(pluginManager);
pluginManager.EnsurePluginLoaded<Chance.MvvmCross.Plugins.UserInteraction>();
}
My approach is that i use an event for this scenario. My base class for my view models has a EventHandler OnUserNotification, where the views can kinda subscribe to. The UserNotificationType is just an enum and i let the view kinda decide how it reacts to the situation.
The property:
public EventHandler<UserNotificationType> OnUserNotification { get; set; }
The call:
if (OnUserNotification != null)
{
OnUserNotification.Invoke(this, UserNotificationType.ENetworkError);
}
In the view:
private void onUserNotification(object sender, UserNotificationType userNotificationType)
{
// Do Something like showing a Snackbar, AlertDialog, etc...
}
Of course you can make the eventtype more complex if needed.
Didnt try the plugin which got suggested by wishmaster though, so that might be a smoother implementation?
Use Acr.UserDialogs. There is a great examples on github
You can grab it on nuget
It works well with dependency injection or a static singleton UserDialogs.Instance
Here Caliburn.Micro was successfully combined with ModernUI.
But if we want to use multiple windows we also need to re-implement Caliburn's WindowManager to work properly with ModernUI. How can it be done?
UPDATE:
(Additional question about IoC-Container/Dependency Injection)
Ok, as I get it: I used a Constructor Injection here:
public class BuildingsViewModel : Conductor<IScreen>
{
public BuildingsViewModel(IWindowManager _windowManager)
{
windowManager = _windowManager;
}
}
As far as BuildingsViewModel resolved from IoC container,
container itself injected ModernWindowManager implementation of IWindowManager interface because of this line in Bootstrapper's Configure() method:
container.Singleton<IWindowManager, ModernWindowManager>();
If I resolving an object instance from container, it injects all needed dependencies. Like a tree.
1) So now I wonder how can I replace this line using an injection(with interface)?
_windowManager.ShowWindow(new PopupViewModel());
2) If I want my whole project match DI pattern, all objects instances must be injected into ModernWindowViewModel, that resolves from container first?
3) Is it okay to use Caliburn's SimpleContainer for whole project, or better use mature framework like Castle Windsor? Should I avoid mixing?
UPDATE2:
4) Integrating an IoC container into an existing application requires creating this container first(in Main() method of console app for example), and then all object instanses must grow from it with injected dependencies?
Simply create your own derived WindowManager and override EnsureWindow:
public class ModernWindowManager : WindowManager
{
protected override Window EnsureWindow(object rootModel, object view, bool isDialog)
{
var window = view as ModernWindow;
if (window == null)
{
window = new ModernWindow();
window.SetValue(View.IsGeneratedProperty, true);
}
return window;
}
}
Any views that you want to use as popups must be based on ModernWindow and must either use a LinkGroupCollection or you must set the ContentSource property of the window, otherwise there will be no content.
You could possibly make this View-First but it works ViewModel-First using the method above.
e.g. to popup my PopupView I did the following
PopupView.xaml
<mui:ModernWindow x:Class="TestModernUI.ViewModels.PopupView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mui="http://firstfloorsoftware.com/ModernUI"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" ContentSource="/ViewModels/ChildView.xaml">
</mui:ModernWindow>
PopupViewModel.cs
public class PopupViewModel : Screen
{
// Blah
}
Code to popup the view from another ViewModel:
public void SomeMethod()
{
_windowManager.ShowWindow(new PopupViewModel()); // Or use injection etc
}
Don't forget to register ModernWindowManager in place of WindowManager in your container!
e.g. using CM's SimpleContainer
container.Singleton<IWindowManager, ModernWindowManager>();
Obviously the only downside I can see to the above is that you can't seem to put content directly in a ModernWindow, so you have to have two UserControls for every popup!
A workaround would be to change EnsureWindow in ModernWindowManager so that it created a UserControl based on ModernWindow and set the ContentSource to the URI of the view you want to load, this will trigger the content loader and wire up your ViewModel. I'll update if I get a minute to try it.
Update:
Ok, so at the moment it's very hacky, but this could be a starting point for something useful. Basically I'm generating a URI based on the namespace and name of the view.
I'm sure there is a more reliable way of doing this, but for my test project it works:
protected override Window EnsureWindow(object rootModel, object view, bool isDialog)
{
var window = view as ModernWindow;
if (window == null)
{
window = new ModernWindow();
// Get the namespace of the view control
var t = view.GetType();
var ns = t.Namespace;
// Subtract the project namespace from the start of the full namespace
ns = ns.Remove(0, 12);
// Replace the dots with slashes and add the view name and .xaml
ns = ns.Replace(".", "/") + "/" + t.Name + ".xaml";
// Set the content source to the Uri you've made
window.ContentSource = new Uri(ns, UriKind.Relative);
window.SetValue(View.IsGeneratedProperty, true);
}
return window;
}
My full namespace for my view was TestModernUI.ViewModels.PopupView and the URI generated was /ViewModels/PopupView.xaml which then was loaded and bound via the content loader automagically.
Update 2
FYI here is my Bootstrapper configure method:
protected override void Configure()
{
container = new SimpleContainer();
container.Singleton<IWindowManager, ModernWindowManager>();
container.Singleton<IEventAggregator, EventAggregator>();
container.PerRequest<ChildViewModel>();
container.PerRequest<ModernWindowViewModel>();
container.PerRequest<IShell, ModernWindowViewModel>();
}
Here I create the container, and register some types.
The CM services such as WindowManager and EventAggregator are both registered against their respective interfaces and as singletons so only 1 instance of each will be available at run time.
The view models are registered as PerRequest which creates a new instance every time you request one from the container - this way you can have the same window popup multiple times without strange behaviour!
These dependencies are injected into the constructor of any objects resolved at run time.
Update 3
In answer to your IoC questions:
1) So now I wonder how can I replace this line using an injection(with interface)? _windowManager.ShowWindow(new PopupViewModel());
Since your viewmodels will now usually need dependencies you need to have some way of injecting them into the instances. If PopupViewModel had several dependencies, you could inject them into the parent class but this would couple the parent viewmodel to PopupViewModel in some way.
There are a couple of other methods you can use to get an instance of PopupViewModel.
Inject it!
If you register PopupViewModel as PerRequest you will get a new instance of it every time you request it. If you only need one popup instance in your viewmodel you can just inject it:
public class MyViewModel
{
private PopupViewModel _popup;
private IWindowManager _windowManager;
public MyViewModel(PopupViewModel popup, IWindowManager windowManager)
{
_popup = popup;
_windowManager = windowManager;
}
public void ShowPopup()
{
_windowManager.ShowPopup(_popup);
}
}
The only downside is that the instance will be the same one if you need to use it multiple times in the same viewmodel, though you could inject multiple instances of PopupViewModel if you knew how many you needed at the same time
Use some form of on-demand injection
For dependencies which are required later on you can use on-demand injection such as a factory
I don't think Caliburn or SimpleContainer support factories out of the box, so the alternative is to use IoC.Get<T>. IoC is a static class which lets you access your DI container after instantiation
public void ShowPopup()
{
var popup = IoC.Get<PopupViewModel>();
_windowManager.ShowWindow(popup);
}
You need to make sure you have correctly registered the container in your bootstrapper and delegated any calls to CM's IoC methods to the container - IoC.Get<T> calls the bootstrapper's GetInstance and other methods:
Here's an example:
public class AppBootstrapper : BootstrapperBase {
SimpleContainer container;
public AppBootstrapper() {
Initialize();
}
protected override void Configure() {
container = new SimpleContainer();
container.Singleton<IWindowManager, ModernWindowManager>();
container.Singleton<IEventAggregator, EventAggregator>();
container.PerRequest<IShell, ModernWindowViewModel>();
// Register viewmodels etc here....
}
// IoC.Get<T> or IoC.GetInstance(Type type, string key) ....
protected override object GetInstance(Type service, string key) {
var instance = container.GetInstance(service, key);
if (instance != null)
return instance;
throw new InvalidOperationException("Could not locate any instances.");
}
// IoC.GetAll<T> or IoC.GetAllInstances(Type type) ....
protected override IEnumerable<object> GetAllInstances(Type service) {
return container.GetAllInstances(service);
}
// IoC.BuildUp(object obj) ....
protected override void BuildUp(object instance) {
container.BuildUp(instance);
}
protected override void OnStartup(object sender, System.Windows.StartupEventArgs e) {
DisplayRootViewFor<IShell>();
}
Castle.Windsor supports factories so that you can Resolve and Release your components and manage their lifetime more explicitly, but I won't go into that here
2) If I want my whole project match DI pattern, all objects instances must be injected into ModernWindowViewModel, that resolves from container first?
You only need to inject the dependencies that the ModernWindowViewModel needs. Anything that is required by children is automatically resolved and injected e.g.:
public class ParentViewModel
{
private ChildViewModel _child;
public ParentViewModel(ChildViewModel child)
{
_child = child;
}
}
public class ChildViewModel
{
private IWindowManager _windowManager;
private IEventAggregator _eventAggregator;
public ChildViewModel(IWindowManager windowManager, IEventAggregator eventAggregator)
{
_windowManager = windowManager;
_eventAggregator = eventAggregator;
}
}
In the above situation, if you resolve ParentViewModel from the container - the ChildViewModel will get all it's dependencies. You don't need to inject them into the parent.
3) Is it okay to use Caliburn's SimpleContainer for whole project, or better use mature framework like Castle Windsor? Should I avoid mixing?
You can mix, but it might be confusing as they won't work with each other (one container won't know about the other). Just stick with one container, and SimpleContainer is fine - Castle Windsor has a lot more features, but you might never need them (I've only used a few of the advanced features)
4) Integrating an IoC container into an existing application requires creating this container first(in Main() method of console app for example), and then all object instanses must grow from it with injected dependencies?
Yes, you create the container, then you resolve the root component (in 99.9% of applications there is one main component which is called the composition root), and this then builds the full tree.
Here is an example of a bootstrapper for a service based application. I'm using Castle Windsor and I wanted to be able to host the engine in a Windows service or in a WPF application or even in a Console Window (for testing/debug):
// The bootstrapper sets up the container/engine etc
public class Bootstrapper
{
// Castle Windsor Container
private readonly IWindsorContainer _container;
// Service for writing to logs
private readonly ILogService _logService;
// Bootstrap the service
public Bootstrapper()
{
_container = new WindsorContainer();
// Some Castle Windsor features:
// Add a subresolver for collections, we want all queues to be resolved generically
_container.Kernel.Resolver.AddSubResolver(new CollectionResolver(_container.Kernel));
// Add the typed factory facility and wcf facility
_container.AddFacility<TypedFactoryFacility>();
_container.AddFacility<WcfFacility>();
// Winsor uses Installers for registering components
// Install the core dependencies
_container.Install(FromAssembly.This());
// Windsor supports plugins by looking in directories for assemblies which is a nice feature - I use that here:
// Install any plugins from the plugins directory
_container.Install(FromAssembly.InDirectory(new AssemblyFilter("plugins", "*.dll")));
_logService = _container.Resolve<ILogService>();
}
/// <summary>
/// Gets the engine instance after initialisation or returns null if initialisation failed
/// </summary>
/// <returns>The active engine instance</returns>
public IIntegrationEngine GetEngine()
{
try
{
return _container.Resolve<IIntegrationEngine>();
}
catch (Exception ex)
{
_logService.Fatal(new Exception("The engine failed to initialise", ex));
}
return null;
}
// Get an instance of the container (for debugging)
public IWindsorContainer GetContainer()
{
return _container;
}
}
Once the bootstrapper is created, it sets up the container and registers all services and also plugin dlls. The call to GetEngine starts the application by resolving Engine from the container which creates the full dependency tree.
I did this so that it allows me to create a service or a console version of the application like this:
Service Code:
public partial class IntegrationService : ServiceBase
{
private readonly Bootstrapper _bootstrapper;
private IIntegrationEngine _engine;
public IntegrationService()
{
InitializeComponent();
_bootstrapper = new Bootstrapper();
}
protected override void OnStart(string[] args)
{
// Resolve the engine which resolves all dependencies
_engine = _bootstrapper.GetEngine();
if (_engine == null)
Stop();
else
_engine.Start();
}
protected override void OnStop()
{
if (_engine != null)
_engine.Stop();
}
}
Console App:
public class ConsoleAppExample
{
private readonly Bootstrapper _bootstrapper;
private IIntegrationEngine _engine;
public ConsoleAppExample()
{
_bootstrapper = new Bootstrapper();
// Resolve the engine which resolves all dependencies
_engine = _bootstrapper.GetEngine();
_engine.Start();
}
}
Here's part of the implementation of IIntegrationEngine
public class IntegrationEngine : IIntegrationEngine
{
private readonly IScheduler _scheduler;
private readonly ICommsService _commsService;
private readonly IEngineStateService _engineState;
private readonly IEnumerable<IEngineComponent> _components;
private readonly ConfigurationManager _configurationManager;
private readonly ILogService _logService;
public IntegrationEngine(ICommsService commsService, IEngineStateService engineState, IEnumerable<IEngineComponent> components,
ConfigurationManager configurationManager, ILogService logService)
{
_commsService = commsService;
_engineState = engineState;
_components = components;
_configurationManager = configurationManager;
_logService = logService;
// The comms service needs to be running all the time, so start that up
commsService.Start();
}
All of the other components have dependencies, but I don't inject those into the IntegrationEngine - they are handled by the container
In our real world application we defined an attribute that is used to enable logging in methods or classes (the usual AOP use case). When we apply this attribute to a WPF window class, objects of this class can't be created by Ninject. Here is a minimal example to reproduce the issue:
dummy interceptor for logging:
public class MyInterceptor: IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("Calling {0} at {1}", invocation.Request.Method.Name, DateTime.Now);
invocation.Proceed();
}
}
the corresponding attribute:
public class MyAttribute: InterceptAttribute
{
public override IInterceptor CreateInterceptor(IProxyRequest request)
{
return new MyInterceptor();
}
}
the window class (completely empty, only the automatically generated empty grid is inside):
[My]
public partial class MainWindow: Window
{
public MainWindow()
{
InitializeComponent();
}
}
and finally the app startup code where the object is requested:
public partial class App: Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
var kernel = new StandardKernel(new NinjectSettings() { LoadExtensions = false }, new DynamicProxyModule());
var window = kernel.Get<MainWindow>();
window.ShowDialog();
}
}
When requesting the window via kernel.Get<MainWindow>(); an TargetInvocationException is thrown with an inner exception telling me that Castle.Proxies.MainWindowProxy doesn't have a resource specified by URI "/NinjectInterceptionWPF;component/mainwindow.xaml" where NinjectInterceptionWPF is our assembly's short name.
When we look at the automatically created InitializeComponent of MainWindow we can see that an URI is created to address the XAML code, which seems to be missing for the proxy:
System.Uri resourceLocater = new System.Uri("/NinjectInterceptionWPF;component/mainwindow.xaml", System.UriKind.Relative);
#line 1 "..\..\..\MainWindow.xaml"
System.Windows.Application.LoadComponent(this, resourceLocater);
I already played around a bit and tried to use an absolute URI but LoadComponent only accepts relative ones.
Some internet searching shows that a lot of people use Ninject Interception and DynmaicProxy for WPF binding (INotifyPropertyChanged), so I think in general it should be possible to build a proxy of a WPF window.
But how?
The interception extension of Ninject created a new dynamic assembly. This means you won't be able to load resources with a relative path. But the question here is if you really want to create a dynamic proxy for the view. Usually you should do this on your ViewModel instead.
I've successfully implemented Ninject in an MVC3 application, but am running into some trouble doing the same thing with ASP.NET Web Forms. I'm getting null references every time I try to access an injected property in my business layer. After setting breakpoints within the CreateKernel method, as well as several places within the ServiceLocator class, it looks like none of them are ever getting hit, so it's not even loading.
I'm sure I'm just approaching this wrong, but there is very little documentation or info out there for wiring up Ninject in a Web Forms application.
Basically here's what I have so far:
code behind
public class ReviewManager
{
[Inject] private IReviewRepository _reviewRepository { get; set; }
public ReviewManager() { }
public ReviewManager(IReviewRepository reviewRepository)
{
_reviewRepository = reviewRepository;
}
public Review GetById(int id)
{
if (id <= 0) throw new ArgumentException("ID must be greater than zero");
**I get a null reference exception on the next line. _reviewRepository is null**
return _reviewRepository.GetById(id);
}
}
global.asax.cs
public class Global : NinjectHttpApplication
{
protected override IKernel CreateKernel()
{
return ServiceLocator.Kernel;
}
// deleted for brevity
}
ServiceLocator.cs (edited for brevity, the relevant parts are here)
public static class ServiceLocator
{
public static IKernel Kernel { get; set; }
public static ILogger Logger { get; set; }
static ServiceLocator()
{
Kernel = new StandardKernel(new INinjectModule[] {
new LoggerBindings(),
new DataBindings()
});
if (Logger == null)
Logger = Kernel.Get<ILogger>();
}
}
public class LoggerBindings : NinjectModule
{
public override void Load()
{
Bind<ILogger>().To<NLogLogger>();
}
}
public class DataBindings : NinjectModule
{
public override void Load()
{
Bind<IReviewRepository>().To<ReviewRepository>();
}
}
ASP.Net via WebForms does not allow you to manage the lifecycle of all object instances (like MVC does). For example, the framework instantiates page objects. This means you probably can't implement DI in quite the same way as you would in MVC/WPF/Silverlight (the same problem is present in WinForms IIRC). You will likely have to initiate the dependency graph directly in each of your code behinds.
Translation: you will want to call ServiceLocator.Kernel.Get<IReviewRepository> when your page loads (or as lazy-init on the property).
The cool thing about MVC ist that it can run side a side of ASP.NET WebForm pages in the same application. In my opinion the best way to extend ASP.NET WebForms websites is to create new pages using MVC3 and to refactor every page that needs major changes to MVC3.
If this is no option go and use the Ninject.Web extension. It contains a IHttpModule that property injects all web pages and controlls after they are initialized. That way you can property inject the services als have them created by Ninject.
A potential workaround, by changing your DataBindings class as follows:
public class DataBindings : NinjectModule
{
public override void Load()
{
Bind<IReviewRepository>().To<ReviewRepository>();
Bind<ReviewManager>().ToSelf();
}
}
And within your caller, instead of
var rm = new ReviewManager();
Try using
var rm = ServiceLocator.Kernel.Get<ReviewManager>();
I havent tested this code, but i think it'll solve your null reference problem.
I use property injection for pages, masterpages and usercontrols. All my pages, for example, inherit from a base class that overrides RequestActivation method with the following code:
''' <summary>
''' Asks the kernel to inject this instance.
''' </summary>
Protected Overridable Sub RequestActivation()
ServiceLocator.Kernel.Inject(Me)
End Sub
And in each page I declare injectable properties:
<Inject()>
Property repo As IMyRepository