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;
};
}
}
}