User Tools

Site Tools


dev:csharp

This is an old revision of the document!


the best trick: subtypes of

I need to just derive stuff from something, and all the derived types I'll register somewhere, or initialize, or something like that - but I don't want to also have to have an ever-growing list of tasks for each
var subtypes = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(domainAssembly => domainAssembly.GetTypes())
    .Where(type => type.IsSubclassOf(typeof(MyAbstractClass)) && !type.IsAbstract)
    .ToList();
 
foreach (var subtype in subtypes)
{
    var instance = (MyAbstractClass) Activator.CreateInstance(subtype);
}

so you make an abstract class MyAbstractClass and derive from it.

example

static List<Task<Report>> CollectReporters(Configuration conf)
{
    var toReturn = new List<Task<Report>>();
 
    var reporterTypes = AppDomain.CurrentDomain.GetAssemblies()
      .SelectMany(domainAssembly => domainAssembly.GetTypes())
      .Where(type => type.IsSubclassOf(typeof(newsletter.Reporters.Reporter)) && !type.IsAbstract)
      .ToList();
    var skipPortionInName = "newsletter.Reporters.".Length;
 
 
    foreach(var discoveredConfType in conf.Reporters.Select(r => r.ReporterClass))
    {
        Console.WriteLine($"{discoveredConfType} configuration type discovered");
    }
    foreach (var reporterType in reporterTypes)
    {
        Console.WriteLine($"{reporterType.ToString().Substring(skipPortionInName).ToLower()} reporter class discovered");
        Func<Configuration.Reporter, bool> predicate = r => r.ReporterClass == reporterType.ToString().Substring(skipPortionInName).ToLower();
        if (!conf.Reporters.Any(predicate))
        {
            Console.WriteLine($"no configurations for it");
        }
        else
        {
            var configurationsFor = conf.Reporters.Where(predicate);
            Console.WriteLine($"{configurationsFor.Count()} configurations for it");
 
            foreach (var confFor in configurationsFor)
            {
                 var instance = (newsletter.Reporters.Reporter) Activator.CreateInstance(reporterType);
                toReturn.Add(instance.Report(confFor));
            }
        }
    }
 
    return toReturn;
}

observe - I write a text string in a config file to describ ea type, and now I can pick what object to instantiate :)))

nuget on non-windows

this comes up a lot.

it's easy just install it via nuget with
Install-Package WebDav.Client

- normal devs

for some reason, it works differently when you're not on windows. what we do:

dotnet add package WebDav.Client

why is not dotnet nuget Install-Package WebDav.Client? why does the quintessential nuget function not involve the word “nuget”? All I got for you is a nice big shrug.

entityframework (my beloved)

install packages: * Microsoft.EntityFrameworkCore.Design * Npgsql.EntityFrameworkCore.PostgreSQL (or whatever you like)

migrations:

  dotnet ef migrations add "name of migration"
  dotnet ef database update --connection "Host=asdfasdfasdf etc"
  

enum names

forget “switch(enum) return string” functions, do it with decorators! https://stackoverflow.com/questions/479410/enum-tostring-with-user-friendly-strings

make yourself this function:

public static string GetDescription<T>(this T enumerationValue)
    where T : struct
{
    Type type = enumerationValue.GetType();
    if (!type.IsEnum)
    {
        throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
    }
 
    //Tries to find a DescriptionAttribute for a potential friendly name
    //for the enum
    MemberInfo[] memberInfo = type.GetMember(enumerationValue.ToString());
    if (memberInfo != null && memberInfo.Length > 0)
    {
        object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
 
        if (attrs != null && attrs.Length > 0)
        {
            //Pull out the description value
            return ((DescriptionAttribute)attrs[0]).Description;
        }
    }
    //If we have no description attribute, just return the ToString of the enum
    return enumerationValue.ToString();
}

and then all you have to do is use Description from System.ComponentModel:

private enum PublishStatusValue
{
    [Description("Not Completed")]
    NotCompleted,
    Completed,
    Error
};

what is the actual publish command

specify output folder. I don't know what all the other bullshit it insists on dumping in the folder is.

dotnet publish -c Release -o ../publish
dev/csharp.1699821715.txt.gz · Last modified: 2023/11/12 20:41 by adam