question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Should IStringLocalizer be covariant?

See original GitHub issue

Like ILogger<T>, IOptions<T> or IOptionsMonitor<T>, should IStringLocalizer<T> be covariant? This would allow this kind of pattern:

public class Base
{
    public Base(IStringLocalizer<Base> localizer) { }
}
public class Derived : Base
{
    public Base(IStringLocalizer<Derived> localizer)
        : base(localizer) { }
}

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:12 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
kevinchaletcommented, Feb 14, 2019

Excellent, I’ll send a PR soon, then 😄

1reaction
kevinchaletcommented, Feb 13, 2019

Do you have something concrete @PinpointTownes ?

Yeah, the main scenario I have in mind is to allow an application to override the resources location when subclassing a class from a class library that comes with .resx files and uses [assembly: ResourceLocation("...")].

// Defined in a class library.
public class Base
{
    // Uses the resources defined in the class library (ClassLibrary.Resources.Base).
    public Base(IStringLocalizer<Base> localizer) { }
}
// Subclassed in application code.
public class Derived : Base
{
    // Uses the resources defined in the application (App.Resources.Derived).
    // Both this class and the base one will use the application strings.
    public Base(IStringLocalizer<Derived> localizer)
        : base(localizer) { }
}

It’s exactly like how options and generic loggers work:

public class Base
{
    public Base(IOptions<Base> options) { }
}
public class Derived : Base
{
    // Resolve specialized Derived options and inject them
    // into the base class as IOptions<Base>.
    public Base(IOptions<Derived> options)
        : base(options) { }
}

It’s something I use in OpenIddict: I have a OpenIddictServerOptions class that inherits from OpenIdConnectServerOptions (from ASOS) and defines additional options. Wherever IOptionsMonitor<OpenIdConnectServerOptions> is used, I simply flow IOptionsMonitor<OpenIddictServerOptions> (e.g https://github.com/openiddict/openiddict-core/blob/dev/src/OpenIddict.Server/OpenIddictServerHandler.cs#L25).

Read more comments on GitHub >

github_iconTop Results From Across the Web

Should IStringLocalizer be covariant? · Issue #975
@davidfowl thoughts? I feel like making it covariant only makes sense if we actually walk the class inheritance tree as part of class ......
Read more >
c# - How dependency injection work for covariance type in ...
You could check the source code for ILogger by Logging. Here is the process. For ILogger<AController> , it is crated by LoggerFactoryExtensions
Read more >
Covariance and Contravariance in Generics
Covariance. Enables you to use a more derived type than originally specified. You can assign an instance of IEnumerable<Derived> to a ...
Read more >
Introducing C# 9: Covariant returns
In this article I will show you how it works with a very simple example and ... Here is a simple example of...
Read more >
Practical usage of C# covariance
Variance is a .NET 4.0 concept that allows implicit conversion between instances of generic types. In other words, it permits the ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found