namespace Caliburn.Micro { using System; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Linq; using System.Reflection; #if !WinRT using System.Windows; using Caliburn.Micro.Core; #else using Windows.UI.Xaml; #endif /// /// A source of assemblies that are inspectable by the framework. /// public static class AssemblySource { /// /// The singleton instance of the AssemblySource used by the framework. /// public static readonly IObservableCollection Instance = new BindableCollection(); /// /// Finds a type which matches one of the elements in the sequence of names. /// public static Func, Type> FindTypeByNames = names => { if (names == null) { return null; } var type = names .Join(Instance.SelectMany(a => a.GetExportedTypes()), n => n, t => t.FullName, (n, t) => t) .FirstOrDefault(); return type; }; } /// /// A caching subsystem for . /// public static class AssemblySourceCache { static bool isInstalled; static readonly IDictionary TypeNameCache = new Dictionary(); /// /// Extracts the types from the spezified assembly for storing in the cache. /// public static Func> ExtractTypes = assembly => assembly.GetExportedTypes() .Where(t => #if !CORE typeof(UIElement).IsAssignableFrom(t) || #endif typeof(INotifyPropertyChanged).IsAssignableFrom(t)); /// /// Installs the caching subsystem. /// public static void Install() { if (isInstalled) return; isInstalled = true; AssemblySource.Instance.CollectionChanged += (s, e) => { switch (e.Action) { case NotifyCollectionChangedAction.Add: e.NewItems.OfType() .SelectMany(a => ExtractTypes(a)) .Apply(t => TypeNameCache.Add(t.FullName, t)); break; case NotifyCollectionChangedAction.Remove: case NotifyCollectionChangedAction.Replace: case NotifyCollectionChangedAction.Reset: TypeNameCache.Clear(); AssemblySource.Instance .SelectMany(a => ExtractTypes(a)) .Apply(t => TypeNameCache.Add(t.FullName, t)); break; } }; AssemblySource.Instance.Refresh(); AssemblySource.FindTypeByNames = names => { if (names == null) { return null; } var type = names.Select(n => TypeNameCache.GetValueOrDefault(n)).FirstOrDefault(t => t != null); return type; }; } } }