2010-06-10 2 views
5

Quelle est la manière la plus simple de vérifier qu'un paquet peut être trouvé?pack uri validation

Par exemple, étant donné

pack://application:,,,Rhino.Mocks;3.5.0.1337;0b3305902db7183f;component/SomeImage.png 

comment pourrais-je vérifier si l'image existe réellement?

Cheers,
Berryl

Répondre

5

Je ne pouvais pas trouver une réponse simple à cela, donc j'enroulé rouler mon propre code pour accomplir trois choses en ce qui concerne les ressources d'image:
(1) ont une chaîne représentation d'un paquet uri (databind)
(2) vérifier que l'image est située à l'endroit où je la trouve (test unitaire)
(3) vérifier que le paquet uri peut être utilisé pour définir une image (test unitaire)

Une partie de la raison pour laquelle ce n'est pas simple C'est parce que les emballages de Uri sont un peu déroutants au début, et viennent dans plusieurs saveurs. Ce code est pour un paquet uri qui représente une image qui est incluse dans un assembly VS (soit localement, soit un assembly référencé avec une action de construction de 'resource'.) msdn articles clarifie ce que cela signifie dans ce contexte. a propos des ensembles et construit que peut d'abord sembler un bon moment.

Hope this rend plus facile pour quelqu'un d'autre. des cris de joie,
Berryl

/// <summary> (1) Creates a 'Resource' pack URI .</summary> 
    public static Uri CreatePackUri(Assembly assembly, string path, PackType packType) 
    { 
     Check.RequireNotNull(assembly); 
     Check.RequireStringValue(path, "path"); 

     const string startString = "pack://application:,,,/{0};component/{1}"; 
     string packString; 
     switch (packType) 
     { 
      case PackType.ReferencedAssemblySimpleName: 
       packString = string.Format(startString, assembly.GetName().Name, path); 
       break; 
      case PackType.ReferencedAssemblyAllAvailableParts: 
       // exercise for the reader 
       break; 
      default: 
       throw new ArgumentOutOfRangeException("packType"); 
     } 
     return new Uri(packString); 
    } 

    /// <summary>(2) Verify the resource is located where I think it is.</summary> 
    public static bool ResourceExists(Assembly assembly, string resourcePath) 
    { 
     return GetResourcePaths(assembly).Contains(resourcePath.ToLowerInvariant()); 
    } 

    public static IEnumerable<object> GetResourcePaths(Assembly assembly, CultureInfo culture) 
    { 
     var resourceName = assembly.GetName().Name + ".g"; 
     var resourceManager = new ResourceManager(resourceName, assembly); 

     try 
     { 
      var resourceSet = resourceManager.GetResourceSet(culture, true, true); 

      foreach (DictionaryEntry resource in resourceSet) 
      { 
       yield return resource.Key; 
      } 
     } 
     finally 
     { 
      resourceManager.ReleaseAllResources(); 
     } 
    } 

    /// <summary>(3) Verify the uri can construct an image.</summary> 
    public static bool CanCreateImageFrom(Uri uri) 
    { 
     try 
     { 
      var bm = new BitmapImage(uri); 
      return bm.UriSource == uri; 
     } 
     catch (Exception e) 
     { 
      Debug.WriteLine(e); 
      return false; 
     } 
    } 
1
Public Class Res 

    Private Shared __keys As New List(Of String) 

    Shared Function Exist(partName As String) As Boolean 
     Dim r As Boolean = False 

     If __keys.Count < 1 Then 
      Dim a = Assembly.GetExecutingAssembly() 
      Dim resourceName = a.GetName().Name + ".g" 
      Dim resourceManager = New ResourceManager(resourceName, a) 
      Dim resourceSet = resourceManager.GetResourceSet(Globalization.CultureInfo.CurrentCulture, True, True) 
      For Each res As System.Collections.DictionaryEntry In resourceSet 
       __keys.Add(res.Key) 
      Next 
     End If 

     __keys.ForEach(Sub(e) 
          If e.Contains(partName.ToLower) Then 
           r = True 
           Exit Sub 
          End If 
         End Sub) 

     Return r 
    End Function 
End Class 
1

Je sais, la question est très ancienne, mais peut-être que quelqu'un a le même problème. 210 J'ai également eu le problème que je voulais tester mes chaînes de ressources dans un test unitaire.

La solution la plus simple consiste à initialiser un ResourceDictionary. Vous pouvez également accéder à une clé spécifique avec dictionary.Keys ["myKey"] et vérifier le contenu.

[SetUp] 
public void OnTestInitialize() 
{ 
    if (!UriParser.IsKnownScheme("pack")) 
    { 
     new Application(); 
    } 
} 

[TestCase] 
public void TestIfResourcesExist() 
{ 
    var resources = new [] { 
     "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/CommonColors.xaml", 
     "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/CommonStyles.xaml", 
     "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/GridSplitterStyle.xaml" 
    }; 

    foreach (var mergedResource in resources) 
    { 
     // init 
     ResourceDictionary dictionary = 
      new ResourceDictionary {Source = new Uri(mergedResource, UriKind.RelativeOrAbsolute)}; 

     // verify 
     dictionary.Keys.Count.Should().BeGreaterThan(0); 
    } 
} 


D'ailleurs, cela est la façon dont j'inscrire mes ressources dans le App.xaml.cs (donc je peux les tester par test unitaire):

public static class ResourceManager 
{ 
    public static readonly string[] MergedResources = { 
     "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/CommonColors.xaml", 
     "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/CommonStyles.xaml", 
     "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/GridSplitterStyle.xaml" 
    }; 

    public static void AddResources() 
    { 
     Application.Current.Resources.BeginInit(); 
     foreach (var resource in MergedResources) 
     { 
      Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary 
      { 
       Source = new Uri(resource, UriKind.Absolute) 
      }); 
     } 
     Application.Current.Resources.EndInit(); 
    } 
} 

Et dans OnStartup:

// add xaml resources (styles, colors, ...) 
ResourceManager.AddResources();