Miguel Moura
Miguel Moura

Reputation: 39394

Expose class private field to be defined in constructor

I have the following class that takes a configuration in its constructor:

public class Importer {

  private ImporterConfiguration _configuration;

  public Importer(String path, ImporterConfiguration configuration) {
    _configuration = configuration;
  }

}

I have seen some classes that can be used as follows:

Class class = new Class("path", x => {
   x.ConfigurationProperty1 = 1;
   x.ConfigurationProperty2 = 2;
});

How can I allow to define my Importer Class _configuration this way?

Upvotes: 1

Views: 89

Answers (3)

Lucca Ferri
Lucca Ferri

Reputation: 1347

You need to define an Action passing the Type ImporterConfiguration and then create the object inside the constructor itself, then you invoke the action passing the context the object you've created.

Example:

public Importer(String path, Action<ImporterConfiguration> configuration) 
{
    ImporterConfiguration importerConfiguration = new ImporterConfiguration();
    configuration.Invoke(importerConfiguration);
    _configuration = importerConfiguration;
}

Usage:

Importer importer = new Importer("foo", x => { /*..*/ });

Edit (why I use .Invoke):

You could also create the basic configurations, so to speak, if you make changes to the constructor, passing Action default as null, and using a nullable invoke on the action:

configuration?.Invoke(importerConfiguration);

This way, it will create the ImporterConfiguration with the default values, and if the configuration is null then it will use the "default settings"

Upvotes: 4

Rion Williams
Rion Williams

Reputation: 76557

There may be two potentially different syntax options that you could use for configuring this property. I'll include some details on each of them in case there's one specific you are looking for.

Anonymous Object Syntax

Are you potentially referring to the use of defining an anonymous object for your specific properly using something like this syntax?

var importer = new Importer("path", new ImporterConfiguration(){
   ConfigurationProperty1 = 1;
   ConfigurationProperty2 = 2;
});

This approach would work and allow you to set any properties within your ImporterConfiguration object that were publicly accessible.

Delegation / Action Syntax

Otherwise, if you wanted the lambda style syntax, you'd want to define an Action<ImporterConfiguration> as your second parameter, which would allow you pass in a delegate to handle the configuration:

// Constructor that accepts a delegate for your configuration
public Importer(String path, Action<ImporterConfiguration> config) 
{ 
     // Create an instance
     var configuration = new ImporterConfiguration();
     configuration.Invoke(config);

     // Set your backing property
     _configuration = configuration;
}

This would just be called as:

var importer = new Importer("path", x => { ... });

Upvotes: 1

John Wu
John Wu

Reputation: 52250

Instead of accepting a value for the configuration, accept a delegate and execute it, passing your existing configuration instance.

public class Importer {

    private ImporterConfiguration _configuration;

    public Importer(String path, Action<ImporterConfiguration> configurator) {
        var configuration = new ImporterConfiguration();
        configurator(configuration);
        _configuration = configuration;
    }
}

Upvotes: 2

Related Questions