どのようにアプリケーションを別のモジュールに分けることができますか?エンドユーザーは購入したモジュールのみを使用します。私はプラグアンドプレイを使用してそれを使用できますか?C#Windowsフォームアプリケーションのモジュールセキュリティ?
答えて
はい。
一般的なインターフェイスまたはマークアップ属性に基づいてアセンブリを動的に読み込むことができます。動的にモジュールを追加するManaged Extensibility Frameworkに見てみるために
あなたはコンポジットアプリケーションブロック(CAB)を調査することもできます(ただし、それは学習曲線を持っている)
あなたは可能性があります。
MSには、シェアウェアスターターキットfor C#のサンプルとツールがあります。ここからダウンロード: http://msdn.microsoft.com/en-us/library/cc533530.aspx
多少古いです。しかし、無料のリソース(いくつかの商用ソリューションがあります)を探しているなら、インフラストラクチャ全体をゼロから開発することなく、これがすべて存在します。
MEFを使用しない場合は、これを試してください。すべての まず(ライブラリ内の)あなたのインターフェイスを定義します。
namespace Interfaces
{
public interface IPlugin01
{
string Name { get; }
string Description { get; }
void Calc1();
}
public interface IPlugin02
{
void Calc2();
}
}
は、次に(DLLファイルで、おそらくアセンブリ)あなたのプラグインを書くあなたのインターフェイスを実装するクラス(一つ以上)を使用して、最後に
namespace Plugin01
{
public class Class1 : Interfaces.IPlugin01,Interfaces.IPlugin02
{
public string Name { get { return "Plugin01.Class1"; } }
public string Description { get { return "Plugin01.Class1 description"; } }
public void Calc1() { Console.WriteLine("sono Plugin01.Class1 Calc1()"); }
public void Calc2() { Console.WriteLine("sono Plugin01.Class1 Calc2()"); }
}
public class Class2 : Interfaces.IPlugin01
{
public string Name { get { return "Plugin01.Class2"; } }
public string Description { get { return "Plugin01.Class2 description"; } }
public void Calc1() { Console.WriteLine("sono Plugin01.Class2 Calc1()"); }
}
}
を
namespace Test
{
class Program
{
/// ------------------------------------------------------------------------------
/// IMPORTANT:
/// you MUST exclude Interfaces.dll from being copied in Plugins directory,
/// otherwise plugins will use that and they're not recognized as using
/// the same IPlugin interface used in main code.
/// ------------------------------------------------------------------------------
static void Main(string[] args)
{
List<Interfaces.IPlugin01> list1 = new List<Interfaces.IPlugin01>();
List<Interfaces.IPlugin01> list2 = new List<Interfaces.IPlugin01>();
List<Interfaces.IPlugin01> listtot = GetDirectoryPlugins<Interfaces.IPlugin01>(@".\Plugins\");
Console.WriteLine("--- 001 ---");
foreach(Interfaces.IPlugin01 plugin in list1)
plugin.Calc1();
Console.WriteLine("--- 002 ---");
foreach (Interfaces.IPlugin01 plugin in list2)
plugin.Calc1();
Console.WriteLine("--- TOT ---");
foreach (Interfaces.IPlugin01 plugin in listtot)
plugin.Calc1();
Console.ReadLine();
}
public static List<T> GetFilePlugins<T>(string filename)
{
List<T> ret = new List<T>();
if (File.Exists(filename))
{
Assembly ass = Assembly.LoadFrom(filename);
foreach (Type type in ass.GetTypes())
{
if (!type.IsClass || type.IsNotPublic) continue;
if (typeof(T).IsAssignableFrom(type))
{
T plugin = (T)Activator.CreateInstance(type);
ret.Add(plugin);
}
}
}
return ret;
}
public static List<T> GetDirectoryPlugins<T>(string dirname)
{
/// To avoid that plugins use Interfaces.dll in their directory,
/// I delete the file before searching for plugins.
/// Not elegant perhaps, but functional.
string idll = Path.Combine(dirname, "Interfaces.dll");
if (File.Exists(idll)) File.Delete(idll);
List<T> ret = new List<T>();
string[] dlls = Directory.GetFiles(dirname, "*.dll");
foreach (string dll in dlls)
{
List<T> dll_plugins = GetFilePlugins<T>(Path.GetFullPath(dll));
ret.AddRange(dll_plugins);
}
return ret;
}
}
私の解決策(インターフェイス、プラグイン、テストコンソールアプリケーションを含む)は私のアプリケーションをコンパイルしました。私はあなたのプラグインを読み込んで使用します。 n 。\ binとプラグインは。\ bin \ Pluginsにあります。両方のフォルダに展開されましたInterfaces.dll私のプロジェクトが依存しています。 これは深刻な問題です、覚えています(コードのコメントを読む)! プラグインをコンパイルすると、Interfaces.dllがにコピーされます。\ bin \ Plugins dir;これを忘れると、あなたのアプリはまったく動作しません。そこで、プラグインを検索して読み込む前に、dllの削除を強制することにしました。
イタリア語ですが、Gian Maria Ricci(Microsoft MVP)から優れた記事が寄せられています。 リンク先はこちら[link] http://dotnetmarche.org/blogs/article/archive/2006/10/30/Creare-un-programma-estendibile-mediante-plugin-_2D00_-Parte-1.aspx [/ link] ] と [リンク] http://dotnetmarche.org/blogs/article/archive/2007/01/29/Creare-un-programma-estensibile-tramite-plugins-_2D00_-Parte-2.aspx [/ link] – Marco
プラグアンドプレイとは全く異なる意味です。クラスライブラリを書く。 –