9

設定に基づいてCSSファイルとJSファイルを追加する動的なバンドルを扱っています。Web.Optimizations - スタイル/スクリプトバンドルからすべてを取得する方法はありますか?

私がそのようなことを新しいStyleBundleスピンアップします。config通じその後

var cssBundle = new StyleBundle("~/bundle/css"); 

ループし、任意見つかりました追加が含まれています:私はすべてのファイルが実際にあったかどうかを確認したいループ後

cssBundle.Include(config.Source); 

を/ディレクトリが含まれています。私はEnumerateFiles()があることを知っているが、私はこの100%が目的を果たすとは思わない。

他の人はこれまでに同様のことをしましたか?

答えて

13

Bundleクラスは、アプリケーション に露出されていない内部アイテムのリストを使用し、必ずしも反射(私は試み、任意のコンテンツを取得できませんでした) を介してアクセス可能ではありません。あなたはそのようBundleResolverクラスを使用してこのに関するいくつかの情報を取得することができます

var cssBundle = new StyleBundle("~/bundle/css"); 
cssBundle.Include(config.Source); 

// if your bundle is already in BundleTable.Bundles list, use that. Otherwise... 
var collection = new BundleCollection(); 
collection.Add(cssBundle) 

// get bundle contents 
var resolver = new BundleResolver(collection); 
List<string> cont = resolver.GetBundleContents("~/bundle/css").ToList(); 

あなたはちょうどその数が必要な場合:

int count = resolver.GetBundleContents("~/bundle/css").Count(); 

編集:反射

を使用してどうやら私が何かをしました前に私の反射テストに間違っていた。

using System.Reflection; 
using System.Web.Optimization; 

... 

int count = ((ItemRegistry)typeof(Bundle).GetProperty("Items", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(cssBundle, null)).Count; 

あなたはおそらく、もちろんそこにいくつかの安全性チェックを追加する必要があり、かつ反射多くの例のように、これはItemsプロパティの意図した安全性に違反し、それ作業を行います。

これは実際に動作します。

+0

Coreyがうまくいくように感謝していますが、問題はコレクションがコンテンツにカウントされるようにコレクションに追加されていることだけです。理想的には、コレクションに追加する前に> 0を確実にするために内容をチェックしたいと思います。それは理にかなっていますか? – timothyclifford

+0

リフレクションの例を使用してカウントを取得するか、上記の初期コードサンプルで行ったように新しい(一時的な)コレクションを作成し、 'BundleResolver'を使用してインクルードされたファイルのリストを取得できます。 'BundleTable.Bundles'コレクションに追加するまで、バンドルはシステムの残りの部分で使用できるようになりません。そのため、どちらの方法を使ってバンドルをチェックしてから一般に利用できるようにします。 – Corey

+0

ItemRegistryは内部ではありませんか? – timothyclifford

1

あなたはBundleのために、以下の拡張メソッドを使用することができます。

public static class BundleHelper 
{ 
    private static Dictionary<Bundle, List<string>> bundleIncludes = new Dictionary<Bundle, List<string>>(); 
    private static Dictionary<Bundle, List<string>> bundleFiles = new Dictionary<Bundle, List<string>>(); 

    private static void EnumerateFiles(Bundle bundle, string virtualPath) 
    { 
     if (bundleIncludes.ContainsKey(bundle)) 
      bundleIncludes[bundle].Add(virtualPath); 
     else 
      bundleIncludes.Add(bundle, new List<string> { virtualPath }); 

     int i = virtualPath.LastIndexOf('/'); 
     string path = HostingEnvironment.MapPath(virtualPath.Substring(0, i)); 

     if (Directory.Exists(path)) 
     { 
      string fileName = virtualPath.Substring(i + 1); 
      IEnumerable<string> fileList; 

      if (fileName.Contains("{version}")) 
      { 
       var re = new Regex(fileName.Replace(".", @"\.").Replace("{version}", @"(\d+(?:\.\d+){1,3})")); 
       fileName = fileName.Replace("{version}", "*"); 
       fileList = Directory.EnumerateFiles(path, fileName).Where(file => re.IsMatch(file)); 
      } 
      else // fileName may contain '*' 
       fileList = Directory.EnumerateFiles(path, fileName); 

      if (bundleFiles.ContainsKey(bundle)) 
       bundleFiles[bundle].AddRange(fileList); 
      else 
       bundleFiles.Add(bundle, fileList.ToList()); 
     } 
    } 

    public static Bundle Add(this Bundle bundle, params string[] virtualPaths) 
    { 
     foreach (string virtualPath in virtualPaths) 
      EnumerateFiles(bundle, virtualPath); 

     return bundle.Include(virtualPaths); 
    } 

    public static Bundle Add(this Bundle bundle, string virtualPath, params IItemTransform[] transforms) 
    { 
     EnumerateFiles(bundle, virtualPath); 
     return bundle.Include(virtualPath, transforms); 
    } 

    public static IEnumerable<string> EnumerateIncludes(this Bundle bundle) 
    { 
     return bundleIncludes[bundle]; 
    } 

    public static IEnumerable<string> EnumerateFiles(this Bundle bundle) 
    { 
     return bundleFiles[bundle]; 
    } 
} 

そして、単にAdd()であなたのInclude()呼び出しを置き換える:あなたもIncludeDirectory()を使用している場合は、

var bundle = new ScriptBundle("~/test") 
    .Add("~/Scripts/jquery/jquery-{version}.js") 
    .Add("~/Scripts/lib*") 
    .Add("~/Scripts/model.js") 
    ); 

var includes = bundle.EnumerateIncludes(); 
var files = bundle.EnumerateFiles(); 

をちょうど完全なこの例では、それぞれAddDirectory()拡張メソッドを追加しています。

+1

'EnumerateFiles'メソッドは実際にBundleクラスに組み込まれています。 BundleFileオブジェクトのリストが返され、各ファイルのパスだけでなく、適用されている各ファイルのIItemTransform(存在する場合)にアクセスすることができます。 – Triynko