ninject / Ninject

the ninja of .net dependency injectors
http://ninject.org/
Other
2.68k stars 530 forks source link

Passing argument into ninject Provier #363

Open HoomanBahreini opened 5 years ago

HoomanBahreini commented 5 years ago

This is a question (not a bug). Please would you be able to provide an example for the following scenario:

I want to create a provider for MyRepository class which has dependency on ApplicationDbContext:

public class MyRepository<TEntity> 
    where TEntity : MyEntity
{
    private ApplicationDbContext _dbContext;

    public MyRepository(ApplicationDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    // ...
}

I have seen this document which explains how the providers should be created, but I am not sure:

  1. How to pass ApplicationDbConextargument to the provider
  2. How to instantiate a generic type

Here is my attempt:

public class MyRepositoryProvider : Provider<MyRepository> 
{
    protected override MyRepository CreateInstance(IContext context)
    {
        // how to create a generic instance of type T?
        MyRepository myRepository = new MyRepository<T>(/*need ApplicationDbContext*/);
        return myRepository;
    }
}

If this cannot be achieved using a provider, can anyone show how this can be done using Factory interface?

I have asked the same question on stackoverflow

drieseng commented 5 years ago

I'm currently working on a big rewrite of Ninject. If you can provide a (minimal but) complete sample project that you expect to work, I'll try to have a look at how we can support this scenario.

Please also clarify whether a new instance of ApplicationDbContext can be injected into the provider?

HoomanBahreini commented 5 years ago

@drieseng: thanks for your reply.

I have created a code review here

I have some internal services in my infrastructure project, these internal services are hidden from outside world (the web project) where the ninject binding is happening.

The accepted answer is suggesting to use an internal constructor AdPersister (the service which combines the internal services). The would be ideal, because AdPersister can accept its own dependencies... we would put the Provider in the infrastructure layer so it has access to internal services... so ideally, the provider accepts ApplicationDbContext and creates the internal services, but as you can see the implementation of the provider is quite complex.

Please let me know if this code review is sufficient or you would want me to create a repository? The accepted answer has created a gist for this question: here