らびたろちゃんにっきスマートフォン用の表示で見るらびたろちゃんにっきこの広告は、90日以上更新していないブログに表示しています。2013」の18日目の記事です。猫とC#について書くmatarilloの雑記」でした。MEFなどを勉強しています。勉強している中で、CSharpCodeProviderとMEFを組み合わせたら実行時にDLLを生成してもその読み込みに苦労しないんじゃないかと思ったので、紹介しようと思います。動的コード生成ということで、yfakariyaさんとネタが被ってヒヤヒヤしました・・。(もしかしたらこの組み合わせは普通なのかもしれませんが、個人的に感動したので記事にしちゃいます。)もくじコンソールで入力した文字をそのまま返すクラスを動的に生成して、それをMEFで読み込んで実行してみようと思います。文字からコードを生成するCSharpCodeProviderを使って、入力された文字からコードとDLLを生成します。今回は、以下のインターフェースを実装したクラスを作成し、その中で入力された文字をそのまま返すコードを生成します。GetMessage();}さて、コンソールで入力された文字からコードを生成していきますが、今回はRazorEngineを使ってみようと思います。RazorEngineApp_Dataディレクトリを作成し、その中にテンプレートIMessageTemplate.razorを作成します。}}ポイントは、クラスにつける属性ExportAttributeです。この属性をつけることで、MEFのカタログに公開するクラスであることを指定しています。ExportAttributeのプロパティに名前をつけることで、生成した後に名前を指定してインスタンスを取得できるようにしています。Razorに渡すモデルとして、以下のクラスも作成します。}}準備は整ったので、Razorを使ってコードを生成するクラスCodeFactoryを作成します。}}このクラスを使ってコードを生成してみます。Console.Write("文字を入力してください。}}CteateIdメソッドでは、Guidからクラス名とMEFのカタログに公開する際の名前を生成しています。先頭にアンダーバーをつけているのは、クラス名は数値から始められないからです。実行して、なにか文字を入力してみると、生成されたコードが表示されます。生成したコードからDLLを作成するソースコードの生成ができましたので、次はDLLを作成していきます。DLLの作成にはCSharpCodeProviderを利用します。VB.NETDLLを生成する処理については、ほぼ@ITの記事そのままですので、特に説明はしません。注意する点としては、参照するDLLを指定する際に、自分自身のexeファイルを指定する必要があることです。}}このクラスを使って、DLLを生成するように、Mainメソッドを書き換えます。Console.Write("文字を入力してください。Framework)を使い作成したDLLを読み込むクラスを作成していきます。(MEF)MEFについては、okazukiさんのブログに入門記事がまとまっています。かずきのBlog@hatenaDLLを読み込む手順は、以下のとおりになります。カタログを作成するカタログを指定してコンテナを作成するインターフェースと名前を指定してコンテナからインスタンスを取得するそれぞれの細かい手順については、うえで紹介した入門記事にすべてまとまっています。(丸投げ)上記の処理を実行するクラスMessageContainerを作成します。}}ポイントは、Refreshメソッドです。RefreshメソッドではDirectoryCatalog#Refreshを呼び出しています。このメソッドを呼び出すことで、コンストラクタで指定したディレクトリ以下に新しいDLLがあれば、それを含むようにカタログを更新してくれます。DLLを生成後にRefreshメソッドを呼び出すことで、毎回1からコンテナを作成する必要がありません。Resolveメソッドに、コード生成とDLL作成時に指定したIDを指定することで、生成したクラスのインスタンスが取得できます。そのインスタンスのメソッドGetMessageを実行することで、入力した文字が取得できるようになります。Mainメソッドを次のように書き換えます。ついでに時間も測っておきます。Console.Write("文字を入力してください。}実行してみると、マシンの性能によりますが、コード生成からメッセージ出力までだいたい200ミリ秒くらいでできます。一度生成したDLLについてはMEFのコンテナでキャッシュされていますので、時間がかかりません。IDをキャッシュして、コンソールからの入力がなかった場合は前回のメッセージを出力するように修正してみます。Console.Write("文字を入力してください。MEFを組み合わせることで、実行時に生成したDLLを簡単に扱う方法を紹介しました。今回の例は特に役に立たないと思いますが、これを使うことでLINQPadのようなものが簡単に作れます。実際に、Fluentdを使ってMongoDBに集めたログなどのデータに対して、入力したLINQを利用して検索・集計するWebツールを作ってます。CSharpCodeProviderではなく、いま話題(?)のRoslynなどを使えば、もっと面白いことができるかもしれないですね。追いかけてませんが・・・。MEFを組み合わせる方法の紹介でした。今回のソースコードは、以下においてあります。nameofという演算子が追加されています。2013の8日目の記事です。2013の3日目の記事です。(1)月別アーカイブリンクヘルプはてなブログお知らせはてなブログをはじめよう!rabitarochanさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。