【发布时间】:2023-01-12 07:44:48
【问题描述】:
几年前,我创建了一套用于 CQRS 的 nuget 包,它使用 AutoFac 模块来连接内部结构。我想在我的 .NET MAUI 开发中使用它,所以我已将它们更新到 .NET 6.0,并且它们很好地链接到我的 MAUI 项目,但我不确定我的注册中缺少什么。我的框架的 AutoFac 模块注册了一个 IDateTimeService,但是当我将其添加到已注册类的构造函数时,它无法解析。
因此,按照 .NET Core 的 AutoFac 指南,我添加了 Populate 调用,然后加载 AutoFac 模块。
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Pages;
using Perigee.Framework.Services;
using Services;
using ViewModels;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
builder.Services.AddSingleton<IAppNavigationService, AppNavigationService>();
builder.Services.AddSingleton<AppShellViewModel>();
builder.Services.AddTransient<MainPageViewModel>();
builder.Services.AddSingleton<AppShell>();
builder.Services.AddSingleton<MainPage>();
// Hook in AutoFac for the PerigeeFramework services
var autofacBuilder = new ContainerBuilder();
autofacBuilder.Populate(builder.Services);
autofacBuilder.RegisterModule(new ServicesModule());
autofacBuilder.Build(); // Invokes the Load method on the registered Modules.
return builder.Build();
}
}
AutoFac 模块是这样启动的:
public class ServicesModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register(c =>
{
var config = c.IsRegistered<IDateTimeConfig>() ? c.Resolve<IDateTimeConfig>() : null;
return new DateTimeService(config);
}).As<IDateTimeService>().InstancePerLifetimeScope();
这是 AppShellViewModel 的定义
public AppShellViewModel(IDateTimeService dateTimeService)
注入到 AppShell 中:
public partial class AppShell : Shell
{
public AppShell(AppShellViewModel viewModel)
{
InitializeComponent();
BindingContext = viewModel;
在运行时,IDateTimeService 不会解析。我也试过只在没有模块的情况下注册 AutoFac,但它无法解决:
// Hook in AutoFac for the PerigeeFramework services
var autofacBuilder = new ContainerBuilder();
autofacBuilder.Populate(builder.Services);
autofacBuilder.RegisterType<DateTimeService>().As<IDateTimeService>().SingleInstance();
var cont = autofacBuilder.Build();
return builder.Build();
}
我需要 .NET DI 以外的东西的关键原因是因为架构利用了装饰器,SimpleInjector 和 AutfoFac 提供了开箱即用的功能,所以我选择了 AutoFac。在任何一种情况下,我都需要使用这种“交叉线”方法来使用 AutoFac 和 .NET DI,因为 MAUI 使用的是内置的。有谁知道我错过了什么步骤阻止 AutoFac 模块的注册出现在 IServiceCollection 中,或者我可以在 MauiApp 上用 AutoFac 完全替换 .NET DI 吗?
编辑: 我整理了一个精简版的应用程序。我想也许我需要将一个新的 AutoFacServiceProvider 传递给应用程序,并且 ISomeService 在向 AutoFac 注册时确实解析了
但是如果我尝试将 ISomeService 注入另一个已注册的类,对 MainPage = serviceProvider.GetService<AppShell>() 的调用将无法解决。如果该服务在标准 DI 中注册,它将工作。
有人知道如何传播 Maui 将使用的 AutoFac 服务提供商吗?项目是here
【问题讨论】:
标签: autofac .net-6.0 .net-maui autofac-module