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