namespace Caliburn.Micro { using Caliburn.Micro.Core; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Windows; using System.Windows.Threading; /// /// Inherit from this class in order to customize the configuration of the framework. /// public abstract class BootstrapperBase { readonly bool useApplication; bool isInitialized; /// /// The application. /// protected Application Application { get; set; } /// /// Creates an instance of the bootstrapper. /// /// Set this to false when hosting Caliburn.Micro inside and Office or WinForms application. The default is true. protected BootstrapperBase(bool useApplication = true) { this.useApplication = useApplication; } /// /// Initialize the framework. /// public void Initialize() { if(isInitialized) { return; } isInitialized = true; PlatformProvider.Current = new XamlPlatformProvider(); #if WP8 || NET45 var baseExtractTypes = AssemblySourceCache.ExtractTypes; AssemblySourceCache.ExtractTypes = assembly => { var baseTypes = baseExtractTypes(assembly); var elementTypes = assembly.GetExportedTypes() .Where(t => typeof(UIElement).IsAssignableFrom(t)); return baseTypes.Union(elementTypes); }; AssemblySource.Instance.Refresh(); #endif if(Execute.InDesignMode) { try { StartDesignTime(); }catch { //if something fails at design-time, there's really nothing we can do... isInitialized = false; throw; } } else { StartRuntime(); } } /// /// Called by the bootstrapper's constructor at design time to start the framework. /// protected virtual void StartDesignTime() { AssemblySource.Instance.Clear(); AssemblySource.Instance.AddRange(SelectAssemblies()); Configure(); IoC.GetInstance = GetInstance; IoC.GetAllInstances = GetAllInstances; IoC.BuildUp = BuildUp; } /// /// Called by the bootstrapper's constructor at runtime to start the framework. /// protected virtual void StartRuntime() { EventAggregator.HandlerResultProcessing = (target, result) => { var task = result as System.Threading.Tasks.Task; if (task != null) { result = new IResult[] {task.AsResult()}; } var coroutine = result as IEnumerable; if (coroutine != null) { var viewAware = target as IViewAware; var view = viewAware != null ? viewAware.GetView() : null; var context = new CoroutineExecutionContext { Target = target, View = view }; Coroutine.BeginExecute(coroutine.GetEnumerator(), context); } }; AssemblySourceCache.Install(); AssemblySource.Instance.AddRange(SelectAssemblies()); if (useApplication) { Application = Application.Current; PrepareApplication(); } Configure(); IoC.GetInstance = GetInstance; IoC.GetAllInstances = GetAllInstances; IoC.BuildUp = BuildUp; } /// /// Provides an opportunity to hook into the application object. /// protected virtual void PrepareApplication() { Application.Startup += OnStartup; #if SILVERLIGHT Application.UnhandledException += OnUnhandledException; #else Application.DispatcherUnhandledException += OnUnhandledException; #endif Application.Exit += OnExit; } /// /// Override to configure the framework and setup your IoC container. /// protected virtual void Configure() { } /// /// Override to tell the framework where to find assemblies to inspect for views, etc. /// /// A list of assemblies to inspect. protected virtual IEnumerable SelectAssemblies() { return new[] { GetType().Assembly }; } /// /// Override this to provide an IoC specific implementation. /// /// The service to locate. /// The key to locate. /// The located service. protected virtual object GetInstance(Type service, string key) { #if NET if (service == typeof(IWindowManager)) service = typeof(WindowManager); #endif return Activator.CreateInstance(service); } /// /// Override this to provide an IoC specific implementation /// /// The service to locate. /// The located services. protected virtual IEnumerable GetAllInstances(Type service) { return new[] { Activator.CreateInstance(service) }; } /// /// Override this to provide an IoC specific implementation. /// /// The instance to perform injection on. protected virtual void BuildUp(object instance) { } /// /// Override this to add custom behavior to execute after the application starts. /// /// The sender. /// The args. protected virtual void OnStartup(object sender, StartupEventArgs e) { } /// /// Override this to add custom behavior on exit. /// /// The sender. /// The event args. protected virtual void OnExit(object sender, EventArgs e) { } #if SILVERLIGHT /// /// Override this to add custom behavior for unhandled exceptions. /// /// The sender. /// The event args. protected virtual void OnUnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) { } #else /// /// Override this to add custom behavior for unhandled exceptions. /// /// The sender. /// The event args. protected virtual void OnUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) { } #endif #if SILVERLIGHT && !WINDOWS_PHONE /// /// Locates the view model, locates the associate view, binds them and shows it as the root view. /// /// The view model type. protected void DisplayRootViewFor(Type viewModelType) { var viewModel = IoC.GetInstance(viewModelType, null); var view = ViewLocator.LocateForModel(viewModel, null, null); ViewModelBinder.Bind(viewModel, view, null); var activator = viewModel as IActivate; if(activator != null) activator.Activate(); Mouse.Initialize(view); Application.RootVisual = view; } /// /// Locates the view model, locates the associate view, binds them and shows it as the root view. /// /// The view model type. protected void DisplayRootViewFor() { DisplayRootViewFor(typeof(TViewModel)); } #elif NET /// /// Locates the view model, locates the associate view, binds them and shows it as the root view. /// /// The view model type. /// The optional window settings. protected void DisplayRootViewFor(Type viewModelType, IDictionary settings = null) { var windowManager = IoC.Get(); windowManager.ShowWindow(IoC.GetInstance(viewModelType, null), null, settings); } /// /// Locates the view model, locates the associate view, binds them and shows it as the root view. /// /// The view model type. /// The optional window settings. protected void DisplayRootViewFor(IDictionary settings = null) { DisplayRootViewFor(typeof(TViewModel), settings); } #endif } }