diff --git a/Stylet/Bootstrapper.cs b/Stylet/Bootstrapper.cs index 5498771..ca9920f 100644 --- a/Stylet/Bootstrapper.cs +++ b/Stylet/Bootstrapper.cs @@ -11,20 +11,14 @@ namespace Stylet public class Bootstrapper : BootstrapperBase where TRootViewModel : class { /// - /// Create a new Bootstrapper, which automatically starts and launches on application startup + /// Create a new Bootstrapper /// public Bootstrapper() : base() { } - /// - /// Create a new Bootstrapper, and specify whether to auto-start and auto-launch - /// - /// True to call this.Start() on Application.Startup. If false, call this.Start() in your OnStartup override - public Bootstrapper(bool autoStart) : base(autoStart) { } - /// /// IoC container. This is created after ConfigureIoC has been run. /// - protected IContainer container; + protected IContainer Container { get; private set; } /// /// Overridden from BootstrapperBase, this sets up the IoC container @@ -38,7 +32,7 @@ namespace Stylet this.DefaultConfigureIoC(builder); this.ConfigureIoC(builder); - this.container = builder.BuildContainer(); + this.Container = builder.BuildContainer(); } /// @@ -67,7 +61,7 @@ namespace Stylet /// protected override object GetInstance(Type service, string key = null) { - return this.container.Get(service, key); + return this.Container.Get(service, key); } /// @@ -75,7 +69,7 @@ namespace Stylet /// protected override IEnumerable GetAllInstances(Type service) { - return this.container.GetAll(service); + return this.Container.GetAll(service); } /// @@ -83,7 +77,7 @@ namespace Stylet /// protected override void BuildUp(object instance) { - this.container.BuildUp(instance); + this.Container.BuildUp(instance); } } } diff --git a/Stylet/BootstrapperBase.cs b/Stylet/BootstrapperBase.cs index 06af41b..ee0244c 100644 --- a/Stylet/BootstrapperBase.cs +++ b/Stylet/BootstrapperBase.cs @@ -13,7 +13,7 @@ namespace Stylet /// Bootstrapper to be extended by applications which don't want to use StyletIoC as the IoC container. /// /// Type of the root ViewModel. This will be instantiated and displayed - public abstract class BootstrapperBase where TRootViewModel : class + public abstract class BootstrapperBase : IBootstrapper where TRootViewModel : class { /// /// Reference to the current application @@ -21,18 +21,12 @@ namespace Stylet protected Application Application { get; private set; } /// - /// Create a new BootstrapperBase, which automatically starts on application startup + /// Called by the ApplicationLoader when this bootstrapper is loaded /// - public BootstrapperBase() : this(true) { } - - /// - /// Create a new BootstrapperBase, and specify whether to auto-start - /// - /// True to call this.Start() at the end of this constructor - [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "We give the user the option to not call the virtual method, and call it themselves, if they want/need to")] - public BootstrapperBase(bool autoStart) + /// + public void Setup(Application application) { - this.Application = Application.Current; + this.Application = application; // Allows for unit testing if (this.Application != null) @@ -40,8 +34,7 @@ namespace Stylet this.Application.Startup += (o, e) => { this.OnApplicationStartup(o, e); - if (autoStart) - this.Start(); + this.Start(); }; // Make life nice for the app - they can handle these by overriding Bootstrapper methods, rather than adding event handlers @@ -56,8 +49,7 @@ namespace Stylet /// /// Called from the constructor, this does everything necessary to start the application /// - /// True to automatically launch the main window - protected virtual void Start(bool autoLaunch = true) + protected virtual void Start() { // Stitch the IoC shell to us IoC.GetInstance = this.GetInstance; @@ -72,14 +64,11 @@ namespace Stylet AssemblySource.Assemblies.Clear(); AssemblySource.Assemblies.AddRange(this.SelectAssemblies()); - this.ConfigureResources(); this.Configure(); - this.OnStart(); - View.ViewManager = IoC.Get(); - if (autoLaunch && !Execute.InDesignMode) + if (!Execute.InDesignMode) this.Launch(); } @@ -91,18 +80,6 @@ namespace Stylet IoC.Get().ShowWindow(IoC.Get()); } - /// - /// Add any application resources to the application. Override to add your own, or to avoid Stylet's default resources from being added - /// - protected virtual void ConfigureResources() - { - if (this.Application == null) - return; - - var rc = new ResourceDictionary() { Source = new Uri("pack://application:,,,/Stylet;component/Xaml/StyletResourceDictionary.xaml", UriKind.Absolute) }; - this.Application.Resources.MergedDictionaries.Add(rc); - } - /// /// Override to configure your IoC container, and anything else /// @@ -143,11 +120,6 @@ namespace Stylet /// protected virtual void OnApplicationStartup(object sender, StartupEventArgs e) { } - /// - /// Hook called when the application has started, and Stylet is fully initialised - /// - protected virtual void OnStart() { } - /// /// Hook called on application exit /// diff --git a/Stylet/IBootstrapper.cs b/Stylet/IBootstrapper.cs new file mode 100644 index 0000000..b3d12fd --- /dev/null +++ b/Stylet/IBootstrapper.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace Stylet +{ + /// + /// Interface specifying a bootstrapper, as loaded by the ApplicationLoader + /// + public interface IBootstrapper + { + /// + /// Called during application setup, allowing the bootstrapper to configure itself. + /// Should hook into Application.Startup + /// + /// Reference to the current application + void Setup(Application application); + } +} diff --git a/Stylet/Stylet.csproj b/Stylet/Stylet.csproj index 38f8142..8902c63 100644 --- a/Stylet/Stylet.csproj +++ b/Stylet/Stylet.csproj @@ -47,8 +47,10 @@ + + diff --git a/Stylet/Xaml/ApplicationLoader.cs b/Stylet/Xaml/ApplicationLoader.cs new file mode 100644 index 0000000..d730842 --- /dev/null +++ b/Stylet/Xaml/ApplicationLoader.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace Stylet.Xaml +{ + /// + /// Added to your App.xaml, this is responsible for loading the Boostrapper you specify, and Stylet's other resources + /// + public class ApplicationLoader : ResourceDictionary + { + private ResourceDictionary styletResourceDictionary; + + /// + /// Create a new ApplicationLoader instance + /// + public ApplicationLoader() + { + this.styletResourceDictionary = new ResourceDictionary() { Source = new Uri("pack://application:,,,/Stylet;component/Xaml/StyletResourceDictionary.xaml", UriKind.Absolute) }; + this.LoadStyletResources = true; + } + + private IBootstrapper _bootstrapper; + + /// + /// Bootstrapper instance to use to start your application. This must be set. + /// + public IBootstrapper Bootstrapper + { + get { return _bootstrapper; } + set + { + this._bootstrapper = value; + this._bootstrapper.Setup(Application.Current); + } + } + + private bool _loadStyletResources; + + /// + /// Control whether to load Stylet's own resources (e.g. StyletConductorTabControl). Defaults to true. + /// + public bool LoadStyletResources + { + get { return this._loadStyletResources; } + set + { + this._loadStyletResources = value; + if (this._loadStyletResources) + this.MergedDictionaries.Add(this.styletResourceDictionary); + else + this.MergedDictionaries.Remove(this.styletResourceDictionary); + } + } + } +}