【问题标题】:WPF with Prism and DryIOC fails when dependency injecting IOption<> settings in .Net Core 3.1在 .Net Core 3.1 中依赖注入 IOption<> 设置时,带有 Prism 和 DryIOC 的 WPF 失败
【发布时间】:2020-03-13 00:21:07
【问题描述】:

我正在将基于 Prism 和 DryIOC 的 WPF 迁移到 .Net Core 3.1。我发现 DryIOC 在涉及 .net 核心配置功能时无法处理依赖关系解析。我已经尝试注入 IOption、IConfiguration 等,使用 .Net Core Configuration 的任何内容都不会在不引发异常的情况下解决。

我认为 DryIOC 可能与 Microsoft DI 不完全兼容,但我已经进行了许多沙盒尝试,表明 DryIOC 确实适用于使用 .Net Core 的 Web 项目。我还证明了我可以在不使用 Prism 和 DryIOC 的情况下让 WPF 项目工作。我有一个示例应用程序,它显示了我遇到的问题。

该示例解析一个类对象并尝试将配置部分从文件 appsettings.json 解析到 MainWindowViewModel。我的类对象解析得很好,但是在尝试使用此代码解析 IOptions 时崩溃了

public MainWindowViewModel(
    IUser user
    // Comment out the next line to avoid the DI exception
    , IOptions<AppSettings> settings
)
{
    _user = user;

    // Comment out the next line to avoid the DI exception
    _settings = settings;
}

ConfigurationBuilder的设置代码如下:

    public static IConfiguration Configuration { get; set; } = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile(
            $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json",
            optional: true)
        .AddEnvironmentVariables()
        .Build();

    public IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseServiceProviderFactory(new DryIocServiceProviderFactory(container: Container.GetContainer()))
            .ConfigureServices((hostContext, services) =>
            {
                // <-- Here is where I'm using IOptions<AppSettings> dependency object -->
                services.Configure<AppSettings>(Configuration.GetSection(nameof(AppSettings)));
            })
            .ConfigureContainer<Container>((hostContext, container) =>
            {
                // <-- the debugger shows right here, the IOptions<> stuff is in the container -->
                var stuff = container.GetServiceRegistrations();
            });

        var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            ;

        Configuration = builder.Build();

        CreateHostBuilder(args: new string[] { }).Build();

请参阅示例项目以了解整个设置。 https://1drv.ms/u/s!AvdDo8v2RmDrjDeBRHfhkHH_kXbK?e=37GHDF

我得到以下异常

无法解析 WpfPrismCore.ViewModels.MainWindowViewModel IsResolutionCall 来自没有范围的容器 使用带有 {AutoConcreteTypeResolution} 的规则 与 Made={FactoryMethod=ConstructorWithResolvableArguments} 未找到服务注册的地方 并且在 0 个 Rules.DynamicServiceProviders 中找不到动态注册 在 Rules.UnknownServiceResolvers 的 1 中找不到任何内容

在 D:\Dev\DryIoc\src\DryIoc\Container.cs:line 10684 中的 DryIoc.Throw.It(Int32 错误,对象 arg0,对象 arg1,对象 arg2,对象 arg3) 在 D:\Dev\DryIoc\src\DryIoc\Container.cs:line 939 中的 DryIoc.Container.TryThrowUnableToResolve(Request request) 在 D:\Dev\DryIoc\src\DryIoc\Container.cs:line 918 中的 DryIoc.Container.DryIoc.IContainer.ResolveFactory(请求请求) 在 D:\Dev\DryIoc\src\DryIoc\Container.cs:line 256 中的 DryIoc.Container.ResolveAndCacheFactoryDe​​legate(Type serviceType, IfUnresolved ifUnresolved) 在 D:\Dev\DryIoc\src\DryIoc\Container.cs:line 230 中的 DryIoc.Container.DryIoc.IResolver.Resolve(Type serviceType, IfUnresolved ifUnresolved) 在 D:\Dev\DryIoc\src\DryIoc\Container.cs:line 5884 中的 DryIoc.Resolver.Resolve(IResolver resolver, Type serviceType) 在 Prism.DryIoc.Ioc.DryIocContainerExtension.Resolve(类型类型) 在 Prism.PrismApplicationBase.b__6_0(对象视图,类型类型) 在 Prism.Mvvm.ViewModelLocationProvider.AutoWireViewModelChanged(对象视图,Action`2 setDataContextCallback) 在 Prism.Mvvm.ViewModelLocator.AutoWireViewModelChanged(DependencyObject d,DependencyPropertyChangedEventArgs e) 在 System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e) 在 System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e) 在 System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs 参数) 在 System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex、DependencyProperty dp、PropertyMetadata 元数据、EffectiveValueEntry oldEntry、EffectiveValueEntry& newEntry、Boolean coerceWithDeferredReference、Boolean coerceWithCurrentValue、OperationType operationType) 在 System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp、对象值、PropertyMetadata 元数据、布尔 coerceWithDeferredReference、布尔 coerceWithCurrentValue、OperationType operationType、布尔 isInternal) 在 System.Windows.DependencyObject.SetValue(DependencyProperty dp,对象值) 在 System.Windows.Baml2006.WpfMemberInvoker.SetValue(对象实例,对象值) 在 MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(XamlMember 成员,对象 obj,对象值) 在 MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(Object inst, XamlMember property, Object value)

【问题讨论】:

    标签: wpf .net-core configuration prism


    【解决方案1】:

    尝试在 ConfigureServices 第一行添加。

    services.TryAddSingleton(typeof(IOptionsSnapshot<>),typeof(OptionsManager<>));
    

    【讨论】:

      猜你喜欢
      • 2017-03-15
      • 2021-09-11
      • 2020-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多