Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should we create one interface for this configuration class?

My understanding of interfaces is that they define contracts and classes implementing the interface sign the contract. In that case, we may design classes to depend on the contract and not on the concrete implementation. This has advantages like reducing coupling, enabling polymorphism, and so forth.

Now I have came across one use of interfaces which I didn't get. This is from the ASP.NET Core documentation, regarding configuration. In particular, in the page, one is talking about setting up MongoDB with ASP.NET Core.

They basically define a class and an interface like this:

namespace BooksApi.Models
{
    public class BookstoreDatabaseSettings : IBookstoreDatabaseSettings
    {
        public string BooksCollectionName { get; set; }
        public string ConnectionString { get; set; }
        public string DatabaseName { get; set; }
    }

    public interface IBookstoreDatabaseSettings
    {
        string BooksCollectionName { get; set; }
        string ConnectionString { get; set; }
        string DatabaseName { get; set; }
    }
}

Then they use this as follows:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<BookstoreDatabaseSettings>(
        Configuration.GetSection(nameof(BookstoreDatabaseSettings)));

    services.AddSingleton<IBookstoreDatabaseSettings>(sp =>
        sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value);

    services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

I must say I gon't get it. The objects of type BookstoreDatabaseSettings are meant to work as DTOs for the settings. They don't provide any functionality at all. So why introduce one interface in the middle?

I don't see here one usage on which one would use some other implementation. I don't see here why one is trying to decouple this, I don't see any use of polymorphism at all, and I really didn't get the point.

So why in this situation, when dealing with settings in ASP.NET Core, one uses interfaces and not the concrete class (for example BookstoreDatabaseSettings) directly?

like image 465
user1620696 Avatar asked Sep 23 '19 14:09

user1620696


People also ask

When should you create an interface?

If you want to introduce an abstraction for multiple specific things. If you want to treat different, specific classes in some way that is the same for every one of them, you should introduce an interface that covers their common ground.

Why do we need interface instead of class?

An interface defines common functionality across unrelated classes. For example, all sorts of classes that look nothing like each other may have the need to safely get rid of the resources they use.

Do I need to use an interface when only one class will ever implement it?

Interfaces can be implemented by multiple classes. There is no rule that only one class can implement these. Interfaces provide abstraction to the java.

What is an interface and when would you use one?

An interface can be used to define a contract behavior and it can also act as a contract between two systems to interact while an abstract class is mainly used to define default behavior for subclasses, it means that all child classes should have performed the same functionality.


1 Answers

In the context of just one app, you're correct that this doesn't make sense. However, there could be scenarios where it might.

What's happening here is that, first, the BookstoreDatabaseSettings is bound to the config section. This is technically all that's required. However, this uses the options pattern, which mean that you must then injnect IOptions<BookstoreDatabaseSettings>, IOptionsSnapshot<BookstoreDatabaseSettings> etc., rather than BookstoreDatabaseSettings directly. That implies a dependency on Microsoft.Extensions.Options, which is not necessary a bad thing, but it is a dependency nonetheless.

The next line then binds the interface to the actual BookstoreDatabaseSettings instance, pulled from IOptions<BookstoreDatabaseSettings>. In other words, you can now simply inject the interface, instead of IOptions<BookstoreDatabaseSettings. Again, nothing monumental, but it abstracts the use of Microsoft.Extensions.Options. For what it's worth, you could have just as easily registered BookstoreDatabaseSettings instead of the interface to get the same thing. Then, you'd be able to inject BookstoreDatabaseSettings directly, without a dependency on Microsoft.Extensions.Options.

What the interface buys you here, is abstracting the actual class implementation. You could potentially put the interface alone in a library that's shared between projects, and leave the actual class implementation to each individual project. If your shared libraries depend only on the interface, then the actual implementation that's provided won't matter. However, you could just as easily share the class implementation between projects as well. It's just a matter of perspective.

like image 148
Chris Pratt Avatar answered Sep 21 '22 03:09

Chris Pratt