Continuing with topics based on ASP.NET Core code reviews.
Here is a bit of code I came across in an application’s Startup class.
public void ConfigureServices(IServiceCollection services) { services.AddScoped<IStore<User>, SqlStore<User>>(); services.AddScoped<IStore<Invoice>, SqlStore<Invoice>>(); services.AddScoped<IStore<Payment>, SqlStore<Payment>>(); // ... }
The actual code ran for many more lines, with the general idea that the application needs an IStore implementation for a number of distinguished objects in the system.
Because ASP.NET Core understands unbound generics, there is only one line of code required.
public void ConfigureServices(IServiceCollection services) { services.AddScoped(typeof(IStore<>), typeof(SqlStore<>)); }
Unbound generics are not useful in day to day business programming, but if you are curious how the process works, I did show how to use unbound generics at a low level in my C# Generics course.
One downside to this approach is the fact that you might experience a runtime error (instead of a compile error) if a component requests an implementation of IStore<T> that isn’t possible. For example, if a concrete implementation of IStore<T> uses a generic constraint of class, then the following would happen:
Assert.Throws<ArgumentException>(() => { services.GetRequiredService<IStore<int>>(); });
However, this problem should be avoidable.