2017-09-17 4 views
0

cを文字列に一致するプラグインを取得し、私のプラグインクラスは、私は、ときにアプリケーションと呼ばれている各プラグインのActionメソッドを呼び出す機能を持っている私のローダークラスでは、この私はプラグインシステムを持っている#

namespace CSV_Analyzer_Pro.Core.PluginSystem 
{ 
    public interface IPlugin 
    { 
     string Name { get; } 
     string Version { get; } 
     string TargetVersion { get; } 
     string Description { get; } 
     string TargetFramework { get; } 
     void Action(); 
    } 
} 

のように見えます

public void Init() 
{ 
    if(Plugins != null) 
    { 
     Plugins.ForEach(plugin => plugin.Action()); 
    } 
} 

をロードされ、私は自分のアプリケーションに

を呼び出すことができますので、私は似メソッドを使用したいですそれは何を知っているのに役立ちます場合は

これはこれは私がこれまで

public void GetPluginByTargetFramework(string framework) 
{ 
    //Get all plugins 
    List<IPlugin> frameworkPlugs = new List<IPlugin>(); 

    //Put all plugins targeting framework into list 

    if(frameworkPlugs != null) 
    { 
     frameworkPlugs.ForEach(plugin => plugin.Action()); 
    } 
} 

持っているものである

"UI"フレームワークをターゲットにすべてのプラグインを取得し、リストに入れ、その後、私は方法を反復処理することができなければなりません異なる変数はここにある全体PluginLoaderクラス

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Reflection; 
using System.Threading.Tasks; 

namespace CSV_Analyzer_Pro.Core.PluginSystem { 
    public class PluginLoader { 
     public static List<IPlugin> Plugins { set; get; } 

     public void LoadPlugins() { 
      Plugins = new List<IPlugin>(); 

      if (Directory.Exists(Constants.PluginFolder)) { 
       string[] files = Directory.GetFiles(Constants.PluginFolder); 
       foreach(string file in files) { 
        if (file.EndsWith(".dll")) { 
         Assembly.LoadFile(Path.GetFullPath(file)); 
        } 
       } 
      } 

      Type interfaceType = typeof(IPlugin); 

      Type[] types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass).ToArray(); 

      foreach(Type type in types) { 
       Plugins.Add((IPlugin)Activator.CreateInstance(type)); 
      } 
     } 

     public void Init() { 
      if(Plugins != null) { 
       Plugins.ForEach(plugin => plugin.Action()); 
      } 
     } 

     public void GetPluginByTargetFramework(string framework) { 
      //Get all plugins 
      List<IPlugin> frameworkPlugs = new List<IPlugin>(); 

      //Put all plugins targeting framework into list 

      if(frameworkPlugs != null) { 
       frameworkPlugs.ForEach(plugin => plugin.Action()); 
      } 
     } 
    } 
} 
+0

したがって、特定の 'フレームワーク 'を持つ' Plugins'の項目だけが必要ですか? –

+3

あなたの_question_は何ですか?それは何ですか?具体的には、あなたは理解しづらいことがありますか?あなたの疑問を解決して、良いコード[mcve]が含まれていることを確認し、そのコードが現在正確に何をしているのか、あなたが何をしたいのかを明確かつ詳細に説明し、解決できない_specific_問題の説明。 –

答えて

1

使用LINQですさん.Where

frameworkPlugs = Plugins.Where(p => p.TargetFramework == framework); 

あなたはすべて一緒にそれをすることができます置く:LINQクエリがnullになることはありませんIEnumerable<T>を返すので、そのコレクションをチェックする必要がないことを

public void GetPluginByTargetFramework(string framework) 
{ 
    Plugins.Where(p => p.TargetFramework == framework) 
      .ToList().ForEach(p => p.Action()); 


    //Better to use a foreach loop on the items returned from the where 
    foreach(var item in Plugins.Where(p => p.TargetFramework == framework) 
      item.Action(); 
} 

通知はnullではありません - 何も一致しない場合はwhereは空ですが、nullではありません

あなたが見てい小文字を区別しない文字列の場合を比較したい場合は:あなたは、プラグインのリストをフィルタリングする必要がlinq case insensitive (without toUpper or toLower)

+0

これはコンパイルされません。また、 'ToList'と' ForEach'を使って時間とメモリを浪費します。 –

+0

@RichardSchneider - コンパイルの場合 - true - コピー貼り間違いでした。 'ToList'については、説明が追加されます - ちょうどOPのやり方にとどまることを決めました –

+0

これは動作しますが、' Enviroment.Exit(1) 'を使ってアプリケーションを終了するときに' 'ウィンドウハンドルを作成中です。 – FlamingGenius

1

を。 Whereメソッドを使用します。

public void GetPluginByTargetFramework(string framework) 
{ 
    if (Plugins == null) return; 
    foreach (var p in Plugins.Where(p => p.TargetFramework == framework)) 
    p.Action(); 
} 

ところで、名前が操作と一致しません。 InitForFrameworkへの変更を提案する。

関連する問題