Injecting a dependency having constructor parameters in common with the higher level class

dependency injection example
types of dependency injection c#
dependency injection java example
dependency injection explained
java dependency injection frameworks
dependency injection container
dependency injection java example stackoverflow
dependency injection c++

Sometimes when I design my classes, I need some dependency classes with similar constructor parameters. Assume we have

interface IDependency {
    void DoSomething();
}

class DependencyClass : IDependency {
    public DependencyClass(int length) {...}
    ...
}

class MainClass {
    public MainClass(int length, IDependency dependency) {...}
    ...
}

MainClass needs an instance of DependencyClass with the same length. I have two methods in mind to deal with it:

  1. Not creating instances of MainClass directly and always getting them from a factory. This way I can make sure that the desired IDependency instance will be provided to MainClass constructor.

  2. Passing a factory interface, say IDependencyFactory, to MainClass constructor instead of IDependency. So that I can get the desired instance of DependencyClass within my MainClass implementation.

I'm not sure if either of them is a good choice. Is there a best practice in this case?

This is a very interesting question and the answer lies in what you try to achieve here.

Solution 1. you provided will make your IDependency the main factory interface, all instanced will be implemented with IDependency interface which will provide you with a lot of scalability - you will be able to use the IDependency interface to initialize additional classes in the future with different functionality, which is the classic use and implementation of factory design pattern.

solution 2. you provided will make your MainClass well, the Main Class of the program, you will handle the instances and their behavior inside the main class and the advantage here is that you can manage all of your instances through IDependency, and the only thing you do in MainClass is handle their logic, MinaClass will be your instances transporter and all of the fundamental changes for the base classes will be made in the interface IDependency which is a classic solution for Dependency Inversion.

The question still remains, what you are trying to achieve. Consider this question and the two possibilities and you have your answer.

Design Patterns Explained – Dependency Injection with Code , Dependency injection is a programming technique that makes a You can introduce interfaces to break the dependencies between higher and lower level classes. The interface only decouples the usage of the lower level class but It provided that object as a constructor parameter while instantiating a  5 Injecting a dependency having constructor parameters in common with the higher level class Aug 13 '18 View all questions and answers → Badges (58)

One of the simplest changes you could make to guarantee the length will be the same for both the DepencyClass and the MainClass is to add a Length property to the interface and initialize it from a constructor, and then allow MainClass to access the length (you then save one parameter on the MainClass, which is more DRY.

interface IDependency {
    int Length { get; }
    void DoSomething();
}

class DependencyClass : IDependency {
public DependencyClass(int length) { Length = length; }
    ...
}

class MainClass {
    public MainClass(IDependency dependency) {...}
    ...
    // do something with dependency.Length
}

This does have the possible drawback of "polluting" your interface and perhaps exposing the length to other code. That's up to you if that matters.

The 3 Types of Dependency Injection - Better Programming, The dependencies are declared as parameters of the constructor. As a result, you cannot create a new instance of the class without I say take because while a user of the class can pass in null , the class itself doesn't have to accept null Checking that a reference is not null is probably the most common  Constructor Injection. Constructor injection instruments the constructor of a class, which used by the DI framework to inject the dependencies. It is the other variant that makes dependencies explicit. In opposite to the Setter Injection it prevents you to create a class in irregular state.

If your length is runtime variable - refer to this comment.

If you need this in runtime, you can use the solution #2 from this answer.

If it's compile time setting, you can inject it as any other dependency, that's normal that both MainClass and DependencyClass are dependent on the same value.

To have a safe compile-time injection, you can introduce something like that:

interface ILength {
    int Length { get; }
}

class StaticLength : ILength {
    public StaticLength(int length) {
        Length = length;
    }
}

void Main() {
    const int length = 10;
    ILength lengthDependency = new StaticLength(length);
    IDependency dep = new DependencyClass(lengthDependency);
    MainClass mainClass = new MainClass(lengthDependency, dep); 
}

And now you can implement any kind of ILength - read from configuration file, constant, web, mock, calculate base on any other dependency, random etc.

Using dependency injection in Java - Introduction - Tutorial, Dependency injection (DI) is the concept in which objects get other required objects from outside. If the Java class creates an instance of another class via the new The most common approach is to use Java annotations to describe As fields and method parameters are injected after the constructor is  You can implement Dependency Injection on your own by creating instances of the lower-level components and passing them to the higher-level ones. You can do it using three common approaches: Constructor Injection : with this approach, you create an instance of your dependency and pass it as an argument to the constructor of the dependent class.

Dependency injection in action, This section explores many of the features of dependency injection (DI) in Angular. dependencies, so the framework can simply use new to instantiate the class and Providers can also be scoped by injector through constructor parameter In order to get a service from a dependency injector, you have to give it a token. Dependency Injection via Method Injection In this type of injection, the dependent object is injected, using the method of the class. In Constructor Injection, the dependent class uses the same concrete class for its all life time and if we have to pass some separate concrete class on each invocation of the method, at this moment, we have to pass the dependency in method only and not in

Dependency Injection anti-pattern: multiple constructors · .NET , Newables are classes that the application news up manually using An injectable should have a single constructor. 2: The container selects the constructor with the most parameters. return constructors in a particular order, such as declaration order. Third-party types such as types defined by the . Having the constructor injection in place is the best possible approach with the DI in general. One of the biggest advantages is that you can easily see if your class violates SOLID principles and you see how many dependencies you have in a single place

Understanding Dependency Injection in .NET Core, Learn what Dependency Injection and IoC are and what . Have you ever had to change a lot of code because of a new simple requirement? It relies on the OrderSender class to actually send the order received as an argument. Constructor Injection: with this approach, you create an instance of your  Dependency injection can be also achieved by having getter setter property, and if initiate the class at setter level, it is called a Setter level injection. (i.e. after creating an instance of the main class and before accessing the dependent method we need to set the property.)

Comments
  • Interesting question! Are you looking for a generic design solution or can it be specific to a DI framework?
  • Can you consider make length a parameter in of the MainClass method, which will use it?
  • @Flater A generic solution would be great.
  • I think you are looking for something like the builder pattern, where you can build in one function let's say a one type of pizza (large pizza with extra cheese), or another type of pizza ( small pizza with extra cheese), please have a look at builder pattern, and also decorator pattern.
  • If length is a runtime value, you should refrain from injecting it into a injection constructor. Injecting runtime values into components is a code-smell.
  • Nice comment ;)