Make BootstrapperBase non-generic

Instead, it has an abstract RootViewModel property, which bootstrapper
overrides to return an instance of TRootViewModel from the container.

This means that the root ViewModel is treated a singleton by the bootstrapper,
regardless of whether it's singleton in the container
This commit is contained in:
Antony Male 2015-01-15 10:06:00 +00:00
parent 46dc485eee
commit 07160aa4fe
10 changed files with 72 additions and 21 deletions

View File

@ -6,10 +6,16 @@ using System.Windows;
namespace Bootstrappers
{
public class AutofacBootstrapper<TRootViewModel> : BootstrapperBase<TRootViewModel> where TRootViewModel : class
public class AutofacBootstrapper<TRootViewModel> : BootstrapperBase where TRootViewModel : class
{
private IContainer container;
private object _rootViewModel;
protected override object RootViewModel
{
get { return this._rootViewModel ?? (this._rootViewModel = this.GetInstance(typeof(TRootViewModel))); }
}
protected override void ConfigureBootstrapper()
{
this.Configure();

View File

@ -7,10 +7,16 @@ using System.Windows;
namespace Bootstrappers
{
public class CastleWindsorBootstrapper<TRootViewModel> : BootstrapperBase<TRootViewModel> where TRootViewModel : class
public class CastleWindsorBootstrapper<TRootViewModel> : BootstrapperBase where TRootViewModel : class
{
private IWindsorContainer container;
private object _rootViewModel;
protected override object RootViewModel
{
get { return this._rootViewModel ?? (this._rootViewModel = this.GetInstance(typeof(TRootViewModel))); }
}
protected override void ConfigureBootstrapper()
{
this.Configure();

View File

@ -5,10 +5,16 @@ using System.Windows;
namespace Bootstrappers
{
public class NinjectBootstrapper<TRootViewModel> : BootstrapperBase<TRootViewModel> where TRootViewModel : class
public class NinjectBootstrapper<TRootViewModel> : BootstrapperBase where TRootViewModel : class
{
private IKernel kernel;
private object _rootViewModel;
protected override object RootViewModel
{
get { return this._rootViewModel ?? (this._rootViewModel = this.GetInstance(typeof(TRootViewModel))); }
}
protected override void ConfigureBootstrapper()
{
this.Configure();

View File

@ -4,7 +4,7 @@ using System.Collections.Generic;
namespace Bootstrappers
{
public class NoIoCContainerBootstrapper<TRootViewModel> : BootstrapperBase<TRootViewModel> where TRootViewModel : class
public abstract class NoIoCContainerBootstrapper : BootstrapperBase
{
protected readonly Dictionary<Type, Func<object>> Container = new Dictionary<Type, Func<object>>();
@ -35,7 +35,7 @@ namespace Bootstrappers
}
/// <summary>
/// Use this to add your own types to this.Container. You *MUST* add TRootViewModel
/// Use this to add your own types to this.Container
/// </summary>
protected virtual void ConfigureContainer() { }

View File

@ -6,10 +6,16 @@ using System.Windows;
namespace Bootstrappers
{
public class StructureMapBootstrapper<TRootViewModel> : BootstrapperBase<TRootViewModel> where TRootViewModel : class
public class StructureMapBootstrapper<TRootViewModel> : BootstrapperBase where TRootViewModel : class
{
private IContainer container;
private object _rootViewModel;
protected override object RootViewModel
{
get { return this._rootViewModel ?? (this._rootViewModel = this.GetInstance(typeof(TRootViewModel))); }
}
protected override void ConfigureBootstrapper()
{
this.Configure();

View File

@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace Bootstrappers.Tests
{
public class MyNoIocContainerBootstrapper : NoIoCContainerBootstrapper<TestRootViewModel>, ITestBootstrapper
public class MyNoIocContainerBootstrapper : NoIoCContainerBootstrapper, ITestBootstrapper
{
public List<string> ConfigureLog { get; set; }
@ -16,6 +16,11 @@ namespace Bootstrappers.Tests
this.ConfigureLog = new List<string>();
}
protected override object RootViewModel
{
get { return new TestRootViewModel(); }
}
protected override void Configure()
{
base.Configure();

View File

@ -5,10 +5,16 @@ using System.Windows;
namespace Bootstrappers
{
public class UnityBootstrapper<TRootViewModel> : BootstrapperBase<TRootViewModel> where TRootViewModel : class
public class UnityBootstrapper<TRootViewModel> : BootstrapperBase where TRootViewModel : class
{
private IUnityContainer container;
private object _rootViewModel;
protected override object RootViewModel
{
get { return this._rootViewModel ?? (this._rootViewModel = this.GetInstance(typeof(TRootViewModel))); }
}
protected override void ConfigureBootstrapper()
{
this.Configure();

View File

@ -9,13 +9,23 @@ namespace Stylet
/// Bootstrapper to be extended by any application which wants to use StyletIoC (the default)
/// </summary>
/// <typeparam name="TRootViewModel">Type of the root ViewModel. This will be instantiated and displayed</typeparam>
public abstract class Bootstrapper<TRootViewModel> : BootstrapperBase<TRootViewModel> where TRootViewModel : class
public abstract class Bootstrapper<TRootViewModel> : BootstrapperBase where TRootViewModel : class
{
/// <summary>
/// Gets or sets the Bootstrapper's IoC container. This is created after ConfigureIoC has been run.
/// </summary>
protected IContainer Container { get; set; }
private object _rootViewModel;
/// <summary>
/// Gets the instance of the root ViewMode, which is displayed at launch
/// </summary>
protected override object RootViewModel
{
get { return this._rootViewModel ?? (this._rootViewModel = this.GetInstance(typeof(TRootViewModel))); }
}
/// <summary>
/// Overridden from BootstrapperBase, this sets up the IoC container
/// </summary>

View File

@ -12,8 +12,7 @@ namespace Stylet
/// <summary>
/// Bootstrapper to be extended by applications which don't want to use StyletIoC as the IoC container.
/// </summary>
/// <typeparam name="TRootViewModel">Type of the root ViewModel. This will be instantiated and displayed</typeparam>
public abstract class BootstrapperBase<TRootViewModel> : IBootstrapper, IViewManagerConfig where TRootViewModel : class
public abstract class BootstrapperBase : IBootstrapper, IViewManagerConfig
{
/// <summary>
/// Gets the current application
@ -32,11 +31,16 @@ namespace Stylet
public string[] Args { get; private set; }
/// <summary>
/// Initialises a new instance of the <see cref="BootstrapperBase{TRootViewModel}"/> class
/// Gets the instance of the root ViewMode, which is displayed at launch
/// </summary>
protected abstract object RootViewModel { get; }
/// <summary>
/// Initialises a new instance of the <see cref="BootstrapperBase"/> class
/// </summary>
protected BootstrapperBase()
{
this.Assemblies = new List<Assembly>() { typeof(BootstrapperBase<>).Assembly, this.GetType().Assembly };
this.Assemblies = new List<Assembly>() { typeof(BootstrapperBase).Assembly, this.GetType().Assembly };
}
/// <summary>
@ -62,7 +66,7 @@ namespace Stylet
};
// Fetch this logger when needed. If we fetch it now, then no-one will have been given the change to enable the LogManager, and we'll get a NullLogger
this.Application.DispatcherUnhandledException += (o, e) => LogManager.GetLogger(typeof(BootstrapperBase<>)).Error(e.Exception, "Unhandled exception");
this.Application.DispatcherUnhandledException += (o, e) => LogManager.GetLogger(typeof(BootstrapperBase)).Error(e.Exception, "Unhandled exception");
this.Application.DispatcherUnhandledException += (o, e) => this.OnUnhandledExecption(e);
}
@ -88,8 +92,7 @@ namespace Stylet
protected virtual void Launch()
{
var windowManager = (IWindowManager)this.GetInstance(typeof(IWindowManager));
var rootViewModel = this.GetInstance(typeof(TRootViewModel));
windowManager.ShowWindow(rootViewModel);
windowManager.ShowWindow(this.RootViewModel);
this.OnStartup();
}

View File

@ -17,7 +17,7 @@ namespace StyletUnitTests
{
private class RootViewModel { }
private class MyBootstrapperBase<T> : BootstrapperBase<T> where T : class
private class MyBootstrapperBase : BootstrapperBase
{
private IViewManager viewManager;
private IWindowManager windowManager;
@ -35,6 +35,11 @@ namespace StyletUnitTests
get { return base.Application; }
}
protected override object RootViewModel
{
get { return new RootViewModel(); }
}
public bool GetInstanceCalled;
public override object GetInstance(Type service)
{
@ -43,8 +48,6 @@ namespace StyletUnitTests
return this.viewManager;
if (service == typeof(IWindowManager))
return this.windowManager;
if (service == typeof(RootViewModel))
return new RootViewModel();
return null;
}
@ -92,7 +95,7 @@ namespace StyletUnitTests
}
private MyBootstrapperBase<RootViewModel> bootstrapper;
private MyBootstrapperBase bootstrapper;
private Mock<IViewManager> viewManager;
private Mock<IWindowManager> windowManager;
@ -104,7 +107,7 @@ namespace StyletUnitTests
this.dispatcher = Execute.Dispatcher;
this.viewManager = new Mock<IViewManager>();
this.windowManager = new Mock<IWindowManager>();
this.bootstrapper = new MyBootstrapperBase<RootViewModel>(this.viewManager.Object, this.windowManager.Object);
this.bootstrapper = new MyBootstrapperBase(this.viewManager.Object, this.windowManager.Object);
}
[TearDown]