2017-02-04 4 views
0

現在、すべての単一の型を渡す代わりに、リフレクションによってAsp.Netコアのサービスをロードするための基本的なソリューションを実装しています。 は、いくつかのウィグル-部屋を持っているために、私は私に新しいコア反射タイプを使用して、アセンブリの型を返す静的ヘルパーを作成しました:Asp.Netアセンブリ:Asp.Netアセンブリのスロー例外を反映する

internal static class ReflectionTypeHelper 
{ 
    private static readonly Assembly _currentAssembly = typeof(ServiceContainerInitializer).GetTypeInfo().Assembly; 

    internal static IReadOnlyCollection<Type> ScanAssembliesForTypes(Func<Type, bool> predicate) 
    { 
     var result = new List<Type>(); 
     var appAssemblies = GetApplicationAssemblies(); 

     foreach (var ass in appAssemblies) 
     { 
      var typesFromAssembly = ass.GetTypes().Where(predicate); 
      result.AddRange(typesFromAssembly); 
     } 

     return result; 
    } 

    private static IEnumerable<Assembly> GetApplicationAssemblies() 
    { 
     var consideredFileExtensions = new[] 
     { 
      ".dll", 
      ".exe" 
     }; 

     var result = new List<Assembly>(); 
     var namespaceStartingPart = GetNamespaceStartingPart(); 

     var assemblyPath = GetPath(); 
     IEnumerable<string> assemblyFiles = Directory.GetFiles(assemblyPath); 

     var fileInfos = assemblyFiles.Select(f => new FileInfo(f)); 
     fileInfos = fileInfos.Where(f => f.Name.StartsWith(namespaceStartingPart) && consideredFileExtensions.Contains(f.Extension.ToLower())); 

     // Net.Core can't load the Services for some reason, so we exclude it at the moment 
     //fileInfos = fileInfos.Where(f => f.Name.IndexOf("Services", StringComparison.OrdinalIgnoreCase) == -1); 

     foreach (var fi in fileInfos) 
     { 
      var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(fi.FullName); 
      result.Add(assembly); 
     } 

     return result; 
    } 

    private static string GetNamespaceStartingPart() 
    { 
     var fullNamespace = _currentAssembly.FullName; 
     var splittedNamespace = fullNamespace.Split('.'); 

     var result = string.Concat(splittedNamespace[0], ".", splittedNamespace[1]); 
     return result; 
    } 

    private static string GetPath() 
    { 
     var codeBase = _currentAssembly.CodeBase; 
     var uri = new UriBuilder(codeBase); 
     var result = Uri.UnescapeDataString(uri.Path); 
     result = Path.GetDirectoryName(result); 

     return result; 
    } 
} 

あなたはおそらく、コードのコメントに見ることができるように、私はロードすることはできません"ASP.NET Core Web Application(.Net Core)" - プロジェクトテンプレートから作成した "Services" -Assembly。

は残念ながら、例外が

は、ファイルまたはアセンブリをロードできませんでした '中立文化=、、 バージョン= 1.0.0.0をArgusnet.Pis.Servicesを、なPublicKeyToken = nullを' 非常に汎用的です。

また、ファイルは期待通りに存在します。 このトピックに関するGitHub-Issuesに関するヒントをいくつか見つけましたが、リリース候補ですべて解決されています。

興味深いことに、他のすべてのアセンブリは期待どおりに機能するので、このアセンブリタイプには何か特別なものが必要ですか?

編集:例外のスクリーンショット:コンパイル時に選択したターゲットプロセッサアーキテクチャの不一致であるかもしれない読み込みに失敗だ理由の enter image description here

+0

投稿したエラーメッセージは完全ですか?一般に「ファイルまたはアセンブリを読み込めませんでした...」例外には、より具体的な理由を示す2番目の部分もあります。 –

+0

入力していただきありがとうございます。再チェックし、スクリーンショットを追加しました。十分な興味をそそられているメッセージ自体には、それ以上のテキストはありません。 –

答えて

0

一つ。 Argusnet.Pis.Servicesはx86構成でコンパイルされ、コンパイル時にx64オプションを使用してロードしようとしているクライアントアプリケーションをビルドすることができます。両方のプロジェクトのビルド前に同じオプション(x86またはx64)が設定されていることを確認してください。それ以外の場合は、Any CPUオプションでビルドを試してください。

+0

ヒントはありがたいですが、それらはすべてすべてのCPUとして構築されています。それはチームが認識していることを望みましょう。時には修正が必要な場合もあります。 –

関連する問題