.NETで作る!

.NETに関するあれこれ(C#、VB.NET)

アプリケーション単位で管理できて書き込みもできる設定ファイルを自作する

元ネタ

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パッケージ化すると幸せになれる予感。

. .