Display Name
Display Name

Reputation: 15091

AddTransient<IService, Service>() versus AddTransient<Service>()

I am learning the built-in DI of .net core and I am confused why I can use B but not A in the following?

interface IService
{
    void Do();
}

class Service : IService
{
    public void Do() => Console.WriteLine("Doing...");
}


class Program
{
    static void Main()
    {
        using (ServiceProvider sp = RegisterServices())
        {
            sp.GetRequiredService<Service>().Do();
        }
    }

    static ServiceProvider RegisterServices()
    {
        ServiceCollection sc = new ServiceCollection();
        //sc.AddTransient<IService, Service>(); // A
        sc.AddTransient<Service>(); // B
        return sc.BuildServiceProvider();
    }
}

Upvotes: 1

Views: 319

Answers (1)

Scott Hannen
Scott Hannen

Reputation: 29202

If you do this:

sc.AddTransient<Service>();

You're telling the ServiceProvider (container) that it must be able to resolve Service. When I ask for Service, give me Service.

That would work if you had a class that depended directly on Service. For example:

public class DependsOnService
{
    private readonly Service _service;

    public DependsOnService(Service service)
    {
        _service = service;
    }
}

But in many (perhaps most cases) we're going to write classes to depend on abstractions (like interfaces) instead of directly on concrete classes. So the above would more commonly look like this:

public class DependsOnService
{
    private readonly IService _service;

    public DependsOnService(IService service)
    {
        _service = service;
    }
}

Now, when DependsOnService is created, the container must resolve IService. It has to know that when it's asked to resolve IService, the implementation it should create is Service. That's what this does:

sc.AddTransient<IService, Service>();

It says, when I ask for IService, give me Service.

Upvotes: 1

Related Questions