Search code examples
c#wpf

My service collection doesn't recognize my dependency injection


Service isn't registered to be used in ViewModel

Hello I'm asking this desperately because i can't find a solution. Im doing a mvvm prject in wpf with dependency injection and i got this clases.

public class ObservableObject : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler? PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
 public abstract class ViewModelCore:ObservableObject
    {

    }
 public class NavigationService : ObservableObject, INavigationService
    {
        private ViewModelCore _currentView;
        private Func<Type, ViewModelCore> _viewModelFactory;

        public ViewModelCore CurrentView
        {
            get => _currentView;
            private set
            {
                _currentView = value;
                OnPropertyChanged();
            }
        }
        public NavigationService(Func<Type,ViewModelCore> viewModelFactory)
        {
            _viewModelFactory = viewModelFactory;
        }

         
        public void NavigateTo<TViewModel>() where TViewModel : ViewModelCore
        {
            ViewModelCore viewModel = _viewModelFactory.Invoke(typeof(TViewModel));
            CurrentView = viewModel;
        }

    }
public class MainViewModel:ViewModelCore
    {

        private INavigationService _navigation;
        public INavigationService Navigation
        {
            get => _navigation;
            set
            {
                _navigation = value;
                OnPropertyChanged();
            }
        }

        public RelayCommand NavigationHomeCommand { get; set; }
        public RelayCommand NavigationPatientListViewCommand { get; set; }
        public RelayCommand NavigationAppointmentsViewCommand { get; set; }
        public MainViewModel(INavigationService navService)
        {
            Navigation = navService;
            NavigationHomeCommand = new RelayCommand(o => true, o => { Navigation.NavigateTo<HomeViewModel>(); });
            NavigationPatientListViewCommand = new RelayCommand(o => true, o => { Navigation.NavigateTo<PatientListViewModel>(); });
            NavigationAppointmentsViewCommand = new RelayCommand(o => true, o => { Navigation.NavigateTo<AppointmentViewModel>(); });

        }
    }
public partial class App : Application
    {
        private ServiceProvider _serviceProvider;

        
        public App()
        {

            IServiceCollection services = new ServiceCollection();
            services.AddSingleton(
                provider => new MainWindow
                {
                    DataContext = provider.GetRequiredService<MainViewModel>()
                }
                );

            services.AddSingleton<MainViewModel>();
            services.AddSingleton<HomeViewModel>();
            services.AddSingleton<PatientListViewModel>();
            services.AddSingleton<AppointmentViewModel>();
            services.AddScoped<INavigationService, NavigationService>();
            services.AddScoped<IAppointmentService, AppointmentService>();
         


            services.AddSingleton<Func<Type, ViewModelCore>>(serviceProvider => viewModelType => (ViewModelCore)serviceProvider.GetRequiredService(viewModelType));


            _serviceProvider = services.BuildServiceProvider();
        }
        protected override void OnStartup(StartupEventArgs e)
        {
        
            var mainWindow = _serviceProvider.GetService<MainWindow>();
            mainWindow.Show();
            base.OnStartup(e);
        }

I get this error message: System.InvalidOperationException: 'Unable to resolve service for type 'Healthplss.Services.GenericDataService`1[Healthplss.Models.Appointment]' while attempting to activate 'Healthplss.Services.AppointmentService'.' Even though the service is resgitered in my app.xaml.cs, I declared also my DI container in my appointment contructor viewmodel to access but it doesn't let me. Anyone know something? thanks in advance.

Edit1: Adding the AppointmentService

public class AppointmentService:IAppointmentService
    {
        private readonly GenericDataService<Appointment> _genericDataService;


        public AppointmentService(GenericDataService<Appointment> genericDataService)
        {
            _genericDataService = genericDataService;
        }

        public async Task AddAppointmentAsync(Models.Appointment appointment)
        {
            await _genericDataService.Create(appointment);
        }

        public Task DeleteAppointmentAsync(int id)
        {
            throw new NotImplementedException();
        }

        public Task GetAppointmentById(int id)
        {
            throw new NotImplementedException();
        }

        public async Task<List<Models.Appointment>> GetAppointmentsAsync()
        {
            return await _genericDataService.GetAll();
        }

        public Task UpdateAppointmentAsync(Models.Appointment appointment)
        {
            throw new NotImplementedException();
        }
    }

I want to write the entity in the database, so im using a generic data service


Solution

  • Looking at your DI registrations I don't see the GenericDataService class being registered. Assuming, based on the namespace of this class from exception, this is your own class, you also need to register it.

    Probably you'd want to assign some interface e.g. IAppointmentDataService to GenericDataService<Appointment> and register it as you've done with other classes:

    services.AddScoped<IAppointmentDataService, GenericDataService<Appointment>>();
    

    If class GenericDataService has constructor with parameters you would also want to ensure that all the types from it's constructor are registered too