2

Using Net 4.5.1 and StructureMap 3.1.4

I have services that extending an abstract class:

 public abstract class Charting<T> {

   protected readonly String baseConfigurationString;

   public Charting(String baseConfigurationString)
   {
      this.baseConfigurationString = baseConfigurationString;
   }

   ...
 }

For every concrete service I want to set the baseConfigurationString. Right now I am doing it individually per service:

 public class MyRegistry : Registry
 {
    public MyRegistry()
    {
        Profile("Development", x => {
            ForConcreteType<AveragePartySizeChart>().Configure.Ctor<String>("baseConfigurationString").Is(MyDbConfiguration.getBaseConnectionString());

            ...next service....about 6 total
        });
    }
 }

Is there anyway to do this generally acting against the abstract class despite it having a generic qualifier?

Matthew Campbell
  • 1,864
  • 3
  • 24
  • 51

2 Answers2

1

This does not solve your abstract constructor argument setting via Profile problem but I would like to suggest that you avoid taking dependencies on primitive types like System.String and use an abstraction instead.

You could have an type IDatabaseSettings which gets the connection settings you desire for either environment variables or application settings.

public interface IDatabaseSettings
{
  string DbConnectionString { get; set; }
}

public class DatabaseSettings : IDatabaseSettings
{
  public string DbConnectionString { get; set; }
}

public class DatabaseRegistry : Registry
{
  public DatabaseRegistry()
  {
    For<IDatabaseSettings>().Use(c =>
    {
        var setting = c.GetInstance<DatabaseSettings>();

        setting.DbConnectionString =
            System.Configuration.ConfigurationManager.AppSettings["DatabaseSettings.DBConnectionString"];

        return setting;
    });
  }
}

Important: Your project will need to reference System.Configuration.

If you have a lot of settings you may want to conventionalize this pattern. We use the SettingsProvider out of FubuCore to make this a breeze. You simply have objects that end in Settings which get their properties automatically populated out of application settings. Chad Myers has a nice blog post on it.

KevM
  • 2,496
  • 1
  • 22
  • 25
1

My suggestion, and what we did with StructureMap for configuration within FubuMVC, is to create a class something like:

public class ConnectionSettings
{
    public string Connection {get;set;}
}

and resolve that through StructureMap as a singleton. Then in any class that needs the connection string, just do:

public abstract class DatabaseConnectionUser
{
    public DatabaseConnectionUser(ConnectionSettings settings){}
}

Autowiring will connect your ConnectionSettings object to all the class objects that take in that object in their constructor function.

You could try using a custom IPluginGraphConfiguration class in StructureMap 3 to set the ctor argument explicitly on all Instance's that build a subclass, but I think that would be more work.

  • @Jermey, Thanks. I did as KevM suggested and Weinart making a custom settings object that I pass to the **Charting** abstraction. Works great. Appreciate the tip on SM graphs and I looked at the FubuMVC code. – Matthew Campbell Oct 14 '14 at 04:44