Home > database >  Dependency injection for open type generic interface and closed type class
Dependency injection for open type generic interface and closed type class

Time:06-23

I have a generic interface IViewModelService.cs

public interface IViewModelService<T> where T : class
{
    public Task<T> Get(); // returns a view model
}

Which is implemented by two different View Model Services that I assume are closed types:

public class HomeViewModelService : IViewModelService<HomeViewModel>
{
    public HomeViewModelService()
    {
        // Dependency injection for Db Context here
    }

    public async Task<HomeViewModel> Get()
    {
        //requires some async _dbContext logic
        return new HomeViewModel(); // for testing purposes
    }
}

and

public class ProfileViewModelService : IViewModelService<ProfileViewModel>
{
    public ProfileViewModelService()
    {
        // Dependency injection for Db Context here
    }

    public async Task<ProfileViewModel> Get()
    {
        //requires some async _dbContext logic
        return new ProfileViewModel(); // for testing purposes
    }
}

Been researching on dependency injection, and I wanted to know how would I be able to implement these services into Startup.cs. I tried these:

services.AddTransient(typeof(IViewModelService<>), typeof(HomeViewModelService)); 

// ERROR: Open generic service type 'IViewModelService`1[T]' requires registering an open generic implementation type. (Parameter 'descriptors')'
services.AddTransient(typeof(IViewModelService<HomeViewModelService>), typeof(HomeViewModelService)); 

// ERROR: Implementation type 'HomeViewModelService' can't be converted to service type 'IViewModelService`1[HomeViewModelService]'

services.AddScoped<IViewModelService<HomeViewModelService>, HomeViewModelService>(); 

// ERROR: This type cannot be used as a type parameter 'TImplementation' in the generic type or method. 
// There is no implicit reference conversion from HomeViewModelService to IViewModelService<HomeViewModelService>

CodePudding user response:

Try

 services.AddScoped<IViewModelService<HomeViewModel>, HomeViewModelService>();

Read enter image description here

  • Related