ユーザーシークレットの動きについてちょっと調べてみた

お久しぶりです。100億年ぶりにプログラミングを始めました。
先日、Visual Studio 2019をダウンロードして、何やらいろいろ調べながらやっています。
DBの接続文字列など、以前は config ファイルに書いていたように記憶していますが、何やらいろいろ仕組みが変わっていて、今は appsettings.json に書くのがよさそう。
appsettings.json に関連して、機密情報を扱うときは「ユーザーシークレット」なるものを使うと良さげなことを知ったのですが、ちょっと気になったことを確かめてみました。

appsettings.jsonとダブった項目はどうなるのか?

ユーザーシークレットが使われるみたいです。以下のように記載して確かめてみました。

/* appsettings.json */
{
  "Login": {
    "Email": "hoge@example.com",
    "Password": "hoge"
  }
}
/* secret.js */
{
  "Login": {
    "Email": "secret@example.com",
    "Password": "secret"
  }
}

secret.jsonが存在しない場合はどうなるのか?(git clone した場合など)

ちゃんとappsettings.jsonの値が取得されました。

ユーザーシークレットに関する設定はプロジェクトファイルに以下のように記述されるようです。
この長いIDと同じ名前のフォルダが C:\Users\【ユーザー名】\AppData\Roaming\Microsoft\UserSecrets に作られて、その中に secret.json が置かれるようです。この設定を残したまま、ユーザーシークレットのフォルダを消して確認してみました。

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <UserSecretsId>7a0d510b-d5ad-477a-a103-0d4d117cb851</UserSecretsId>
  </PropertyGroup>

</Project>

DIってなんだっけ?

appsettings.json で設定した値を取得するために、HomeController クラスのコンストラクタの引数を追加したけど、なんで好き勝手にコンストラクタの引数増やして良いの?何が起きてるの?勉強しよう。

ターミナルで実行したときとスクリプトファイルを実行したときで結果が違う

次のようなitems.xmlを作って、

<?xml version="1.0" encoding="UTF-8"?>
<items>
  <item>foo</item>
  <item>bar
baz</item>
  <item>qux</item>
</items>

bash

$echo "cat /items/item[2]" | xmllint --shell items.xml

したときは

/ >  -------
<item>bar
baz</item>
/ >

ってなるけど、

#!/bin/sh
echo "cat /items/item[2]" | xmllint --shell items.xml

を保存したファイルを実行したとき

/ > ------- <item>bar baz</item> / >

ってなるのなんでや!連続したスペース類がスペース1個にされてる...。困るなあ。連続スペースはどうでもいいけど、改行は改行のまま欲しいんだけどな...。

解決した

ファイルに保存するスクリプト

#!/bin/sh
str=`echo "cat /items/item[2]" | xmllint --shell items.xml`
echo "${str}"

ってしたら改行と連続スペースが保持されたままになった。わーい。
あとは、これをsedかなんかで処理して中身だけ取り出したい。

プロジェクトの参照設定

C#のプロジェクトの参照設定がよく分からない。ソリューションは以下のような状況になっている。

プロジェクトA
俺ライブラリ側。プロジェクトBや他のアプリなどでも使う(かもしれない)部品群。このプロジェクトの中で、とあるインターフェースX(.NET Framework 3.0以降で提供されているきわめて標準的なもの)を実装したクラスFooを定義している。つまり、プロジェクトAはインターフェースXを含むdllを参照している。
プロジェクトB
アプリ側。このプロジェクト内で、プロジェクトAのクラスFooを使用している。プロジェクトBはプロジェクトAをプロジェクト参照しているが、インターフェースXを含むdllは参照していない。


この状況でビルドすると、

型 'X' が参照されていないアセンブリで定義されています。アセンブリ ほげほげふがふが への参照を追加してください。

ってエラーが出る。なんでプロジェクトBがインターフェースXを含むdllを参照しないといけないの?プロジェクトBを参照してるからそれでいいやん。

日付や時間を表す文字列を受理するオートマトン②

以下のフォーマットを受理するDFAを作った。
Ideone.com - FxXej0 - Online C# Compiler & Debugging Tool

  • yyyy/MM/dd HH:mm:ss.fff
  • yyyy/MM/dd HH:mm:ss
  • yyyy/MM/dd HH:mm
  • yyyy/MM/dd HH
  • yyyy/MM/dd
  • yyyy/MM
  • yy/MM/dd HH:mm:ss.fff
  • yy/MM/dd HH:mm:ss
  • yy/MM/dd HH:mm
  • yy/MM/dd HH
  • yy/MM/dd
  • MM/dd HH:mm:ss.fff
  • MM/dd HH:mm:ss
  • MM/dd HH:mm
  • MM/dd HH
  • MM/dd
  • HH:mm:ss.fff
  • HH:mm:ss
  • HH:mm
  • mm:ss.fff

受理するかどうか確かめると同時に、どのパターンか判断する方法は無いかな...。
ただし、MM/ddとmm:ssは、それぞれyy/MMとHH:mmと区別できないから、yy/MMとHH:mmとして扱うことにした。

日付や時間を表す文字列を受理するオートマトン①

日付や時間に関する型も用意して、オートマトンでチェックしたい。受理したい形式は以下。

  • yyyy/MM/dd HH:mm:ss.fff
  • yyyy/MM/dd HH:mm:ss
  • yyyy/MM/dd HH:mm
  • yyyy/MM/dd HH
  • HH:mm:ss.fff
  • HH:mm:ss
  • HH:mm
  • mm:ss.fff
  • mm:ss
  • ss.fff

時刻部分はAM/PM表記も許したいな。例えば"01:23 AM"や"01:23:45 PM"とか。
このままだと、HH:mmとmm:ssを区別できないし、ss.fffと実数も区別できない。

整数、実数の時と同じようにDFAC#で実装したい。