MAUI: Dependency injection is not working

Sreejith Sreenivasan 856 Reputation points
2023-09-25T15:21:44.31+00:00

I have a dependency injection in my project for getting the device unique id. It is working fine in my xamarin forms project, but when I add it on my MAUI project the result is blank.

My code

IDevice

public interface IDevice
{
    string GetIdentifier();
}

AndroidDevice

public class AndroidDevice : IDevice
{
    public string GetIdentifier()
    {
        return Android.Provider.Settings.Secure.GetString(Android.App.Application.Context.ContentResolver, Android.Provider.Settings.Secure.AndroidId);
    }
}

IOSDevice

public class IOSDevice : IDevice
{
    [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
    private static extern uint IOServiceGetMatchingService(uint masterPort, IntPtr matching);

    [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
    private static extern IntPtr IOServiceMatching(string s);

    [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
    private static extern IntPtr IORegistryEntryCreateCFProperty(uint entry, IntPtr key, IntPtr allocator, uint options);

    [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
    private static extern int IOObjectRelease(uint o);

    public string GetIdentifier()
    {
        string serial = string.Empty;
        uint platformExpert = IOServiceGetMatchingService(0, IOServiceMatching("IOPlatformExpertDevice"));
        if (platformExpert != 0)
        {
            NSString key = (NSString)"IOPlatformSerialNumber";
            IntPtr serialNumber = IORegistryEntryCreateCFProperty(platformExpert, key.Handle, IntPtr.Zero, 0);
            if (serialNumber != IntPtr.Zero)
            {
                serial = NSString.FromHandle(serialNumber);
                //serial = UIDevice.CurrentDevice.IdentifierForVendor.ToString();
            }
            IOObjectRelease(platformExpert);
        }
        return serial;
    }
}

On this thread I have seen adding the dependency service to DI services.

.Services.AddTransient<IGetDeviceInfo, GetDeviceInfo>();

But when I added that, the AndroidDevice class is not found error is showing like the below screenshot.

User's image

The type or namespace name 'AndroidDevice' could not be found (are you missing a using directive or an assembly reference?)

.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,375 questions
0 comments No comments
{count} votes

Accepted answer
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 74,086 Reputation points Microsoft Vendor
    2023-09-26T07:32:27.0966667+00:00

    Hello,

    If you want to invoke specific platform code, you can use Conditional compilation then execute these sepcific code directly in MAUI.

    For example, you create a class that called GetDevice.cs like following code in the MAUI. You can use different namespaces for iOS and Android platform code, then execute the specific code that wrap Conditional compilation.

    #if ANDROID
    
    using static Android.Provider.Settings;
    
    #elif IOS
    
    using Foundation;
    using System.Runtime.InteropServices;
    #endif
    
    
    namespace MauiApp1;
    
    public  class GetDevice
    {
        public  string GetIdentifier()
        {
            string Identifier = "";
    
    #if ANDROID
            Identifier= Secure.GetString(Microsoft.Maui.ApplicationModel.Platform.CurrentActivity.ContentResolver, Secure.AndroidId);
    
    
    #elif IOS
            [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
             static extern uint IOServiceGetMatchingService(uint masterPort, IntPtr matching);
    
           [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
             static extern IntPtr IOServiceMatching(string s);
    
           [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
             static extern IntPtr IORegistryEntryCreateCFProperty(uint entry, IntPtr key, IntPtr allocator, uint options);
    
           [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
             static extern int IOObjectRelease(uint o);
            string serial = string.Empty;
                uint platformExpert = IOServiceGetMatchingService(0, IOServiceMatching("IOPlatformExpertDevice"));
                if (platformExpert != 0)
                {
                    NSString key = (NSString)"IOPlatformSerialNumber";
                    IntPtr serialNumber = IORegistryEntryCreateCFProperty(platformExpert, key.Handle, IntPtr.Zero, 0);
                    if (serialNumber != IntPtr.Zero)
                    {
                        serial = NSString.FromHandle(serialNumber);
                        //serial = UIDevice.CurrentDevice.IdentifierForVendor.ToString();
                    }
                    IOObjectRelease(platformExpert);
                }
                Identifier=serial;
    #endif
           return Identifier;
    
       }
    }
    

    For example, When you want to get Identifier in the button click event. You can initialize this GetDevice.cs and get value directly.

      private async void Button_Clicked(object sender, EventArgs e)
        {
    #if ANDROID || IOS
            GetDevice getDevice=  new GetDevice();
            var res=getDevice.GetIdentifier();
    
    #endif
       }
    

    Best Regards,

    Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.
    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.