Storing (and using) file naming schemas to a class property

Viewed 96

I have a project that contains a stateProfile class and an Inquiry class. The Inquiry class is static and it's job is to create a text file. The text file's contents are calculated using information stored in the properties of a stateProfile object (one for each State in the USA, that winds up being read in from an XML file).

I had been able to share a global naming schema for all of the states but I now have requirements to meet for naming them based on the stateProfile object.

For example: I have a stateProfile for Kansas and another for Missouri.

Inquiry inquiry = new Inquiry();
foreach(stateProfile p in _listOfProfiles){
     inquiry.CreateFile(p);
}

in Inquiry.CreateFile(stateProfile p) I have the expression that defines the filename:

sOutFileName = $"{p.prop1}_{p.prop2}_Literal3_{_staticProp.ToString("D4")}.txt";

Any suggestions for being able to store the logic/expression in a property like stateProfile.outFileName such as

public string outFileName {
     $"{p.prop1}_{p.prop2}_Literal3_{_staticProp.ToString("D4")}.txt";
}

and then be able to refer to that property in Inquiry.CreateFile(stateProfile p) like the following?

sOutFileName = $"{p.outFileName}";
2 Answers

I think that this sort of approach might be what you are looking for. It allows you to embed C# scripts into your XML and interpret them in code.

Every State could have a different filename format now.

using System;
using Microsoft.CodeAnalysis.Scripting;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // This was read from your XML file.
            var filenameFormatterScript = "p => $\"{p.Name.ToLower()}.txt\"";

            var options = ScriptOptions.Default.AddReferences(typeof(StateProfile).Assembly);
        
            var sp = new StateProfile
            {
                Name = "Alabama",
                FilenameFormatter = await CSharpScript.EvaluateAsync<Func<StateProfile, string>>(filenameFormatterScript, options)
            };

            Console.WriteLine(sp.Filename());

        }
    }

    public class StateProfile
    {
        public string Name { get; set; }

        public Func<StateProfile, string> FilenameFormatter { get; set; }

        public string Filename()
        {
            return FilenameFormatter(this);
        }
    }
}

After thinking about this some more, Alex's comment was the way to go.

Since all of the properties I am looking to use in constructing the filename formulas are belonging to the stateProfile object, I make a method GetFileName() class member and pass in anything else I might need.

I use a switch statement, which could get unwieldy as the number of states I have to consider grows, but for now it works.

        public string GetFileName(int prop1) {
            string sOutFileName = "";
            switch (SourceState) {
                case "MO":
                    sOutFileName = $"ReqPref_{this.stProfPropA}_{prop1}.txt";
                    break;
                default:
                    sOutFileName = $"{this.stProfPropB}_{prop1}.txt";
                    break;
            }
            return sOutFileName;
        }
Related