Пакет URI проверки - PullRequest
       1

Пакет URI проверки

5 голосов
/ 11 июня 2010

Какой самый простой способ проверить, можно ли найти пакет uri?

Например, если

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

, как я могу проверить, существует ли изображение на самом деле?

Приветствия,
Беррил

Ответы [ 3 ]

5 голосов
/ 15 июня 2010

Я не мог найти простой ответ на этот вопрос, поэтому я свернул свой собственный код, чтобы выполнить три вещи в отношении ресурсов изображений:
(1) иметь строковое представление пакета uri (привязка данных)
(2) убедитесь, что изображение находится там, где, как мне кажется, оно расположено (модульный тест)
(3) убедитесь, что пакет uri можно использовать для установки изображения (модульный тест)

Одна из причин, по которой это не так просто, заключается в том, что пакеты URI поначалу немного сбивают с толку и имеют несколько разновидностей. Этот код предназначен для пакета URI, представляющего изображение, которое включено в сборку VS (локально или сборку со ссылкой с действием сборки 'resource'). В этом статьях msdn поясняется, что это означает в этом контексте Вам также нужно больше разбираться в сборках и сборках, чем это может показаться на первый взгляд хорошим временем.

Надеюсь, это облегчит кому-то еще. Cheers,
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 голос
/ 29 августа 2017

Я знаю, вопрос очень старый, но, возможно, у кого-то есть такая же проблема.У меня также была проблема с тем, что я хотел проверить свои строки ресурсов в модульном тесте.

Самое простое решение - инициализировать ResourceDictionary.Вы также можете получить доступ к определенному ключу с помощью dictionary.Keys ["myKey"] и проверить содержимое.

[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);
    }
}


Кстати, именно так я регистрирую свои ресурсы вApp.xaml.cs (чтобы я мог проверить их на единицу теста):

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();
    }
}

И в OnStartup:

// add xaml resources (styles, colors, ...)
ResourceManager.AddResources();
1 голос
/ 04 августа 2015
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...