Search code examples
c#.netclass-librarymaui

How do I access the "importer" classes in a Class Library? (.NET MAUI/C#)


I have developed a .NET MAUI app for my company. To do so, I created some "Core" classes in the project that helped me develop the project.

For example, I created a "Navigation" class that handled page navigation in my project.

I have been asked to develop a second app, and I wanted to reuse some of the "Core" classes, since they would be useful in this project as well.

I created a .NET MAUI Class Library (to prevent just copypasting the classes). The problem is that I want to access some of the classes in the project that is going to import my class library.

Following with the above "Navigation" example, it would work like this if the class is in the App1 project.

destinationNavPage = new NavigationPage(new WhateverPage());
App.Current.MainPage = destinationNavPage;

This works fine. It changes the active page to a new specified page.

However, you can't do this in a class library, since both "WhateverPage" and "App" are in the App namespace, and the class library does not know they exist.

Since the "WhateverPage" is going to be a passed argument to the function and all default MAUI projects instantiate the "App" class, I can be completely sure these will both exist in the destination app.

The problem is, how do I access these classes in the project/namespace that is going to import my class library, from the class library?

Thanks in advance.


Solution

  • By definition, a class library does not, and cannot, know anything about the client project that uses it.

    The solution is to create something in the library, that the client calls during app startup, to tell the library what it needs to know.


    SOLUTION 1: Define an Interface

    In OO languages, one simple mechanism to do so is to define an interface in the library, that the client project should implement.

    Define in your library:

    namespace MyLibrary;
    public interface ICallMe
    {
        void TheCall(object aParameter);
    }
    public class StartMe
    {
        static ICallMe Callback;
        public static void Init(ICallMe callback)
        {
            Callback = callback;
        }
    
        // Usage:
        Callback.TheCall(...);
    

    Define in your main project:

    class MyCallMe : MyLibrary.ICallMe
    {
        public void TheCall(object aParameter)
        {
            ...
        }
    }
    

    In your app startup:

    MyLibrary.StartMe.Init(new MyCallMe());
    

    If you want to get at functionality that can't be re-defined to implement MyLibrary.ICallMe, then make a wrapper class. I'll show how to set App.Current.MainPage.

    public interface ICallMe
    {
        void SetCurrentPage(Page newPage);
    }
    
        // Usage (assumes "Callback" defined above):
        Callback.SetCurrentPage(...);
    

    Wrapper class in main app project:

    class MyLibraryCallbacks: MyLibrary.ICallMe
    {
        public void SetCurrentPage(Page newPage)
        {
            App.Current.MainPage = newPage;
        }
    

    Modify as needed.


    SOLUTION 2: Dependency Injection

    TBD: Maybe there is a way to apply Maui's Dependency Injection to the library.

    If so, then during app startup you'd have code setting up "MyLibraryCallbacks" as the implementor of "MyLibrary.ICallMe".

    I don't know if this is possible.