我在WPF应用程序中使用Autofac进行依赖注入,无法解决此问题。
我创建了这个抽象类ListItemViewModelBase
,其中两个类PasswordItemViewModel
和CardItemViewModel
继承。
列表项视图模型库. cs
public abstract class ListItemViewModelBase { protected readonly IMessenger _messenger; public string Id { get; } public string Name { get; } public string Notes { get; } protected ListItemViewModelBase(IMessenger messenger, string id, string name, string notes) { _messenger = messenger; Id = id; Name = name; Notes = notes; } public abstract void SeeDetails(); }
密码项视图模型. cs
public partial class PasswordItemViewModel : ListItemViewModelBase { public string UserName { get; } public string Password { get; } public string Website { get; } public PasswordItemViewModel(IMessenger messenger, string id, string name, string userName, string password, string website, string notes) : base(messenger, id, name, notes) { UserName = userName; Password = password; Website = website; } [RelayCommand] public override void SeeDetails() { _messenger.Send(new PasswordDetailMessage(this)); } }
CardItemViewModel. cs
public partial class CardItemViewModel : ListItemViewModelBase { public string CardNumber { get; } public int ExpMonth { get; } public int ExpYear { get; } public CardItemViewModel(IMessenger messenger, string id, string name, string cardNumber, int expMonth, int expYear, string notes) : base(messenger, id, name, notes) { CardNumber = cardNumber; ExpMonth = expMonth; ExpYear = expYear; } [RelayCommand] public override void SeeDetails() { _messenger.Send(new CardDetailMessage(this)); } }
配置Autofac的App. xaml.cs如下所示:
xaml. cs
public partial class App : Application { public static IServiceProvider ServiceProvider { get; private set; } [STAThread] public static void Main(string[] args) { using IHost host = CreateHostBuilder(args).Build(); CreateGenericHost(host); InitAppAndRun(); } private static void InitAppAndRun() { var app = new App(); app.InitializeComponent(); app.MainWindow = ServiceProvider.GetRequiredService(); app.MainWindow!.Visibility = Visibility.Visible; app.Run(); } #region Host builder private static IHostBuilder CreateHostBuilder(string[] args) { return Host.CreateDefaultBuilder(args) .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureServices(ConfigureServices) .ConfigureContainer(ConfigureAutofacBuilder); } private static void ConfigureAutofacBuilder(HostBuilderContext ctx, ContainerBuilder builder) { builder.RegisterModule>(); builder.RegisterModule>(); var config = new ConfigurationBuilder(); config.AddJsonFile("autofac.json"); var module = new ConfigurationModule(config.Build()); builder.RegisterModule(module); } private static void CreateGenericHost(IHost host) { host.Start(); ServiceProvider = host.Services; } private static void ConfigureServices(HostBuilderContext ctx, IServiceCollection services) { services.AddSingleton(); } #endregion }
当我尝试启动应用程序时,程序在使用IHost host=CreateHostBuilder(args)的上失败。构建();
并抛出此错误消息:
Autofac.Core.Activators.Reflection.NoConstructorsFoundException: 'No accessible constructors were found for the type 'TestApp.Bases.ListItemViewModelBase'.'
似乎Autofac无法解析ListItemViewModelBase
类的非公共构造函数。有没有办法让Autofac解析这些类型的非公共构造函数?
谢了托拜厄斯
对Orenico回复的回应:
这是autoface. json,它基本上什么都不包含。
{ "modules": [], "components": [] }
示例代码中有一些错别字,例如builder. AuthsterModule
然而:
你不能直接实例化抽象类。比如,你不能做new ListItemViewModelBase
。这意味着你不能注册它。你可以将派生类注册为
它,但是即使Autofac可以找到构造函数,你仍然会碰壁,因为它不是具体类。
如果Autofac通过反射来解析一个类型,它不会沿着整个链条看构造函数,它只看你正在解析的东西。这就是为什么听起来你可能试图注册那个抽象类。
如果我不得不猜测,您在这些模块中有一些程序集扫描注册,您没有向我们展示您尝试注册所有视图模型的位置,并且您没有从注册中排除基类。