こんにちは!

IMPRICH CREATEのハナミズキです。

今回は、[.NET Framework]から[.NET Core]へクラスライブラリを書き換えするとき
メモした内容を忘備録としてあげます。

GitHubURL:[.NET Framework]版
https://github.com/hanamizuki10/LogManagerNet
※GitHubに上がっているテストケースは環境構築の為だけだったので、今ブログ登録時点では適当です。

GitHubURL:[.NET Core]版
https://github.com/hanamizuki10/LogManagerCore2
※GitHubに上がっているテストケースは環境構築の為だけだったので、今ブログ登録時点では適当です。

前提

今回は、ログ出力ライブラリをCore版に変えるように対応します。
このログ出力ライブラリLogManagerですが、log4netで痒い所に手が届かない設定というか自分の好きな形式のログ出力機構を作りたくて作ったライブラリです。

環境

  • Windows 10 Pro(64bit)
  • Visual Studio 2017

やった事

基本的に以下の流れで移行できました。

  • .NET Coreのクラスライブラリ(.NET Core)を選択
  • 元ソースコードを、丸っとコピー
  • 名前空間(namespace)より上に記載しているusing が抜けていたので合わせてコピー
  • エラーの原因をもとに一つ一つ対策をチェックして対応

Frameworkで出来てCoreで出来なかった事

  • 設定ファイル(app.Config)の呼び出しが、それまでのやり方ではできなかった。
    [それまでの.NET Frameworkのやり方]

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <appSettings>
        <add key="LogLevel" value="DEBUG" />
        <add key="MaxSizeLimitMB" value="1" />
        <add key="LogRotateLimitIndex" value="0" />
        <add key="Encoding" value="shift_jis" />
        <add key="LogDirPath" value="D:\temp\C#" />
        <add key="LogFileName" value="_debug" />
        <add key="LogFileNameExtension" value=".log" />
        <add key="LogFileNamePrefixDateTimeString" value="yyyyMMdd" />
        <add key="LogFileNameSuffixDateTimeString" value="" />
      </appSettings>
    </configuration>
    // クラスの宣言前にusing System.Configuration;を指定する
    
    // 設定ファイル(log.config)を取り込む
    string configFile  = @"log.config";
    ExeConfigurationFileMap exeFileMap = new ExeConfigurationFileMap { ExeConfigFilename = configFile };
    Configuration config = ConfigurationManager.OpenMappedExeConfiguration(exeFileMap, ConfigurationUserLevel.None);
    
    // 設定値のキー(key)に合わせて値keyvalueを取得する。
    string keyvalue = config.AppSettings.Settings[key].Value;
    

    [Core向けに対策したやり方]

    {
      "LogLevel": "DEBUG",
      "MaxSizeLimitMB": "1",
      "LogRotateLimitIndex": "10",
      "Encoding": "shift_jis",
      "LogDirPath": "D:\\temp\\C#\\log",
      "LogFileName": "_debug",
      "LogFileNameExtension": ".log",
      "LogFileNamePrefixDateTimeString": "yyyyMMdd",
      "LogFileNameSuffixDateTimeString": ""
    }
    
    // 事前にNuGetを利用して、パッケージを「Microsoft.AspNetCore」をインストールする。
    // クラスの宣言前にusing Microsoft.Extensions.Configuration;を指定する
    
    // 設定ファイル(log.config.json)を取り込む
    string configFile  = @"log.config.json";
    
    // exeと同じフォルダにある定義ファイルを指すための指定
    string basePath = Directory.GetCurrentDirectory();
    // (万が一自前で)Windowsサービス化している場合こっちを使う
    // string basePath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
    
    IConfigurationRoot config = new ConfigurationBuilder()
    .SetBasePath(basePath)
    .AddJsonFile(configFile, optional: true)
    //.AddXmlFile("App.config") import Microsoft.Extensions.Configuration.XML
    .AddEnvironmentVariables() // 必要であれば追加
    .Build();
    
    // 設定値のキー(key)に合わせて値keyvalueを取得する。
    string keyvalue = config[key];
    

  • 実行時にEncoding.GetEncoding(“shift_jis”)にて例外が発生した。
    [それまでの.NET Frameworkのやり方]

     
    // クラスの宣言前にusing System.Text;を指定する
     
    // 目的の文字コードに合ったEncodingオブジェクトを取得する
    Encoding.GetEncoding("shift_jis");
    

    [Core向けに対策したやり方]

     
    // 事前にNuGetを利用して、パッケージを「System.Text.Encoding.CodePages」をインストールする。
    // クラスの宣言前にusing System.Text;を指定する
     
    // エンコーディング プロバイダーを登録。
    // "shift_jis"のような追加の文字エンコーディングへのアクセスを提供できるようにする。
    Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
    
    // 目的の文字コードに合ったEncodingオブジェクトを取得する
    Encoding.GetEncoding("shift_jis");
    

以上でした。
私の自作ライブラリの方向性的に、上記のエラーしか移行時に発生しませんでしたが、
色んなコーディングをしていれば、他にもひっかけエラーがあると思います。

出来ることは、一つ一つエラーを潰していくしかないですね。

ソースコードの移行作業で一番怖いのは、ビルドエラーより実行時エラーです。
今回の例でいうとEncoding.GetEncoding(“shift_jis”);のケースです。
膨大なソースコードを使って移行するときは、本当に要注意です。
もし、移行するとなった時は、改めて一から開発した時と同じように、注意して試験していくことを推奨します。

ユニットテストケースでの補足

何気なく、単体テストケースも違うのかな?って思って調べたので情報共有します。
結論から言うとソースコード上において、簡単に動かすレベルだと差異はありませんでした。
しかし、テストケースのプロジェクトを作る時が問題です。
最初に選択する単体テストプロジェクトの選択を間違うと、動かないです。
正直な話、当たり前かもしれないですが、こんな当たり前のことに私は躓きました。
なんというか、見えてなかったです。

↓Frameworkに慣れている人がCora向けの単体テストプロジェクト作成で失敗しがちな奴(私だけ?)

↓Cora向けの正しい単体テストプロジェクトのありか

自分のために、また、同じように悩んだ人のために忘備録として記載しました。

以上、ではでは!

この記事へのコメント

コメントはまだありません。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA