きな粉もち.net

.NET関連仕事に携わっています。OSSのソースを読んで気がついたことを中心に呟いたりブログに投稿したりしています。最近はUiPathを使ったRPAも研究中。気軽にフォローやツッコミよろしくおねがいします! Gitはここを使っています https://github.com/kinakomotitti

log4net × System.Attribute × 呪文

log4netのDeep Diveの続きになります。

前回*1に引き続き、log4netを読んでいるうちに知ったCustomAttributeについてまとめます。
今回は、特に設定したCustom Assemblyの情報をどうやって取得するかを中心にまとめます。
以下のように(普通に)Loggerのインスタンスを生成する時のことを考えます。

LogManager.GetLogger("LoggerName");

処理が始まると、なんやかんやでlog4net.Core名前空間のDefaultRepositorySelectorクラスに処理が進みます。
そして、同クラスのConfigureRepositoryメソッドが実行されます。

一部抜粋しました。

private void ConfigureRepository(Assembly assembly, ILoggerRepository repository)
{
		if (assembly == null)
		{
			throw new ArgumentNullException("assembly");
		}
		if (repository == null)
		{
			throw new ArgumentNullException("repository");
		}
		object[] configAttributes = Attribute.GetCustomAttributes(assembly, typeof(log4net.Config.ConfiguratorAttribute), false);
               ・・・
}

この最後の行のように、AttributeクラスのGetCustomAttributesメソッドを利用することで、
設定したCustom Assemblyの中にある”第二引数で指定した型の情報”を取得することができます。

log4netでは、利用するときに以下の呪文を唱えるので、log4net.Config.ConfiguratorAttributeクラスを継承しているXmlConfiguratorクラスのインスタンスを取得することができます。

呪文↓

[assembly: log4net.Config.XmlConfigurator(Watch = true,ConfigFile =@".\config\log4net.config")]

取得したAttributeの配列はループでそれぞれConfigureメソッドを実行しながら処理されていきます。

foreach(log4net.Config.ConfiguratorAttribute configAttr in configAttributes)
{
	if (configAttr != null)
	{
	 try
	 {
	   configAttr.Configure(assembly, repository);
	 }
	 catch (Exception ex)
	 {
 	   LogLog.Error(declaringType, "Exception calling ["+configAttr.GetType().FullName+"] .Configure method.", ex);
	 }
	}
}


複数呪文を唱えておけば、それだけ設定してくれるということでしょうか・・・
どういうときに複数呪文唱えるか想像ができませんが・・・
今はMPが足りないので、唱えられないようですw

なお、log4netで定義されているConfiguratorAttributeクラスを継承しているクラスは以下の2つです
・SecurityContextProviderAttribute
・XmlConfigurator


まとめ!

属性情報を読み取りたいときは、System.Attributeクラスを利用します!
log4netの設定ファイルの構成処理にも利用されています。
忘備録ですが、以下のように実装すると、アセンブリバージョン情報を取得することができます。

var version = System.Attribute.GetCustomAttributes(System.Reflection.Assembly.GetCallingAssembly(), typeof(System.Reflection.AssemblyFileVersionAttribute));

*1:ここに脚注を書きます kinakomotitti.hatenablog.com