2

Here is how my application makes a call to the database: Web App -> Business Layer -> Data Layer

Everything is using dependency injection.

For example:

In the controller in my Web app I make a call like this:

await _manager.GetCustomers();

Which goes into my Business Layer:

public class CustomerManager : ICustomerManager
{
    private ICustomerRepo _repository;
    public CustomerManager(ICustomerRepo repository)
    {
        _repository = repository;
    }

    public Task<IList<Customer>> GetCustomers(string name = null)
    {
        return _repository.GetCustomers(name);
    }
}

Which goes into my Data Layer:

public class CustomerRepo : BaseRepo, ICustomerRepo
{
    public CustomerRepo(IConfigurationRoot configRoot) 
    : base(configRoot)
    {
    }

    public Customer Find(int id)
    {
        using (var connection = GetOpenConnection())
        {
            ...
        }
    }
}

The trick here is that CustomerRepo inherits from BaseRepo to be able to use the GetOpenConnection() function. But at the same time BaseRepo needs an IConfigurationRoot injected into it from the web application. How can I do both?

public class BaseRepo
{
    private readonly IConfigurationRoot config;

    public BaseRepo(IConfigurationRoot config)
    {
        this.config = config;
    }

    public SqlConnection GetOpenConnection(bool mars = false)
    {
        string cs = config.GetSection("Data:DefaultConnection:ConnectionString").ToString();
        ...
    }
}
5
  • How does the constructor of CustomerRepo look like? Does it take in a IConfigurationRoot and give it to the base constructor? Commented Feb 10, 2016 at 21:00
  • I currently do not have a constructor in my CustomerRepo, I think that might be what I am missing though! I do not understand the syntax for how I would do this. If BaseRepo is in the class declaration and the constructor is declared after this.. How can I ever send it to the BaseRepo as a param? Can you show me an example? Commented Feb 10, 2016 at 21:02
  • Does BaseRepo have a parameterless constructor? Does the CustomerRepo compile? Commented Feb 10, 2016 at 21:07
  • No it does not compile and no BaseRepo does not have a paramaterless constructor so intellisense yells at me. I think what Ryan M posted below answers what I am looking for. Does it? Commented Feb 10, 2016 at 21:08
  • Yes, this is how you should do it. Commented Feb 10, 2016 at 21:17

1 Answer 1

4

How would you instantiate (or even compile) a CustomerRepo at all, regardless of dependency injection? You need an IConfigurationRoot parameter to pass through to the base constructor. Like:

public CustomerRepo(IConfigurationRoot configRoot) 
    : base(configRoot)
{
}

See https://msdn.microsoft.com/en-us/library/hfw7t1ce.aspx for info on the base keyword.

Sign up to request clarification or add additional context in comments.

6 Comments

I am pretty sure this is the exact syntax that I am looking for. I was wondering how to pass a param while inheriting. So will I have to update my Business Layer too?
@BlakeRivell Are you manually constructing a CustomerManager by passing it a CustomerRepo that you also manually constructed? If so, you'll need to give the CustomerRepo an IConfigurationRoot when you construct it. If you're using an IOC container where you can register types, it should be enough to register ICustomerRepo and IConfigurationRoot, and the container will be able to resolve the dependencies for you.
I am using ASP.NET 5 and the built in dependency injection. I am not manually passing anything. I specify everything in my Register Services in Startup.cs of my web app which is like configuring any other IoC container. So I was trying to follow that pattern hoping that I could get my application settings down to my BaseRepo while still using dependency injection. Does this change anything? I updated my post to what my repository class looks like now. I was told by doing this in the ConfigureServices method it will magically work: services.AddSingleton(_ => Configuration);
@BlakeRivell I haven't used that particular container, but yes, as long as ICustomerManager, ICustomerRepo, and IConfigurationRoot are registered, the container should be able to resolve your controller's dependencies. There is an example of this kind of chained dependency injection at docs.asp.net/en/latest/fundamentals/dependency-injection.html (ctrl-f characterscontroller).
@BlakeRivell Really, you are injecting IConfigurationRoot into the CustomerRepo (and then it's just passing the value through to the base constructor). You shouldn't need to do anything explicitly with BaseRepo's dependencies. But yes, I can't see anything else you'd need to do to get this all to work.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.