Skip to main content
replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link

Credits go to @denis@denis.

Credits go to @denis.

Credits go to @denis.

added 80 characters in body
Source Link
t3chb0t
  • 44.3k
  • 9
  • 84
  • 190

Credits go to @denis.

Credits go to @denis.

Source Link
t3chb0t
  • 44.3k
  • 9
  • 84
  • 190

In case someone wanted to use the improved version here's the final one.

abstract class PackUriBuilder
{
    private static readonly Dictionary<UriKind, Func<PackUriBuilder, Uri>> UriFactories = new Dictionary<UriKind, System.Func<PackUriBuilder, Uri>>
    {
        [UriKind.Absolute] = builder => new Uri(builder.AbsolutePath, UriKind.Absolute),
        [UriKind.Relative] = builder => new Uri(builder.RelativePath, UriKind.Relative),
    };

    private static readonly Dictionary<UriKind, Func<PackUriBuilder, string>> StringFactories = new Dictionary<UriKind, System.Func<PackUriBuilder, string>>
    {
        [UriKind.Absolute] = builder => builder.AbsolutePath,
        [UriKind.Relative] = builder => builder.RelativePath,
    };

    private UriKind _uriKind;

    protected PackUriBuilder(string path)
    {
        if (!path.StartsWith("/"))
        {
            throw new ArgumentException(paramName: nameof(path), message: @"Path must start with ""/"".");
        }
        RelativePath = path;
        _uriKind = UriKind.Absolute;
    }

    public string Scheme => "pack";

    public string RelativePath { get; }

    public abstract string AbsolutePath { get; }

    public static implicit operator string (PackUriBuilder builder) => builder.ToString();

    public static implicit operator Uri(PackUriBuilder builder) => UriFactories[builder._uriKind](builder);

    public override string ToString() => StringFactories[_uriKind](this);   

    public Uri ToUri() => this;

    public PackUriBuilder Relative()
    {
        _uriKind = UriKind.Relative;
        return this;
    }

    public PackUriBuilder Absolute()
    {
        _uriKind = UriKind.Absolute;
        return this;
    }

    public static LocalAssemblyResourceFilePackUriBuilder LocalAssemblyResourceFile(string path)
    {
        return new LocalAssemblyResourceFilePackUriBuilder(path);
    }

    public static ReferencedAssemblyResourceFilePackUriBuilder ReferencedAssemblyResourceFile(string path, string assemblyShortName)
    {
        return new ReferencedAssemblyResourceFilePackUriBuilder(path, assemblyShortName);
    }

    public static ContentFilePackUriBuilder ContentFile(string path)
    {
        return new ContentFilePackUriBuilder(path);
    }

    public static SiteOfOriginPackUriBuilder SiteOfOrigin(string path)
    {
        return new SiteOfOriginPackUriBuilder(path);
    }
}

And the builders:

class LocalAssemblyResourceFilePackUriBuilder : PackUriBuilder
{
    public LocalAssemblyResourceFilePackUriBuilder(string path) : base(path) { }

    public override string AbsolutePath => $"{Scheme}://application:,,,{RelativePath}";
}

class ReferencedAssemblyResourceFilePackUriBuilder : PackUriBuilder
{
    private readonly string _assemblyShortName;
    private string _version;
    private string _publicKey;

    public ReferencedAssemblyResourceFilePackUriBuilder(string path, string assemblyShortName) : base(path)
    {
        _assemblyShortName = assemblyShortName;
    }

    private string VersionOrEmpty => string.IsNullOrEmpty(_version) ? string.Empty : $";{_version}";

    private string PublicKeyOrEmpty => string.IsNullOrEmpty(_publicKey) ? string.Empty : $";{_publicKey}";

    public ReferencedAssemblyResourceFilePackUriBuilder Version(string version)
    {
        _version = version;
        return this;
    }

    public ReferencedAssemblyResourceFilePackUriBuilder PublicKey(string publicKey)
    {
        _publicKey = publicKey;
        return this;
    }

    public override string AbsolutePath => $"{Scheme}://application:,,,/{_assemblyShortName}{VersionOrEmpty}{PublicKeyOrEmpty};component{RelativePath}";
}

class ContentFilePackUriBuilder : PackUriBuilder
{
    public ContentFilePackUriBuilder(string path) : base(path) { }

    public override string AbsolutePath => $"{Scheme}://application:,,,{RelativePath}";
}


class SiteOfOriginPackUriBuilder : PackUriBuilder
{
    public SiteOfOriginPackUriBuilder(string path) : base(path) { }

    public override string AbsolutePath => $"{Scheme}://siteoforigin:,,,{RelativePath}";
}
Post Made Community Wiki by t3chb0t