2009-03-16 6 views
1

私が現在持っている問題と解決策を説明しましょう。そして、なぜそれが悪い考えであるのか(それが前提である)、そして私がそれをより良いシステムにするために何ができるのかを教えてください。リフレクション&アプリケーションデザイン

今私はファイルを解析し、CSVや他のフォーマットにリッピングする600 "リッパー"を持っています。リッパーはすべて共通のインターフェースと基本クラスを実装しています。そのジョブの構成に応じてジョブがキューに入れられた瞬間に、特定のリッパーがリフレクションを使用して呼び出されます。

  foreach (var stream in streams) 
      { 
       try 
       { 
        // load it 
        Assembly asm = Assembly.LoadFile(Path.Combine(stream.RipperPath, stream.RipperFileName), new Evidence()); 
        if (asm == null) 
        { 
         MessageBox.Show(String.Format("Invalid Interface ripper loaded.\n{0}", Path.Combine(stream.RipperPath, stream.RipperFileName))); 
         return; 
        } 

        foreach (Type objType in asm.GetTypes()) 
        { 
         if (!objType.IsPublic) 
          continue; 

         // make sure the type isn't Abstract 
         if (((objType.Attributes & TypeAttributes.Abstract) == TypeAttributes.Abstract)) 
          continue; 

         // IRipper is the interface that all of the Rippers must implement to be loaded 
         Type objInterface = objType.GetInterface("IRipper", true); 
         if (objInterface == null) 
          continue; 

         try 
         { 
          var iri = (IRipper)Activator.CreateInstance(objType); 

          // Rippers must register with their hosts 
          iri.Host = this; 
          iri.OnStart += RipperStart; 
          iri.OnComplete += RipperComplete; 
          iri.OnProgressChanged += RipperStatusUpdate; 
          iri.dataStream = stream; 
         } 
         catch (Exception ex) 
         { 
          Console.WriteLine(ex.Message); 
         } 
        } 
       } 
       catch (Exception ex) 
       { 
        MessageBox.Show(String.Format("Error loading interface: {0}\n{1}", Path.Combine(stream.RipperPath, stream.RipperFileName), ex.Message)); 
       } 
      } 

すべてのリッパーは、インターフェイスがそれに契約する「Rip()」という機能を実装しています。

私が見ることができる唯一の問題は、600アセンブリをロードした後(必要なときにロードされているため)、使用後にアンロードされないと少し遅くなり始めることです。

あなたは何をお勧めしますか?

答えて

1

実際には600種類のリッパー、600本のストリーム、いくつかのリッパーがありますか?あなたは本当に各リッパーがそれ自身のアセンブリに入る必要がありますか?あなたがリッパーを一緒に束ねることができるなら、はるかに少ないアセンブリを持つことができます。ストリームの詳細にタイプ名と実行可能ファイルが含まれている場合は、複数のリッパーを持つことができ、アセンブリを調べる必要はありません。Assembly.GetTypeに電話してください。

アセンブリあたり実際にどれくらいのオーバーヘッドがあるのか​​分かりませんが、600組のアセンブリでかなりの量のメモリが必要になりますが、それ以上のパフォーマンスには影響しません。

全体的なアプローチは妥当と思われますが、Managed Extensibility Framework (MEF)を見てみることもできますが、あなたの場合は過度のものかもしれませんが、一見価値があります。もう1つは、「ストリームを処理する」コードから「リッパーを取得する」ことです。

+0

ありがとうジョン - 私は各リッパーへの完全なパスを持っており、彼らはすべて同じインターフェースを使用しています –

+0

また、いくつかのほぼ600リッパー - 組み合わせることができない非常にカスタムファイルフォーマット –

+0

しかし、リッパーはそれ自身のアセンブリになる?単一のアセンブリにそれらをたくさん入れてから、ストリーム情報の型を参照することはできませんか? 10個のアセンブリから600個のタイプを読み込むのは、1個のタイプを持つ600個のアセンブリよりもはるかに合理的です。 –

0

System.Addinの情報を参照してください。アドインは独自のアプリドメインに読み込まれているため、不要になったときにそれらをきれいにアンロードすることができます。

関連する問題