如何读取Maui项目中的dll文件

问题描述 投票:0回答:1

我有 dll 库,我们将其命名为“LibraryA”。我已将其附加到

Application/Resources/Raw/LibraryA.dll
。我只想注册该库中的所有服务和接口,例如:

    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiCommunityToolkit()
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                    fonts.AddFont("Roboto-Regular.ttf", "RobotoRegular");
                    fonts.AddFont("Roboto-Medium.ttf", "RobotoMedium");
                    fonts.AddFont("Roboto-Light.ttf", "RobotoLight");
                })
                ;
            
            RegisterServicesAsync(builder.Services);
            builder.Services.AddSingleton<App>();

            var app = builder.Build();
            return app;
        }


        private static void RegisterServices(IServiceCollection services)
        {
            string dllFileName = "LibraryA.dll";
            var dllPath = Path.Combine(FileSystem.AppDataDirectory, dllFileName);

            var assembly = Assembly.LoadFrom(dllPath);

            var serviceTypes = assembly.GetTypes().Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Any());

            foreach (var implementationType in serviceTypes)
            {
                var interfaceType = implementationType.GetInterfaces().FirstOrDefault();
                if (interfaceType != null)
                {
                    var descriptor = services.FirstOrDefault(d => d.ServiceType == interfaceType);
                    if (descriptor != null)
                    {
                        services.Remove(descriptor);
                    }

                    services.AddSingleton(interfaceType, implementationType);
                }
            }
        }
    }

并且抛出异常,因为路径中没有

LibraryA.dll
文件:
'/data/user/0/com.application/files/LibraryA.dll'
。当我将 LibraryA.dll 复制到该路径时,一切正常。但我无法实现这一点

using var stream = await FileSystem.OpenAppPackageFileAsync(dllFileName);
using var fileStream = File.Create(dllPath);
await stream.CopyToAsync(fileStream);

,因为该代码是异步的,并且有

System.Reflection.TargetInvocationException: 'Exception has been thrown by the target of an invocation.'
,因为服务未注册。有将文件复制到设备的代码:

private static async Task RegisterServicesAsync(IServiceCollection services)
{
    string dllFileName = "LibraryA.dll";
    var dllPath = Path.Combine(FileSystem.AppDataDirectory, dllFileName);

    ****added code below****
    using var stream = await FileSystem.OpenAppPackageFileAsync(dllFileName);
    using var fileStream = File.Create(dllPath);
    await stream.CopyToAsync(fileStream);
    **********************

    var assembly = Assembly.LoadFrom(dllPath);

    var serviceTypes = assembly.GetTypes().Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Any());

    foreach (var implementationType in serviceTypes)
    {
        var interfaceType = implementationType.GetInterfaces().FirstOrDefault();
        if (interfaceType != null)
        {
            var descriptor = services.FirstOrDefault(d => d.ServiceType == interfaceType);
            if (descriptor != null)
            {
                services.Remove(descriptor);
            }

            services.AddSingleton(interfaceType, implementationType);
        }
    }
}

我应该手动将

LibraryA.dll
复制到 Android 设备吗?我该如何处理?

c# dependency-injection maui
1个回答
0
投票

尝试在 .csproj 文件中为 LibraryA.dll 设置构建操作,如下所示:

<ItemGroup>
    <EmbeddedResource Include="LibraryA.dll" />
</ItemGroup>
<ItemGroup>
    <None Remove="LibraryA.dll" />
</ItemGroup>

将我的文件移动到应用程序的 apk 包中对我有用。然后在代码中从APK捆绑包中提取文件将文件移动到APK文件夹我这样做:

var assembly = System.Reflection.Assembly.GetExecutingAssembly();
using (Stream resourceStream = assembly.GetManifestResourceStream(resourceName))
{
    using (var fileStream = new FileStream(destinationPath, FileMode.OpenOrCreate, FileAccess.Write))
    {
      resourceStream.CopyTo(fileStream);
    }
}

其中

resourceName
=
$"{nameof(SolutionName)}.LibraryA.dll"
destinationPath
将此文件移动到哪里 =
Path.Combine(appDataDirectory, "LibraryA.dll")
appDataDirectory
中的
Xamarin.Forms
FileSystem.AppDataDirectory
我不知道这是针对 MAUI 的,但我认为是一样的。

希望这有帮助。如果有任何疑问请留言。

© www.soinside.com 2019 - 2024. All rights reserved.