2007年07月03日

Enterprise Library 3.0 の Logging Application Block の Special Sources

   このエントリーをはてなブックマークに追加 Clip to Evernote
Enterprise Library 3.0 の Logging Application Block の Special Sourcesって使い方が良く分からなかったのだけれど、なんとか理解できた。(ような気がする...)
やはり、はじめからドキュメントを読むべきだった。
Webで該当する記事を見つけるのに、うろうろするよりは、ドキュメント読むほうが、早いということは分かってるんだけど、英語なんで、どうも敬遠しちゃうんだよね。

備忘のために、ここに記録。

------
Logging Errors & Warnings
ログ出力処理中にエラーあるいは、ワーニングが発生した時の処理(Trace Listener)を指定。
デフォルトで、Formatted EventLog TraceListene が指定されている。

Unprocessed Category
処理されなかったカテゴリのログの処理(Trace Listener)を指定。デフォルトでは何も指定しない。

All Events
すべてのログエントリの処理(Trace Listener)を指定。デフォルトでは何も指定しない。


これらの項目には、SourceLevelsプロパティが用意されているので、All EventsであってもWarning とか Error とかを指定すれば、不要なログは除外できる。
------  

Posted by gushwell at 20:10Comments(0)TrackBack(0)

2007年05月07日

Enterprise Library 3.0 - April 2007

   このエントリーをはてなブックマークに追加 Clip to Evernote
Enterprise Library 3.0 - April 2007 がリリースされたので、ダウンロードしてみました。

今までは、CTP版のソースを一部改変して利用していたので、WinMergeを利用し、その変更部分を正式版のソースにマージする作業を行いました。

この該当するソースの中には、

 private static Type[] LoadTypesFromAssembly(Assembly assembly) {
Type[] types = null;
try {
types = assembly.GetTypes();
} catch (ReflectionTypeLoadException) {
}
return types;
}

というコードがあって、null を返すことで、GetTypesに失敗していることを上位メソッドに知らせていたわけですが、これだと、ReflectionTypeLoadException例外の情報が消えてしまうので、なんで、わざわざこんなことしてるんだろう? って疑問に思っていました。
まあ、僕よりは遥かに優秀な人たちが書いたコードだから、それなりに意味があるのかな、なんて思っていたのですが、Enterprise Library 3.0 - April 2007 のソースでは、

 private static Type[] LoadTypesFromAssembly(Assembly assembly) {
Type[] types = null;
types = assembly.GetTypes();
return types;
}


と変更されていました。

やっぱり、ここでの catchは不要だったんですね。
  
Posted by gushwell at 20:22Comments(0)TrackBack(0)

2007年04月16日

Enterprise Library Configuration Tool の TypeSelectorEditor(2)

   このエントリーをはてなブックマークに追加 Clip to Evernote
前回の続きです。
今日の話題の中心は、AppDomain.AssemblyResolve イベントです。

TypeSelector.cs には、以下のようなコードがあります。

 private static Type[] LoadTypesFromAssembly(Assembly assembly) {
Type[] types = null;
try {
types = assembly.GetTypes();
} catch (ReflectionTypeLoadException) {
}
return types;
}


ここで、依存したアセンブリを読み込めないため、ReflectionTypeLoadException 例外が発生し、nullが返り、エラーメッセージが表示されてしまいます。
なお、引数で渡ってくる Assemblyは、Assembly.LoadFrom メソッドで、読み込まれた別フィルダにあるアセンブリのインスタンスです。

結局、TypeSelector.cs のTypeSelectorクラスに、以下のようなコードを追加して、対応しました。

  private static AppDomain currentDomain = AppDomain.CurrentDomain;

static TypeSelector() {
currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(ResolveEventHandler);
}

