User Tools

Site Tools


dev:csharp

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 in your dev env:

dotnet tool install --global dotnet-ef

install packages:

  • Microsoft.EntityFrameworkCore.Design
  • Npgsql.EntityFrameworkCore.PostgreSQL (or whatever you like)
dotnet-ef dbcontext scaffold "Host=HOST;Database=DBNAME;Username=USERNAMEPassword=PASSWORD;IncludeErrorDetail=true;" Npgsql.EntityFrameworkCore.PostgreSQL

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

also you can't not get appsettings.Development.json to show up in release. your only option is to delete it manually.

why is asp.net not accepting my frombody thing?

microsoft replaced the working json parser with one that doesn't. https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-apis/

fix:

  1. dotnet add package Microsoft.AspNetCore.Mvc.NewtonsoftJson –version [compatible version]
  2. go find where services are being added; services.AddControllers().AddNewtonsoftJson();. (hint: Builder.Services?)

which is a field, which is a property?

public class MyClass
{
    // this is a field.  It is private to your class and stores the actual data.
    private string _myField;
 
    // this is a property. When accessed it uses the underlying field,
    // but only exposes the contract, which will not be affected by the underlying field
    public string MyProperty
    {
        get
        {
            return _myField;
        }
        set
        {
            _myField = value;
        }
    }
 
    // This is an AutoProperty (C# 3.0 and higher) - which is a shorthand syntax
    // used to generate a private field for you
    public int AnotherProperty { get; set; } 
}

src: https://stackoverflow.com/a/295109/1173856

dev/csharp.txt · Last modified: 2024/12/08 03:53 by adam