All of our applications currently load a XML file located on the network using Datamembers/Datacontacts with DataContactSerializer. I think it would be safer and easier for us to use a SQL Table even though i would be losing my Type Safety.

I'm trying to figure out a way to reproduce my classes inside my SQL Table so that when i wanna get value of a parameter, I only have to do MyConfig.Property but I can't find a solution other than

  1. Implement a Get/Set for every property/field
  2. List item

B) Use the code below but everytime i wanna get a property, i would need to do the following : MyConfig[nameof(Property)].

Old VB.NET Code

<!-- language: vb -->

Public Sub CreateConfig()
        ConfigApplications = New ConfigurationApplications
        ConfigRBTK = New ConfigurationRBTK2
        ConfigRBRE = New ConfigurationRBRE2
        ConfigTC = New ConfigurationTC2
        ConfigTLS = New ConfigurationTLS2
        ConfigTQ = New ConfigurationTQ2
        ConfigSoustrait = New ConfigurationSoutrait

        Dim ser As New DataContractSerializer(GetType(AppConfig4))
        Dim Settings As New XmlWriterSettings
        Settings.Indent = True
        Dim W As XmlWriter = XmlWriter.Create(ConfigFile, Settings)
        ser.WriteObject(W, Me)
        W.Close()
    End Sub

New C# Code

public object this[string propertyName]
{
    get
    {
        string fullName = typeof(MyConfig).GetField(propertyName).DeclaringType.FullName + "." + propertyName;
        using (Info_IndusContext conn = new Info_IndusContext())
        {
            return conn.AppConfig.Where(x => x.Param == fullName).FirstOrDefault().Value;
        }

    }
    set
    {
        string fullName = typeof(MyConfig).GetField(propertyName).DeclaringType.FullName + "." + propertyName;
        using (Info_IndusContext conn = new Info_IndusContext())
        {
            conn.AppConfig.Where(x => x.Param == fullName).FirstOrDefault().Value = value.ToString();
            conn.SaveChanges();
        }

    }

}

SQL Table Preview

<table>
  <tr>
    <th>ID</th>
    <th>Name</th> 
    <th>Value</th>
  </tr>
  <tr>
    <td>1</td>
    <td>MyConfig.DefaultColor</td> 
    <td>Red</td>
  </tr>
  <tr>
    <td>2</td>
    <td>MyConfig.SiteA.Color</td> 
    <td>Blue</td>
  </tr>
</table>

1 Answers

1
Clay On

I have a complex state object that I serialize and deserialize with DataContractSerializer and I love it. Not sure you're really doing yourself any favors. You'll be bending over backwards and doing a lot of tedious detailed stuff that the serializer does. What you might consider doing is serializing the data contract to a stream or string that you read and write to the db. I've found that to take advantages of both worlds.

My state object has a ToString() override that looks kinda like:

public override string ToString( )
{
  var serializer = new DataContractSerializer( this.GetType( ) );
  using ( var stream = new MemoryStream( ) )
  {
    var settings = new XmlWriterSettings( );
    settings.Indent = true;
    var writer = XmlWriter.Create( stream, settings );
    {
      serializer.WriteObject( writer, this );
      writer.Flush( );
    }
    stream.Position = 0;
    var reader = new StreamReader( stream );
    return reader.ReadToEnd( );
  }
}

...which makes it trivial to put into an nvarchar parameter in SQL, and it also helps with diagnostic examination.