private static Assembly ResolveEventHandler(object sender, ResolveEventArgs args) {
Assembly myAssembly;
string tempAssmbPath = "";

string path = System.Environment.GetEnvironmentVariable(
"EntLibAsmPath", EnvironmentVariableTarget.Process);
foreach (string assemblyFolder in path.Split(';')) {
tempAssmbPath = System.IO.Path.Combine(assemblyFolder,
args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll");
if (File.Exists(tempAssmbPath)) {
myAssembly = Assembly.LoadFrom(tempAssmbPath);
if (myAssembly != null) {
return myAssembly;
}
}
}
return null;
}


AppDomain.AssemblyResolve イベントはアセンブリの解決に失敗したときに発生します。
このイベントハンドラの引数の ResolveEventArgs.name プロパティには、解決するアセンブリ表示名が渡ってきますので、その情報を基に、アセンブリをロードするようにします。

これで、別ディレクトリにあるアセンブリを読み込むことが可能となります。

※このコードでは、環境変数に設定されているパスを検索しています。
  
Posted by gushwell at 23:40Comments(0)TrackBack(0)

2007年04月10日

Enterprise Library Configuration Tool の TypeSelectorEditor (1)

   このエントリーをはてなブックマークに追加 Clip to Evernote
前回、書いた[Enterprise Library Configuration Tool の TypeSelectorEditor]の内容に大きな勘違いがあったので、再度、内容を見直しました。

----

Enterprise Library Configuration Tool に 独自の構成設定を組み込んだ際に、ちょっと困ったことが発生しました。

独自ABを作成するときに、GUIで利用するNodeクラスを定義し、そのプロパティの属性を以下のように記述すると、Enterprise Library Configuration Tool で、型名を入力する際に、Type選択ダイアログが表示されるようになります。

public sealed class MyTaskNode : NameTypeConfigurationNode {

...

[Required]
[SRCategory("CategoryGeneral", typeof(Resources))]
[BaseType(typeof(Gushwell.SampleClass), TypeSelectorIncludes.None)]
[Editor(typeof(TypeSelectorEditor), typeof(UITypeEditor))]
public override string Type {
get { return _typeName; }
set {
if (null == value)
throw new ArgumentNullException("value");
_typeName = value;
}
}
}

このダイアログでは、読み込まれているアセンブリの中から、BaseType属性で指定したSampleClassの派生クラスをTreeViewに一覧表示してくれます。
しかし、BaseType属性で指定したクラスが、独自に定義したクラスだと、当然ながら読み込まれていないので、一覧には表示されません。
このような場合は、「Load Assembly...」というボタンを押し、指定したいクラスが定義されているアセンブリをロードさせることができます。

ここまでは、良いのですが、いざ、BaseTypeで指定した、Gushwell.SampleClass を継承したクラスが定義されているアセンブリを読み込もうとすると、


There were no types found in the assembly 'Sample' that
implement or inherit from the base type 'AbstractSample'.


というエラーダイアログが出てしまいます。

読み込むアセンブリファイルが、Enterprise Library Configuration Tool とは別のフォルダにあるため、依存したアセンブリが読み込めないようです。

ダイアログで読み込むアセンブリファイルを 全部 Enterprise Library Configuration Tool と同じフォルダに入れれば、回避できそうですが、それはやりたくありません。
同様に GACに入れれば、回避できますが、そのためだけに、GACに入れるのも良い解決策とは思えません。

結局、Enterprise Library のソースに手を入れるしか、方法はなさそうです。  
Posted by gushwell at 21:48Comments(0)TrackBack(1)

2007年03月13日

Enterprise Librry:Configuration ツールにアセンブリを認識させる

   このエントリーをはてなブックマークに追加 Clip to Evernote
Enterprise Libraryに独自のApplication Blockを追加する場合、Enterprise Library Configuration ツールに、自作のDLLを認識させる必要がある。

C#の場合、AssemblyInfo.cs に以下の記述が必要。

[assembly: ConfigurationDesignManager(typeof(PrelimHandlingConfigurationDesignManager))]

これをやらずに、なぜEnterprise Library Configuration ツールにメニュー項目が追加されないのか分からずに悩んだ。


構成ファイルから、さまざまな設定情報を読み込み、その設定内容によって動作が変わるフレームワークを作成する場合、この Enterprise Library の Configuration ツールで、構成情報を設定できるようになれば楽だな、と思って調査を開始したのだが、分からないことだらけで、かなり時間を費やしてしまった。

Application Block の形式にするのは、なかなか骨の折れる作業が必要だけれど、それなりのメリットは得られると思う。

  
Posted by gushwell at 23:29Comments(0)TrackBack(0)

2007年03月07日

Enterprise Library: カスタムトレースリスナー

   このエントリーをはてなブックマークに追加 Clip to Evernote
Enterprise Library のカスタムTraceListener をC#で、作成しようとしたのだが、残念ながら日本語のサイトでは見つけることができなかった。

googleで検索し、CodeGuru のサイトに、
Enterprise Library 2.0: The Logging Application Block

という記事があるのを見つける。うれしいことに、C#のサンプルコードもダウンロードできるようになっている。

なるほど、.NET Framework の TraceListenerあるいはその派生クラスを元に、クラスを定義し、属性
[ConfigurationElementType(typeof(CustomTraceListenerData))]

を付加すれば良いだけか。

もっとも簡単なのが、CustomTraceListenerから派生させる方法。

このとき、
void TraceData(TraceEventCache eventCache, string source, 
TraceEventType eventType, int id, object data)

をoverrideするのだが、最後の引数 object には、LogEntry のインスタンスが渡ってくるので、この情報を元に、ログ出力する処理を書けばよいことになる。

TraceDataメソッド内で、

string text = this.Formatter.Format(data as LogEntry);

とすれば、構成ファイルで指定した、Formatter が呼び出される仕組みに
なっている。

string text = (data as LogEntry).ToString();

とした場合は、TextFormatter の Formatメソッドが呼ばれることになる。

構成ファイルに付加的な情報をセットしておいて、TraceListener内で、それを利用することも可能なようだ。

ここまでわかれば、EnterpriseLibraryの該当するソースそのものを読むのもそれほど大変なことではないかな。
  
Posted by gushwell at 22:02Comments(0)TrackBack(0)

2007年03月05日

Enterprise Library: Logging Application Block

   このエントリーをはてなブックマークに追加 Clip to Evernote
Enterprise Library Logging Application Block を使ってみる。

C#で、ログ出力するには、以下のように書けばよい。

LogEntry log = new LogEntry();
log.Message = "エラーが発生したよ";
log.Severity = System.Diagnostics.TraceEventType.Error;
Logger.Write(log);

で、実際に、どこにこのログが出力されるかは、構成ファイルで設定することになる。
ここまでは、Webで調べてすぐにわかったのだが、Severity プロパティに設定した値によって、イベントログに吐き出したり、テキストログに吐き出したり切り分ける方法が、わからず悩んでしまった。

試行錯誤の結果、次のようにすればできることを確認。

例えば、
・Error 以上ならば、イベントログへ
・すべての情報を テキストファイルへ、
出力したい場合は、構成設定を以下のように設定すればよい。

Category Sources
General (SourceLevels : Error)
EventLog TraceListenerを設定する
Special Sources
All Events (SourceLevels : All)
FlatFile TraceListener を設定する。




  
Posted by gushwell at 21:45Comments(0)TrackBack(0)

2006年11月28日

patterns & practices の日本語のページ

   このエントリーをはてなブックマークに追加 Clip to Evernote
Microsoft patterns & practices の日本語のページ(http://www.microsoft.com/japan/resources/practices/)
が無くなってしまったようです。
このURLにアクセスすると、USのサイトに飛んでいくようになってます。

「.NET アプリケーションのパフォーマンスとスケーラビリティの向上」
の内容で確認したいことがあったのに。。。

と思ったら、msdn libraryに入っていました。でもmsdn2じゃないってことは、.NET Framework2.0 の開発では、参考にしてくれるな、ってことですか?
  
Posted by gushwell at 21:03Comments(0)TrackBack(0)