简体   繁体   中英

Adding a implementation rather than its interface in ASP.NET Core DI

What's the difference between adding an implementation rather than its interface, being that I have just one implementation of this interface?

// Adds a transient service by type of the implementation:
services.AddTransient(typeof(SomeConcreteService));

or

// Adds a transient service by interface of the concrete implementation type:
services.AddTransient<ISomeService, SomeConcreteService>();
services.AddTransient<ISomeService, SomeConcreteService>();

This way is preferred as it lets you use dependency injection in the correct manner.

If you use interfaces in all your controllers and then decide you want to change the concrete implementation, you will only have to edit the one line in your Startup.cs

public HomeController(ISomeService someService)
{
      //..
}

When you add the implementation you will only be able to inject it as implementation.

services.AddTransient(typeof(SomeConcreteService));

Injecting this now as ISomeService will cause an error.

While this

services.AddTransient<ISomeService, SomeConcreteService>();

will allow you to inject the interface rather than the implementation.

In the end it is about loosley coupeling . It also makes your software harder to test.

If you only inject the interface you can easily test the class that uses the implementation with its given interface bc you can mock it without any troubles. If you don't and inject the real implementation, the functions of the implementation must be marked as virtual to mock them. You also need to mock the classes your implementation SomeConcreteService might be using.

Today you have one implementation of the interface. Tomorrow you may not. Others may need to extend the service in the future with a decorator , composite , or other design pattern.

Essentially, by using an interface, you are future-proofing your application for every eventuality - it can even be extended in ways that you don't foresee today, without changing a single line of code outside of your DI container registration.

If you use the concrete type, the ability to extend it is very limited. You are basically saying "this is the way it will be forever" without allowing many possibilities for extending it without changing the code . You are giving up the most useful benefit of using the DI pattern - loosely coupling your code by separating its interface from its implementation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM