0

I have a class with a parameterized constructor with an IOptions<TOptions> parameter to access the connection string. Now I need to create a default constructor for my project purpose. Now I want to trigger the parameterized constructor from the default constructor. How can I do that?

FlashOver
  • 1,855
  • 1
  • 13
  • 24
SATHEESH P
  • 389
  • 1
  • 3
  • 21
  • For example: `public MyClass() : this(parameter to be passed to the ctor with parameter) { // implementation }` – Dimitar Dec 10 '18 at 09:41
  • Thanks Dimitar. But now i want to pass IOption with settings like this public ValuesController():this(IOptions configSettings) { }. I am getting following error Using the generic type 'IOptions' requires 1 type arguments – SATHEESH P Dec 10 '18 at 09:47
  • You cannot do this. You must provide an actual object instance like (new DefaultOption) where the Default option is implementing the IOption interface. – Dimitar Dec 10 '18 at 10:06
  • 1
    @SATHEESHP `default constructor` means `no parameters` by definition. Why do you want to use the *default* constructor at all, when you need parameters? Register your class as a service and the DI/Configuration middleware will inject the values you want. During testing just pass an Option class with the hard-coded values – Panagiotis Kanavos Dec 10 '18 at 10:33
  • 1
    @SATHEESHP what is the *actual* problem you want to solve? If you want a fallback value you can set it during configuration. If you want to target different databases, configure your DbContexts or any other class you want to target the correct database. – Panagiotis Kanavos Dec 10 '18 at 10:35
  • Possible duplicate of [C# constructor chaining? (How to do it?)](https://stackoverflow.com/questions/1814953/c-sharp-constructor-chaining-how-to-do-it) – Michael Puckett II Dec 10 '18 at 17:03
  • **You need to use a factory pattern.** The factory class gets the `IOptions` from in its constructor, and it also has a method called `Create()` that creates a new instance of your class by calling the other constructor that you want to call (with the required parameters). – JohnB Jul 19 '22 at 15:57

1 Answers1

2

From the default constructor, you can invoke the parameterized constructor (by using the this keyword) with an instance of the OptionsWrapper class, which implements the IOptions interface:

public class ValuesController
{
    public ValuesController()
        : this(new OptionsWrapper<Config>(new Config() { ConnectionString = "default ConnectionString" }))
    {
    }

    public ValuesController(IOptions<Config> configSettings)
    {
    }
}

public class Config
{
    public string ConnectionString { get; set; }
}

Alternatively, you may use Options.Create, which actually does the same: Options

Options.Create(new Config() { ConnectionString = "default ConnectionString" });

However, either of these solutions - especially if used in the context of ASP.NET Core - entirely defeat the purpose of Configuration and Dependency injection.

FlashOver
  • 1,855
  • 1
  • 13
  • 24
  • 2
    That's a bad idea. It hard-codes the settings and *duplicates* the configuration already stored in the configuration subsystem. The config middleware can read data from dictionaries, environment variables, multiple setting files that allow specifying a fallback connection quite easily and safely – Panagiotis Kanavos Dec 10 '18 at 10:35
  • @PanagiotisKanavos I agree this should be done before the constructor as you mentioned in the comments above; but the question, regardless of configuration logic, was answered. Possibly just answer it with showing how to call one constructor from another; passing default values would be more ideal. That is answered here: https://stackoverflow.com/questions/1814953/c-sharp-constructor-chaining-how-to-do-it – Michael Puckett II Dec 10 '18 at 17:03