我有 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 设备吗?我该如何处理?
尝试在 .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 的,但我认为是一样的。
希望这有帮助。如果有任何疑问请留言。