【发布时间】:2021-03-14 13:16:45
【问题描述】:
我正在尝试使用 Autofac 覆盖在 Avalonia 和 ReactiveUI 中使用的 DI 容器。到目前为止,我已经尝试关注instructions in the Splat.Autofac repository,但我无法让 Avalonia 工作。
作为一个工作示例,我采用了HelloWorld example from the ReactiveUI.Samples 存储库。
我可以想到两个地方来覆盖 Splat。在App.xaml.cs 中OnFrameworkInitializationCompleted 方法中:
using System.Reflection;
using Autofac;
using Avalonia;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
using Avalonia.Threading;
using ReactiveUI;
using Splat;
using Splat.Autofac;
namespace ReactiveAvalonia.HelloWorld {
public class App : Application {
public override void Initialize() {
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
// Build a new Autofac container.
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces();
// Use Autofac for ReactiveUI dependency resolution.
// After we call the method below, Locator.Current and
// Locator.CurrentMutable start using Autofac locator.
AutofacDependencyResolver resolver = new AutofacDependencyResolver(builder);
Locator.SetLocator(resolver);
// These .InitializeX() methods will add ReactiveUI platform
// registrations to your container. They MUST be present if
// you *override* the default Locator.
Locator.CurrentMutable.InitializeSplat();
Locator.CurrentMutable.InitializeReactiveUI();
var container = builder.Build();
resolver.SetLifetimeScope(container);
}
}
}
但是在运行时,启动失败并出现以下异常:
System.ArgumentException: '不知道如何检测 ReactiveAvalonia.HelloWorld.MainView 何时激活/停用,您可能需要实现 IActivationForViewFetcher'
我的另一个想法是在Program.cs 的Main 中进行覆盖:
using System.Reflection;
using Autofac;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Logging.Serilog;
using Avalonia.ReactiveUI;
using Avalonia.Threading;
using ReactiveUI;
using Splat;
using Splat.Autofac;
namespace ReactiveAvalonia.HelloWorld {
// You may want to start here:
// https://reactiveui.net/docs/getting-started/
class Program {
// http://avaloniaui.net/docs/reactiveui/
// https://github.com/AvaloniaUI/Avalonia/wiki/Application-lifetimes
public static AppBuilder BuildAvaloniaApp() {
return AppBuilder
.Configure<App>()
.UseReactiveUI()
.UsePlatformDetect()
.LogToDebug();
}
private static void AppMain(Application app, string[] args) {
app.Run(new MainView());
}
public static void Main(string[] args) {
// Build a new Autofac container.
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces();
// Use Autofac for ReactiveUI dependency resolution.
// After we call the method below, Locator.Current and
// Locator.CurrentMutable start using Autofac locator.
AutofacDependencyResolver resolver = new AutofacDependencyResolver(builder);
Locator.SetLocator(resolver);
// These .InitializeX() methods will add ReactiveUI platform
// registrations to your container. They MUST be present if
// you *override* the default Locator.
Locator.CurrentMutable.InitializeSplat();
Locator.CurrentMutable.InitializeReactiveUI();
var container = builder.Build();
resolver.SetLifetimeScope(container);
BuildAvaloniaApp().Start(AppMain, args);
}
}
}
但这失败了,还有一个例外:
System.Exception: '容器已经构建并且生命周期范围设置,所以不能再修改它。'
我该怎么做才能让它发挥作用?
【问题讨论】:
标签: c# autofac reactiveui avaloniaui