Freelancer
Freelancer

Reputation: 73

How to inject class in constructor of another class?

I have three projects com.comman, com.business in one solution and com.xyz in another solution.

In com.comman i have one class lets say logger, it takes one parameter in constructor. So in com.business i am referring commans DLL and creating logger obj as var obj=new logger("MIS");

Like this i want to create logger object in com.xyz but without referencing com.comman dll. Is it possible to achieve this?

NOTE: From com.business project i am calling one of the class called "ABC"of com.xyz which again calls another class "PQR" in com.xyz. I want to create logger object in PQR class.

Please guide me!!

Upvotes: 1

Views: 2124

Answers (1)

Steven
Steven

Reputation: 172835

I assume that assembly com.xyz is not allowed to reference assembly com.comman, since com.xyz is in a different solution and that solution is already refering at com.xyz.

This means that the PQR class can't depend on com.comman.Logger. Still you want to be able to inject that logger in PQR.

The way to solve this is to define an abstraction/interface in com.xyz and let PQR depend on that interface. For instance:

// Logger abstraction specifically tailored at the needs of com.xyz
public class ILogger {
    void Log(string message);
}

public class PQR {
    private readonly ILogger logger;
    public PQR(ILogger logger) {
        if (logger == null) throw new ArgumentNullException("logger");
        this.logger = logger;
    }
    // PQR methods
}

The existence of this new com.xyz.ILogger abstraction allows you to create an adapter that maps from com.xyz.ILogger to com.comman.logger. This adapter should be located in the solution of com.business. The most preferable place for this is the Composition Root. The Composition Root will likely be an assembly that refers your com.business, but if com.business is your start-up project, that would be the place to create the adapter.

This adapter might look as follows:

public class ComXyzLoggerAdapter : com.xyz.ILogger {
    private com.comman.logger logger;
    ComXyzLoggerAdapter(com.comman.logger logger)
        this.logger = logger;
    }

    public void Log(string message) {
        // Here we map from com.xyz.ILogger to comman.Logger 
        this.logger.LogError(message);
    }
}

In the location where you create the PQR class (in the com.business solution) you will now need to do this:

var abc =
    new ABC(
        new QPR(
            new ComXyzLoggerAdapter(
                new com.comman.logger("MIS"))));

What we did here was basically applying the Dependency Inversion Principle.

Upvotes: 1

Related Questions