2

私には状況があり、最善の方法でそれに対処する方法を知る必要があります。

私はアプリケーション(MVC3)を持っており、そのための統合がいくつかあります。私はインターフェース「IntegrationInterface」を持っており、すべての統合がそれを実装しています。統合のdllをロードし、それらのリストを作成し、リスト内のすべての統合のメソッドを実行するループを実行したいと思います。

たとえば、Facebook、myspace、Twitter(私のアプリケーション用)が統合されていて、ユーザーがアプリケーションにメッセージを投稿するたびに、Facebook、myspace、Twitterにメッセージを投稿したいとします。

コードがどの統合を持っているかを知られたくないので、明日google +の新しい統合を作成する場合は、アプリケーションのコードを変更せずに新しいDLLを追加する必要があります。

どうやってやるの?

4

3 に答える 3

5

まず、関連するすべての dll とクラスを見つける必要があります。

loadedIntegrations.Clear();
if (!Directory.Exists(path))
    return;
DirectoryInfo di = new DirectoryInfo(path);
FileInfo[] files = di.GetFiles("*.dll");
foreach (var file in files)
{
    Assembly newAssembly = Assembly.LoadFile(file.FullName);
    Type[] types = newAssembly.GetExportedTypes();
    foreach (var type in types)
    {
        //If Type is a class and implements the IntegrationInterface interface
        if (type.IsClass && (type.GetInterface(typeof(IntegrationInterface).FullName) != null))
            loadedIntegrations.Add(type);
    }
}

loadedIntegrationsタイプList<Type>です。次に、各統合をインスタンス化し、そのメソッドを呼び出すことができます。

foreach(var integrationType in loadedIntegrations)
{
    var ctor = integrationType.GetConstructor(new Type[] { });
    var integration = ctor.Invoke(new object[] { }) as IntegrationInterface;
    //call methods on integration
}
于 2012-07-15T11:30:07.730 に答える
0

私はあなたが書いたインポートユーティリティであなたが説明したことと同様のことをしています。私の問題は、すべてのアセンブリをロードしたくないということでした。要求された型を含むアセンブリのみをロードしたかったのです。

これを実現するために、AppDomain.CurrentDomain.AssemblyResolveイベント ハンドラーを使用しました。

このイベント ハンドラーは、AppDomain がアセンブリが見つからないことを通知する例外をスローする直前に発生します。Nico がそのハンドラーで提案したものと同様のコードを実行し、要求されたアセンブリを返します。

注: 'Tasks' (Import Tasks と考えてください) というサブディレクトリがあり、実行時にロードするすべてのアセンブリを格納します。

コードは次のとおりです。

        var tasks = GetTasks();
        var basedir = AppDomain.CurrentDomain.BaseDirectory; // Get AppDomain Path
        var tasksPath = Path.Combine(basedir, "Tasks"); // append 'Tasks' subdir

        // NOTE: Cannot be factored, relies on 'tasksPath' variable (above).
        AppDomain.CurrentDomain.AssemblyResolve += (s, e) => // defined 'AssemblyResolve' handler
        {
            var assemblyname = e.Name + ".dll"; // append DLL to assembly prefix
            // *expected* assembly path
            var assemblyPath = Path.Combine(tasksPath, assemblyname); // create full path to assembly
            if (File.Exists(assemblyPath)) return Assembly.LoadFile(assemblyPath); // Load Assembly as file.
            return null; // return Null if assembly was not found. (throws Exception)
        };

        foreach (var task in tasks.OrderBy(q => q.ExecutionOrder)) // enumerate Tasks by ExecutionOrder
        {
            Type importTaskType = Type.GetType(task.TaskType); // load task Type (may cause AssemblyResolve event to fire)
            if (importTaskType == null)
            {
                log.Warning("Task Assembly not found");
                continue;
            }
            ConstructorInfo ctorInfo = importTaskType.GetConstructor(Type.EmptyTypes); // get constructor info
            IImportTask taskInstance = (IImportTask)ctorInfo.Invoke(new object[0]); // invoke constructor and cast as IImportTask
            taskInstances.Add(taskInstance);
        }
        // rest of import logic omitted...
于 2012-07-15T11:50:04.327 に答える
-1

MEF (管理された拡張性フレームワーク) を知っている場合、これは私が個人的に使用するのに役立つかもしれませんが、MVC で MEF を使用することは簡単ではないと言わざるを得ません。詳細については、次を参照してください。

http://msdn.microsoft.com/en-us/library/dd460648.aspx

于 2012-07-15T12:01:39.180 に答える