アプリケーション単位で管理できて書き込みもできる設定ファイルを自作する
元ネタ
VB アプリケーション設定の保存と読み込み@Visual Basic 中学校
- 設定にはユーザーごとの設定である「ユーザースコープ」と、アプリケーションで共通である「アプリケーションスコープ」の2種類がある。
- ユーザースコープの設定を変更した場合は、ユーザーのアプリケーション設定フォルダにuser.configと言う名前のファイルが作成され、そこに値が保存される。
- ユーザースコープの設定は読み書きできるが、アプリケーションスコープの設定は読み取りだけができる。
一般には上記の仕様で問題ないですが、バッチ系のアプリなどでは
- 利用者は1人に限定
- 設定ファイルはexeと近い場所に保管したい(探すのが面倒。)
- 前回の実行状況などを記録しておきたい
ということもよくあり、appconfigが適していないケースがあります。
というわけで、シリアル化/逆シリアル化を使用して独自設定ファイルを作ってみましょう。
コード
.NET3.0から利用できる「DataContractSerializer」を使用したぐらいで、たいして難しくもないです。なお、設定値管理のためシングルトンを適用しています。
Imports System.Reflection Imports System.Runtime.Serialization Imports System.Xml 'ref System.Runtime.Serialization.dll ''' <summary> ''' Application parameter. ''' </summary> Public Class AppParameter #Region "Constractor(singleton)" Private Shared _instance As AppParameter Private Sub New() End Sub ''' <summary> ''' Get Instance(singleton). ''' </summary> ''' <returns></returns> Public Shared Function GetInstance() As AppParameter If _instance Is Nothing Then _instance = Load() End If Return _instance End Function #End Region ''' <summary> ''' Parameter1. ''' </summary> ''' <returns>Sample</returns> Public Property Parameter1 As Integer #Region "Save / Load method" ''' <summary> ''' Save config file. ''' </summary> Public Sub Save() Dim ser As New DataContractSerializer(GetType(AppParameter)) Using w = XmlWriter.Create(ConfigPath) ser.WriteObject(w, Me) End Using End Sub ''' <summary> ''' Load config file. ''' </summary> ''' <returns></returns> Private Shared Function Load() As AppParameter 'If config file isnot found then create force. If IO.File.Exists(ConfigPath) = False Then Dim c = New AppParameter c.Save() Return c End If Dim ser As New DataContractSerializer(GetType(AppParameter)) Using w = XmlReader.Create(ConfigPath) Return DirectCast(ser.ReadObject(w), AppParameter) End Using End Function Private Shared ReadOnly Property StartupPath As String = IO.Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName Public Shared ReadOnly Property ConfigPath As String = IO.Path.Combine(StartupPath, "parameter.config") #End Region End Class
使う
一般的なシングルトンクラスンを呼ぶのとまったく同じ。値を変更したときはSaveメソッドを呼んで永続化する必要あり。
prm.Parameter1 = Now.ToString("fff")
は単なる乱数の保存ですので意味はありません。
Module Module1 Sub Main() Dim prm = AppParameter.GetInstance Console.WriteLine(String.Format("load parameter : {0}", prm.Parameter1)) prm.Parameter1 = Now.ToString("fff") prm.Save() Console.WriteLine(String.Format("write parameter : {0}", prm.Parameter1)) Console.WriteLine("press any key to end.") Console.ReadKey() End Sub End Module
余談
パラメータ値はアプリケーションごとによって変わるので、ソースコードをNuGetパッケージ化すると幸せになれる予感。