Q. How do you get a list of classes under a namespace without instantiating those classes: Reflection
This is the third of three articles; This Article:
Previous articles in this series cover:
Part 1: Refactoring the Project folder and XAML namespace directives
PS: Don’t miss the Footnote at the bottom.
(Recap)
In the article on Xamarin.Forms Xaml Samples, ”Part 5. From Data Bindings to MVVM”, towards the end it presents an app ”Implementing a Navigation Menu” that displays a menu of sample Content pages. The menu lists a Title and Description for each page as well as the page types which get instantiated upon menu selection. The project,, as available on GitHub, has numerous XAMLContent pages, their C# Codebehind pages, some corresponding PageView classes as well as some miscellaneous function classes (called directly from the XAMLcode), all in one humongous project root folder. The sample code explicitly lists each of the pages. Wouldn’t it be “nicer” to implicitly extract the list via the pages’ new namespace. This article discusses getting a list of the Codepages that have been moved into the Views folder and to the XamlSamples.Views namespace, directly form the namespace. That is without instantiating the pages. Reflection is used to implement this.
https://docs.microsoft.com/en-au/xamarin/xamarin-forms/xaml/xaml-basics/data-bindings-to-mvvm
https://github.com/xamarin/xamarin-forms-samples
https://github.com/xamarin/xamarin-forms-samples/tree/master/XamlSamples
My Current Master on GitHub (Latest)XAMLSamples folder therein
[1] XAML namespace mapping: Refactor the project folder: Move files in conceptual folders
[2] MetaInfo: Encapsulate the pages’ metainformation (Title and Description) in the pages’ codebehind.
[3] Refection: Use Reflection to get a collection of pages in XamlSamples.Views. (For this article)
The static constructor is modifies, as below, to use Reflection, and Linq (need using for both), to collect all of the CodePages in the XamlSamples.Views namespace without instantiating any of the pages. Note, ordered by page class Name property.
namespace XamlSamples { public class PageDataViewModel { static int mode = 3; public Type Type { private set; get; } public string Title { private set; get; } public string Description { private set; get; } public PageDataViewModel(Type type) { } //Constructor private string GetPropDescription(Type type, string prop) { } private string GetClassDescription(Type type) { } private string GetStaticProperty(Type type, string prop) {} static PageDataViewModel() { string @namespace = "XamlSamples.Views"; IEnumerable<Type> types = Assembly.GetExecutingAssembly().GetTypes() .Where(t => t.IsClass && t.Namespace == @namespace && t.IsSubclassOf(typeof(Xamarin.Forms.ContentPage))) .ToList().OrderBy(cp => cp.Name); All = new List<PageDataViewModel>(); foreach (Type t in types) { All.Add(new PageDataViewModel(t)); } } public static IList<PageDataViewModel> All { private set; get; } } }
The Revamped PageDataViewModel class (Prototypes only shown for constructor and methods).
Nb: Used a couple of StackOverFlow references for this:
GetSubtypes: Getting all types in a namespace via reflectionRe:IsSubclassOf: How do I check if a type is a subtype OR the type of an object?
This set of articles presents a pattern for presenting a list of XAML pages, all under specific namespace, as a menu for selection (to instantiate) without instantiating or explicitly listing the pages.
A subsequent refactoring was performed:
See the MetaInfo class listing on GitHub here.
See the simplified PageDataView class listing on GitHub here.
Latest Version of XamlSamples here.
Nb: By encapsulating those functions into the MetaInfo class their functionality can then be reused elsewhere simply by including that class code in other projects