/V2.2/trunk/CAL/Desktop/Composite.UnityExtensions/UnityBootstrapper.cs
# · C# · 308 lines · 177 code · 40 blank · 91 comment · 16 complexity · 7270411f8565eaefbc9ce81584235d51 MD5 · raw file
- //===================================================================================
- // Microsoft patterns & practices
- // Composite Application Guidance for Windows Presentation Foundation and Silverlight
- //===================================================================================
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
- // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
- // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- // FITNESS FOR A PARTICULAR PURPOSE.
- //===================================================================================
- // The example companies, organizations, products, domain names,
- // e-mail addresses, logos, people, places, and events depicted
- // herein are fictitious. No association with any real company,
- // organization, product, domain name, email address, logo, person,
- // places, or events is intended or should be inferred.
- //===================================================================================
- using System;
- using System.Globalization;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Controls.Primitives;
- using Microsoft.Practices.Composite.Events;
- using Microsoft.Practices.Composite.Logging;
- using Microsoft.Practices.Composite.Modularity;
- using Microsoft.Practices.Composite.Presentation.Regions;
- using Microsoft.Practices.Composite.Presentation.Regions.Behaviors;
- using Microsoft.Practices.Composite.Regions;
- using Microsoft.Practices.Composite.UnityExtensions.Properties;
- using Microsoft.Practices.ServiceLocation;
- using Microsoft.Practices.Unity;
-
- namespace Microsoft.Practices.Composite.UnityExtensions
- {
- /// <summary>
- /// Base class that provides a basic bootstrapping sequence that
- /// registers most of the Composite Application Library assets
- /// in a <see cref="IUnityContainer"/>.
- /// </summary>
- /// <remarks>
- /// This class must be overriden to provide application specific configuration.
- /// </remarks>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable")]
- public abstract class UnityBootstrapper
- {
- private readonly ILoggerFacade loggerFacade = new TextLogger();
- private bool useDefaultConfiguration = true;
-
- /// <summary>
- /// Gets the default <see cref="IUnityContainer"/> for the application.
- /// </summary>
- /// <value>The default <see cref="IUnityContainer"/> instance.</value>
- [CLSCompliant(false)]
- public IUnityContainer Container { get; private set; }
-
- /// <summary>
- /// Gets the default <see cref="ILoggerFacade"/> for the application.
- /// </summary>
- /// <value>A <see cref="ILoggerFacade"/> instance.</value>
- protected virtual ILoggerFacade LoggerFacade
- {
- get { return this.loggerFacade; }
- }
-
- /// <summary>
- /// Runs the bootstrapper process.
- /// </summary>
- public void Run()
- {
- this.Run(true);
- }
-
- /// <summary>
- /// Run the bootstrapper process.
- /// </summary>
- /// <param name="runWithDefaultConfiguration">If <see langword="true"/>, registers default Composite Application Library services in the container. This is the default behavior.</param>
- public void Run(bool runWithDefaultConfiguration)
- {
- this.useDefaultConfiguration = runWithDefaultConfiguration;
- ILoggerFacade logger = this.LoggerFacade;
- if (logger == null)
- {
- throw new InvalidOperationException(Resources.NullLoggerFacadeException);
- }
-
- logger.Log("Creating Unity container", Category.Debug, Priority.Low);
- this.Container = this.CreateContainer();
- if (this.Container == null)
- {
- throw new InvalidOperationException(Resources.NullUnityContainerException);
- }
-
-
- logger.Log("Configuring container", Category.Debug, Priority.Low);
- this.Container.AddNewExtension<UnityBootstrapperExtension>();
- this.ConfigureContainer();
-
- logger.Log("Configuring region adapters", Category.Debug, Priority.Low);
-
- this.ConfigureRegionAdapterMappings();
- this.ConfigureDefaultRegionBehaviors();
- this.RegisterFrameworkExceptionTypes();
-
- logger.Log("Creating shell", Category.Debug, Priority.Low);
- DependencyObject shell = this.CreateShell();
- if (shell != null)
- {
- RegionManager.SetRegionManager(shell, this.Container.Resolve<IRegionManager>());
- RegionManager.UpdateRegions();
- }
-
- logger.Log("Initializing modules", Category.Debug, Priority.Low);
- this.InitializeModules();
-
- logger.Log("Bootstrapper sequence completed", Category.Debug, Priority.Low);
- }
-
- /// <summary>
- /// Registers in the <see cref="IUnityContainer"/> the <see cref="Type"/> of the Exceptions
- /// that are not considered root exceptions by the <see cref="ExceptionExtensions"/>.
- /// </summary>
- protected virtual void RegisterFrameworkExceptionTypes()
- {
- ExceptionExtensions.RegisterFrameworkExceptionType(
- typeof(Microsoft.Practices.ServiceLocation.ActivationException));
-
- ExceptionExtensions.RegisterFrameworkExceptionType(
- typeof(Microsoft.Practices.Unity.ResolutionFailedException));
-
- ExceptionExtensions.RegisterFrameworkExceptionType(
- typeof(Microsoft.Practices.ObjectBuilder2.BuildFailedException));
- }
-
- /// <summary>
- /// Configures the <see cref="IUnityContainer"/>. May be overwritten in a derived class to add specific
- /// type mappings required by the application.
- /// </summary>
- protected virtual void ConfigureContainer()
- {
- Container.RegisterInstance<ILoggerFacade>(LoggerFacade);
-
- // We register the container with an ExternallyControlledLifetimeManager to avoid
- // recursive calls if Container.Dispose() is called.
- //Container.RegisterInstance<IUnityContainer>(Container);
-
- IModuleCatalog catalog = GetModuleCatalog();
- if (catalog != null)
- {
- this.Container.RegisterInstance(catalog);
- }
-
- if (useDefaultConfiguration)
- {
- RegisterTypeIfMissing(typeof(IServiceLocator), typeof(UnityServiceLocatorAdapter), true);
- RegisterTypeIfMissing(typeof(IModuleInitializer), typeof(ModuleInitializer), true);
- RegisterTypeIfMissing(typeof(IModuleManager), typeof(ModuleManager), true);
- RegisterTypeIfMissing(typeof(RegionAdapterMappings), typeof(RegionAdapterMappings), true);
- RegisterTypeIfMissing(typeof(IRegionManager), typeof(RegionManager), true);
- RegisterTypeIfMissing(typeof(IEventAggregator), typeof(EventAggregator), true);
- RegisterTypeIfMissing(typeof(IRegionViewRegistry), typeof(RegionViewRegistry), true);
- RegisterTypeIfMissing(typeof(IRegionBehaviorFactory), typeof(RegionBehaviorFactory), true);
-
- ServiceLocator.SetLocatorProvider(() => this.Container.Resolve<IServiceLocator>());
- }
- }
-
- /// <summary>
- /// Configures the default region adapter mappings to use in the application, in order
- /// to adapt UI controls defined in XAML to use a region and register it automatically.
- /// May be overwritten in a derived class to add specific mappings required by the application.
- /// </summary>
- /// <returns>The <see cref="RegionAdapterMappings"/> instance containing all the mappings.</returns>
- protected virtual RegionAdapterMappings ConfigureRegionAdapterMappings()
- {
- RegionAdapterMappings regionAdapterMappings = Container.TryResolve<RegionAdapterMappings>();
- if (regionAdapterMappings != null)
- {
- #if SILVERLIGHT
- regionAdapterMappings.RegisterMapping(typeof(TabControl), this.Container.Resolve<TabControlRegionAdapter>());
- #endif
- regionAdapterMappings.RegisterMapping(typeof(Selector), this.Container.Resolve<SelectorRegionAdapter>());
- regionAdapterMappings.RegisterMapping(typeof(ItemsControl), this.Container.Resolve<ItemsControlRegionAdapter>());
- regionAdapterMappings.RegisterMapping(typeof(ContentControl), this.Container.Resolve<ContentControlRegionAdapter>());
- }
-
- return regionAdapterMappings;
- }
-
- /// <summary>
- /// Configures the <see cref="IRegionBehaviorFactory"/>. This will be the list of default
- /// behaviors that will be added to a region.
- /// </summary>
- protected virtual IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
- {
- var defaultRegionBehaviorTypesDictionary = Container.TryResolve<IRegionBehaviorFactory>();
-
- if (defaultRegionBehaviorTypesDictionary != null)
- {
- defaultRegionBehaviorTypesDictionary.AddIfMissing(AutoPopulateRegionBehavior.BehaviorKey,
- typeof(AutoPopulateRegionBehavior));
-
- defaultRegionBehaviorTypesDictionary.AddIfMissing(BindRegionContextToDependencyObjectBehavior.BehaviorKey,
- typeof(BindRegionContextToDependencyObjectBehavior));
-
- defaultRegionBehaviorTypesDictionary.AddIfMissing(RegionActiveAwareBehavior.BehaviorKey,
- typeof(RegionActiveAwareBehavior));
-
- defaultRegionBehaviorTypesDictionary.AddIfMissing(SyncRegionContextWithHostBehavior.BehaviorKey,
- typeof(SyncRegionContextWithHostBehavior));
-
- defaultRegionBehaviorTypesDictionary.AddIfMissing(RegionManagerRegistrationBehavior.BehaviorKey,
- typeof(RegionManagerRegistrationBehavior));
-
- }
- return defaultRegionBehaviorTypesDictionary;
-
- }
-
- /// <summary>
- /// Initializes the modules. May be overwritten in a derived class to use a custom Modules Catalog
- /// </summary>
- protected virtual void InitializeModules()
- {
- IModuleManager manager;
-
- try
- {
- manager = this.Container.Resolve<IModuleManager>();
- }
- catch (ResolutionFailedException ex)
- {
- if (ex.Message.Contains("IModuleCatalog"))
- {
- throw new InvalidOperationException(Resources.NullModuleCatalogException);
- }
-
- throw;
- }
-
- manager.Run();
- }
-
- /// <summary>
- /// Returns the module catalog that will be used to initialize the modules.
- /// </summary>
- /// <remarks>
- /// When using the default initialization behavior, this method must be overwritten by a derived class.
- /// </remarks>
- /// <returns>An instance of <see cref="IModuleCatalog"/> that will be used to initialize the modules.</returns>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
- protected virtual IModuleCatalog GetModuleCatalog()
- {
- return null;
- }
-
- /// <summary>
- /// Creates the <see cref="IUnityContainer"/> that will be used as the default container.
- /// </summary>
- /// <returns>A new instance of <see cref="IUnityContainer"/>.</returns>
- [CLSCompliant(false)]
- protected virtual IUnityContainer CreateContainer()
- {
- return new UnityContainer();
- }
-
- /// <summary>
- /// Registers a type in the container only if that type was not already registered.
- /// </summary>
- /// <param name="fromType">The interface type to register.</param>
- /// <param name="toType">The type implementing the interface.</param>
- /// <param name="registerAsSingleton">Registers the type as a singleton.</param>
- protected void RegisterTypeIfMissing(Type fromType, Type toType, bool registerAsSingleton)
- {
- ILoggerFacade logger = LoggerFacade;
-
- if (Container.IsTypeRegistered(fromType))
- {
- logger.Log(
- String.Format(CultureInfo.CurrentCulture,
- Resources.TypeMappingAlreadyRegistered,
- fromType.Name), Category.Debug, Priority.Low);
- }
- else
- {
- if (registerAsSingleton)
- {
- Container.RegisterType(fromType, toType, new ContainerControlledLifetimeManager());
- }
- else
- {
- Container.RegisterType(fromType, toType);
- }
- }
- }
-
- /// <summary>
- /// Creates the shell or main window of the application.
- /// </summary>
- /// <returns>The shell of the application.</returns>
- /// <remarks>
- /// If the returned instance is a <see cref="DependencyObject"/>, the
- /// <see cref="UnityBootstrapper"/> will attach the default <seealso cref="IRegionManager"/> of
- /// the application in its <see cref="RegionManager.RegionManagerProperty"/> attached property
- /// in order to be able to add regions by using the <seealso cref="RegionManager.RegionNameProperty"/>
- /// attached property from XAML.
- /// </remarks>
- protected abstract DependencyObject CreateShell();
- }
- }