1

I have the class as:

public class ServiceUtility
{
    private IHostingEnvironment _environment;
    public ServiceUtility(IHostingEnvironment environment)
    {
        _environment = environment;
    }
    public string GetFilePath(string fileName)
    {
        return _environment.WebRootFileProvider.GetFileInfo(fileName)?.PhysicalPath;
    }
}

Using in Startup.cs

services.AddScoped<ServiceUtility>();

Using ServiceUtility in another class:

public class LevelUp
{
        private readonly ServiceUtility _serviceUtility;
        public LevelUp(ServiceUtility serviceUtility)
        {
            _serviceUtility = serviceUtility;
        }
        public LevelUp(string input)
        {
          //here the _serviceUtility is null
        }
        public int UserId { get; set; }
        public int Level { get; set; }
}

From controller I am using as:

var object = userList.Select(x => new LevelUp(x.Description));

When I am using the _serviceUtility in Levelup(string input) constructor, the value is always null.

I have also added in Startup.cs class:

services.AddScoped<LevelUp>();

What I am doing wrong here, what is the proper way of dependency injection with multiple constructors?

1 Answer 1

2

In your controller you are (manually) calling the LevelUp constructor with the string parameter (ctor(string)) and not the ctor(ServiceUtility) constructor. This LevelUp class is not created by the DI Container, you are creating it yourself. If you wish to supply ServiceUtility to LevelUp, you should pass both the string and ServiceUtility through the same constructor:

public class LevelUp
{
    private readonly ServiceUtility _serviceUtility;

    public LevelUp(ServiceUtility serviceUtility, string input)
    {
        _serviceUtility = serviceUtility;
    }

    public int UserId { get; set; }
    public int Level { get; set; }
}

From within your controller you then have to pass ServiceUtility as well to LevelUp's constructor:

public class HomeController : Controller
{
    private readonly ServiceUtility serviceUtility;

    public HomeController(ServiceUtility serviceUtility)
    {
        this.serviceUtility = serviceUtility;
    }

    public object Index(List userList)
    {
        var object =
            userList.Select(x => new LevelUp(this.serviceUtility, x.Description));
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

So, there isn't way of doing that by the framework itself? Why do we need to supply by ourselves?
It's one way or the other: either you leave the construction or the object completely to the DI infrastructure (which means a DI Container or a hand-written Composition Root) -or- you create the object using the new statement. A DI Container can't magically change your compiled code.
Also note that when when it comes to classes that contain application behavior and are injected with dependencies, it is considered to be a bad thing for them to have multiple constructors.
Thank you @steven i will certainly note that. and I will try to refactor the multiple constructors.
On the other hand, your LevelUp seems more a newable than an injectable. For data-centric objects it's okay to have multiple constructors.

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.