[GH-ISSUE #63] Support for dependency injection in Models #33

Closed
opened 2026-05-05 11:00:18 -06:00 by gitea-mirror · 0 comments
Owner

Originally created by @MaxMommersteeg on GitHub (Aug 20, 2018).
Original GitHub issue: https://github.com/qmlnet/qmlnet/issues/63

Currently working on a simple todo application (https://github.com/MaxMommersteeg/Qml.Net.TodoApp) and trying to use a repository in my model. I tend to use the Models (as seen in the examples) as my controller (like a controller in mvc). Creating a controller/model without a parameterless constructor throws a System.MissingMethodException exception.

I setup my dependency injection as follows:

Program.cs

 // Dependency injection.
var serviceCollection = new ServiceCollection();

var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = "todoApp.db" };
var connectionString = connectionStringBuilder.ToString();

serviceCollection.AddDbContext<TodoAppDbContext>(options => options.UseSqlite(connectionString));
serviceCollection.AddSingleton<ITodoItemRepository, TodoItemRepository>();

var serviceProvider = serviceCollection.BuildServiceProvider();

serviceProvider.GetService<TodoAppDbContext>();

using (var dbContext = serviceProvider.GetService<TodoAppDbContext>())
{
    await dbContext.EnsureSeedData();
}

TodoItemsController.cs

public class TodoItemsController
{
    private readonly ITodoItemRepository _todoItemRepository;

    private IList<TodoItemModel> _todoItems = new List<TodoItemModel>();

    public TodoItemsController(ITodoItemRepository todoItemRepository)
    {
        _todoItemRepository = todoItemRepository;
    }

    [NotifySignal]
    public IList<TodoItemModel> TodoItems
    {
        get { return _todoItems; }
        private set { _todoItems = value; }
    }

    public async Task AddTodoItem(string title)
    {
        await _todoItemRepository.Add(new Core.Entities.TodoItem
            {
                Title = title,
            })
            .ConfigureAwait(false);

        await UpdateTodoItems()
            .ConfigureAwait(false);
    }

    public async Task MarkAsDone(int todoItemId)
    {
        var todoItem = await _todoItemRepository.Get(todoItemId)
            .ConfigureAwait(false);
        if (todoItem == null)
        {
            return;
        }

        todoItem.CompletedAt = DateTime.UtcNow;

        await _todoItemRepository.Update(todoItem)
            .ConfigureAwait(false);

        await UpdateTodoItems()
            .ConfigureAwait(false);
    }

    public async Task DeleteTodoItem(int todoItemId)
    {
        await _todoItemRepository.Delete(todoItemId)
            .ConfigureAwait(false);

        await UpdateTodoItems()
            .ConfigureAwait(false);
    }

    private async Task UpdateTodoItems()
    {
        _todoItems = (await _todoItemRepository.GetAll().ConfigureAwait(false)).ToModel();
        this.ActivateSignal("todoItemsChanged");
    }
}

Exception

System.MissingMethodException: 'No parameterless constructor defined for this object.'

You can clone and run the TodoApp.FrontEnd project to reproduce the problem. Any ideas on how to handle dependency injection?

Originally created by @MaxMommersteeg on GitHub (Aug 20, 2018). Original GitHub issue: https://github.com/qmlnet/qmlnet/issues/63 Currently working on a simple todo application (https://github.com/MaxMommersteeg/Qml.Net.TodoApp) and trying to use a repository in my model. I tend to use the `Models` (as seen in the examples) as my controller (like a controller in mvc). Creating a controller/model without a parameterless constructor throws a `System.MissingMethodException` exception. I setup my dependency injection as follows: ### Program.cs ```csharp // Dependency injection. var serviceCollection = new ServiceCollection(); var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = "todoApp.db" }; var connectionString = connectionStringBuilder.ToString(); serviceCollection.AddDbContext<TodoAppDbContext>(options => options.UseSqlite(connectionString)); serviceCollection.AddSingleton<ITodoItemRepository, TodoItemRepository>(); var serviceProvider = serviceCollection.BuildServiceProvider(); serviceProvider.GetService<TodoAppDbContext>(); using (var dbContext = serviceProvider.GetService<TodoAppDbContext>()) { await dbContext.EnsureSeedData(); } ``` ### TodoItemsController.cs ```csharp public class TodoItemsController { private readonly ITodoItemRepository _todoItemRepository; private IList<TodoItemModel> _todoItems = new List<TodoItemModel>(); public TodoItemsController(ITodoItemRepository todoItemRepository) { _todoItemRepository = todoItemRepository; } [NotifySignal] public IList<TodoItemModel> TodoItems { get { return _todoItems; } private set { _todoItems = value; } } public async Task AddTodoItem(string title) { await _todoItemRepository.Add(new Core.Entities.TodoItem { Title = title, }) .ConfigureAwait(false); await UpdateTodoItems() .ConfigureAwait(false); } public async Task MarkAsDone(int todoItemId) { var todoItem = await _todoItemRepository.Get(todoItemId) .ConfigureAwait(false); if (todoItem == null) { return; } todoItem.CompletedAt = DateTime.UtcNow; await _todoItemRepository.Update(todoItem) .ConfigureAwait(false); await UpdateTodoItems() .ConfigureAwait(false); } public async Task DeleteTodoItem(int todoItemId) { await _todoItemRepository.Delete(todoItemId) .ConfigureAwait(false); await UpdateTodoItems() .ConfigureAwait(false); } private async Task UpdateTodoItems() { _todoItems = (await _todoItemRepository.GetAll().ConfigureAwait(false)).ToModel(); this.ActivateSignal("todoItemsChanged"); } } ``` ### Exception `System.MissingMethodException: 'No parameterless constructor defined for this object.'` You can clone and run the `TodoApp.FrontEnd` project to reproduce the problem. Any ideas on how to handle dependency injection?
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/qmlnet#33
No description provided.