CompositeWPF is a new framework created by Microsoft to allow developers to build composite user interfaces and modular applications in WPF. Or as I like to call it, build higher quality WPF applications.
The framework is quite easy to get running, I got a sample working in under an hour complete with some pretty cool tricks.
One of the things I modified right away is the module enumerator logic. In the bootstrapper of your application you can specify which module enumerator the application should use to find modules. You can choose between a variaty of enumerators like the configuration enumerator, directory enumerator or the fixed enumerator.
If this isn’t enough for your application you can always make combinations. Although not the easiest task to perform it’s quite feasable. One of the simplest solution for combining enumerators is displayed below
protected override IModuleEnumerator GetModuleEnumerator()
{
ConfigurationModuleEnumerator configurationEnumerator = new ConfigurationModuleEnumerator();
StaticModuleEnumerator enumerator = new StaticModuleEnumerator();
// Add the fixed modules first
enumerator.AddModule(typeof(MainModule));
// Add the dynamic modules that need to be loaded during startup
foreach (ModuleInfo module in configurationEnumerator.GetModules())
{
if (module.StartupLoaded)
{
Assembly moduleAssembly = Assembly.ReflectionOnlyLoadFrom(module.AssemblyFile);
Type moduleType = moduleAssembly.GetType(module.ModuleType);
enumerator.AddModule(moduleType, module.DependsOn.ToArray());
}
}
return enumerator;
}
This loads a set of fixed modules first and then appends the modules from the configuration file. While this method is easy enough to build, it would be much cooler to have a single module enumerator that combines other module enumerators.
public class CompositeModuleEnumerator : IModuleEnumerator
{
private Collection<IModuleEnumerator> _childEnumerators;
/// <summary>
/// Initializes a new instance of the CompositeModuleEnumerator class.
/// </summary>
public CompositeModuleEnumerator()
{
_childEnumerators = new Collection<IModuleEnumerator>();
}
/// <summary>
/// Gets the child enumerators
/// </summary>
public Collection<IModuleEnumerator> ChildEnumerators
{
get { return _childEnumerators; }
}
#region IModuleEnumerator Members
/// <summary>
/// Gets a single module by the specified name
/// </summary>
/// <param name="moduleName"></param>
/// <returns></returns>
public ModuleInfo GetModule(string moduleName)
{
foreach (IModuleEnumerator childEnumerator in _childEnumerators)
{
ModuleInfo module = childEnumerator.GetModule(moduleName);
if (module != null)
return module;
}
return null;
}
/// <summary>
/// Gets all modules
/// </summary>
/// <returns></returns>
public ModuleInfo[] GetModules()
{
List<ModuleInfo> modules = new List<ModuleInfo>();
foreach (IModuleEnumerator childEnumerator in _childEnumerators)
{
modules.AddRange(childEnumerator.GetModules());
}
return modules.ToArray();
}
/// <summary>
/// Gets all modules that need to be loaded at startup
/// </summary>
/// <returns></returns>
public ModuleInfo[] GetStartupLoadedModules()
{
List<ModuleInfo> modules = new List<ModuleInfo>();
foreach (IModuleEnumerator childEnumerator in _childEnumerators)
{
modules.AddRange(childEnumerator.GetStartupLoadedModules());
}
return modules.ToArray();
}
#endregion
}
As soon as I have a login for the CompositeWPFContrib project on codeplex, I will upload these there. In the mean time, enjoy 🙂