📜 ⬆️ ⬇️

Dependency Injection: anti-patterns

Low coupling is often a sign of a well-structured computer system and a sign of good design. Wikipedia

Dependency Injection (DI) is a set of patterns and software development principles that allow you to write loosely coupled code. According to M. Fowler, DI is a kind of more global principle of inversion of control (IoC), also known as the “Hollywood Principle”. Meanwhile, the boundaries of the principles of introducing dependency are rather blurred. It is impossible to draw a really clear boundary between this and other principles of writing high-quality object-oriented code. For example, the principle of Dependency Inversion from SOLID, which is often confused with Dependency Injection, implies dependency injection, but is not limited to it.

As with any patterns and principles, anti-patterns exist for DI. Below I will list them (with a few free translation of English names into Russian).
')
Anti-pattern number 1. "Control Freak". Head addict.

All dependencies are controlled directly. The opposite of inversion control principle.
The antipattern always occurs when we explicitly create a variable dependency within a class using the new keyword. The class that does not let go of control over its dependencies is Control Freak.

An example of such a class is shown below:

private readonly ProductRepository repository;

public ProductService()
{
    string connectionString = ConfigurationManager.ConnectionStrings["Context"].ConnectionString;

    this.repository = new SqlProductRepository(connectionString);
}

-: Dependency Injection ( ). , Control Freak, :

private readonly ProductRepository repository;

public ProductService(ProductRepository repository)
{
    if (repository == null) 
        throw new ArgumentNullException("repository");

    this.repository = repository;
}


- №2. «Bastard Injection». .

« », .Net, BCL. , . , DI-. - :

private readonly ProductRepository repository;

public ProductService() : this(ProductService.CreateDefaultRepository())
{
}

public ProductService(ProductRepository repository)
{
    if (repository == null)
        throw new ArgumentNullException("repository");

    this.repository = repository;
}

private static ProductRepository CreateDefaultRepository()
{
    string connectionString = ConfigurationManager.ConnectionStrings["Context"].ConnectionString;
    return new SqlProductRepository(connectionString);
}

-, Dependency Injection. , .. DI.

- №3. «Constrained Construction». .

- , «» . « Reflection». - :

string connectionString = ConfigurationManager.ConnectionStrings["Context"].ConnectionString;
string productRepositoryTypeName = ConfigurationManager.AppSettings["ProductRepositoryType"];
var productRepositoryType = Type.GetType(productRepositoryTypeName, true);
var repository = (ProductRepository)Activator.CreateInstance(productRepositoryType, connectionString);

-, .

- №4. «Service Locator». -.

- .
DI-- , - , Service Locator -, , - , - .

- DI “Dependency Injection in .NET”, Mark Seemann.

Source: https://habr.com/ru/post/166287/


All Articles