Внедрение базы данных sqlite в MAUI ViewModels дает ошибку, что ViewModel не определяет конструктор без параметров

Я новичок в MAUI, и у меня есть рабочий проект, который использует базу данных sqlite для хранения моих данных для моего проекта. Я пытаюсь внедрить объект доступа к базе данных в ViewModel для одной из моих страниц содержимого. Раньше у меня это работало, просто создавая («обновляя») мой объект доступа к базе данных, и база данных и проект работали нормально. Когда я изменил это, чтобы внедрить объект доступа к базе данных в конструктор ViewModel, я получаю сообщение об ошибке:

/Users/RemoteCommand/Projects/Notes/Views/AllNotesPage.xaml(9,9): Error: XLS0507: Type 'AllNotes' is not usable as an object element because it is not public or does not define a public parameterless constructor or a type converter. (Notes) IntelliSense

Вот мой файл XAML:

<?xml version = "1.0" encoding = "utf-8" ?>
<ContentPage xmlns = "http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
              xmlns:models = "clr-namespace:Notes.Models"
             x:Class = "Notes.Views.AllNotesPage"
             Title = "AllNotesPage">

    <ContentPage.BindingContext>
        <models:AllNotes />
    </ContentPage.BindingContext>

    <ContentPage.ToolbarItems>
        <!--<ToolbarItem Text = "Add" Clicked = "Add_Clicked" IconImageSource = "{FontImage Glyph='+', Color=White, Size=22}"/>-->
        <ToolbarItem Text = "Add" Command = "{Binding AddClickedCommand}" IconImageSource = "{FontImage Glyph='+', Color=White, Size=22}"/>
    </ContentPage.ToolbarItems>

    <CollectionView x:Name = "notesCollection"
                    ItemsSource = "{Binding Notes}"
                    Margin = "20"
                    SelectionMode = "Single"
                    SelectionChanged = "notesCollection_SelectionChanged">

        <CollectionView.ItemsLayout>
            <LinearItemsLayout Orientation = "Vertical" ItemSpacing = "10"/>
        </CollectionView.ItemsLayout>

        <CollectionView.ItemTemplate>
            <DataTemplate>
                <StackLayout>
                    <Label Text = "{Binding Text}" FontSize = "22"/>
                    <Label Text = "{Binding Date}" FontSize = "14" TextColor = "Silver"/>
                </StackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>

Вот мой код:

namespace Notes.Views;
using Notes.Models;
using Notes.Views;
using Notes.Data;
using CommunityToolkit.Mvvm.Input;

public partial class AllNotesPage : ContentPage
{   
    public AllNotesPage()
    {
        InitializeComponent();
    }
    async void notesCollection_SelectionChanged(System.Object sender, Microsoft.Maui.Controls.SelectionChangedEventArgs e)
    {
        if (e.CurrentSelection.Count != 0)
        {
            var note = (Note)e.CurrentSelection[0];
            await Shell.Current.GoToAsync($"{nameof(NotePage)}?{nameof(NotePage.ItemId)} = {note.ID}");
        }
    }
}

Вот моя ViewModel:

using System;
using System.Collections.ObjectModel;
using Notes.Data;
using Notes.Views;
using CommunityToolkit.Mvvm;
using CommunityToolkit.Mvvm.Input;

namespace Notes.Models;

public partial class AllNotes
{
    NotesDatabase _notesDatabase;

    public ObservableCollection<Note> Notes { get; set; } = new ObservableCollection<Note>();

    public AllNotes(NotesDatabase notesDatabase)
    {
        _notesDatabase = notesDatabase;
        LoadNotes();
    }
    [RelayCommand]
    async void AddClicked()
    {
        await Shell.Current.GoToAsync(nameof(NotePage));
    }
    public async void LoadNotes()
    {
        Notes.Clear();
        List<Note> notes = await _notesDatabase.GetItemsAsync();
        foreach(Note note in notes)
        {
            Notes.Add(note);
        }
    }
}

и вот моя программа MauiProgram, в которой я определяю внедрение зависимостей:

using Microsoft.Extensions.Logging;
using Notes.Views;
using Notes.Models;
using Notes.Data;

namespace Notes;

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");
            });

#if DEBUG
        builder.Logging.AddDebug();
#endif

        builder.Services.AddSingleton<AllNotes>();
        builder.Services.AddSingleton<AllNotesPage>();
        builder.Services.AddSingleton<NotesDatabase>();
        
        return builder.Build();
    }
}

[Примечание: я переключил AddSingleton на Add Transient для этой страницы для этих определений, чтобы посмотреть, решит ли это проблему, но это не так]

Я пробовал очень простую инъекцию зависимостей в более раннем тестовом проекте, где я ввел свой объект доступа к данным в код позади, и я получил ту же ошибку об отсутствии конструктора без параметров, и оказалось, что мне не хватало определения моего объекта доступа к данным И ContentPage как Transient или Singleton в MauiProgram (именно поэтому для этого проекта я добавил объект доступа к данным, ContentPage и ViewModel как Singletons в MauiProgram). Как только я это сделал, это сработало, но теперь, когда я использую ViewModel, которую я связываю в XAML, я не могу заставить DI работать для ViewModel.

Пожалуйста, помогите этому новичку!

Искренне,

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
91
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Выполнение этого в XAML является открытым вопросом: Разрешить XAML BindingContext из ServiceCollection.

На данный момент сделайте это с помощью конструктора кода с параметром:

public AllNotesPage(AllNotes vm)
{
    InitializeComponent();
    BindingContext = vm;
}

DI введет vm, создав необходимый экземпляр AllNotes и его базы данных NotesDatabase.

Другие вопросы по теме