1

我正在开发一个相当小的网站,并且已经到了需要将绝对路径转换为 ​​html 中的相对路径的地步。我正在为我的 IoC 使用 AutoFac,并且我构建了一个包装器以在整个项目中注入我的 web.config 应用程序设置,并且遇到了这个问题:

我有一个名为“ContentServerPath”的配置值,我的包装器负责传递:

public interface IConfigurationWrapper
{
    string ContentServerPath { get; }
}

和我的实现(相当简单):

public ConfigurationWrapper()
        : this(ConfigurationManager.AppSettings, ConfigurationManager.ConnectionStrings)
    {
    }


    internal ConfigurationWrapper(NameValueCollection appSettings, ConnectionStringSettingsCollection connectionStrings)
    {
        ContentServerPath = appSettings["ContentServerPath"];
    }

我的 _layout.cshtml 页面最初被编码为在开发网站时使用本地样式表和 jquery:

<link rel="stylesheet" type="text/css" href="~/assets/styles/site.css" />

我希望做的最终输出是将 html 行替换为以下内容:

<link rel="stylesheet" type="text/css" href="@Html.GetContentPath("assets/styles/site.css")" />

但是,事实证明这是一项可怕的任务,因为当我调用扩展方法时,我无法将 IConfigurationWrapper 注入静态类。

我最初的想法是

public static MvcHtmlString GetContentPath(this HtmlHelper htmlHelper, string relativeContentPath)
    {
        return string.Format("{0}/{1}", _configuration.ContentServerPath, relativeContentPath);
    }

但是,同样,我无法将配置包装器注入到静态方法中。

作为旁注,我将内容路径放入 web.config 的原因是因为我们有几个不同的测试环境,每个环境都需要它自己的内容配置值。我们依赖 xdt 转换为我们的构建服务器在部署代码之前获取任何更改并相应地修改配置。

有人遇到过这样的事情并有一个好的解决方案吗?提前致谢!

4

2 回答 2

4

考虑允许HtmlHelperExtensions指定依赖关系的上下文:

public static class HtmlHelperExtensions
{
    public static MvcHtmlString GetContentPath(this HtmlHelper htmlHelper, string relativeContentPath)
    {
        EnsureWrapper();

        return new MvcHtmlString(string.Format("{0}/{1}", ConfigurationWrapper.ContentServerPath, relativeContentPath));
    }

    public static IConfigurationWrapper ConfigurationWrapper;

    private static void EnsureWrapper()
    {
        if(ConfigurationWrapper == null)
        {
            throw new InvalidOperationException();
        }
    }
}

然后,将其设置在组合根中:

HtmlHelperExtensions.ConfigurationWrapper = container.Resolve<IConfigurationWrapper>();

当另一个库要求使用静态类时,这是一种可靠的模式,相当于静态依赖倒置。它强加了最少量的基础设施知识,类似于实例的构造函数注入。

你可以更进一步,去掉中间人,HtmlHelperExtensions尽可能地简化和外化细节:

public static class HtmlHelperExtensions
{
    public static MvcHtmlString GetContentPath(this HtmlHelper htmlHelper, string relativeContentPath)
    {
        EnsureContentServerPath();

        return new MvcHtmlString(string.Format("{0}/{1}", ContentServerPath, relativeContentPath));
    }

    public static string ContentServerPath;

    private static void EnsureContentServerPath()
    {
        if(EnsureContentServerPath == null)
        {
            throw new InvalidOperationException();
        }
    }
}
于 2013-10-02T00:25:17.480 回答
0

所以经过几个小时的研究,我最终在我的扩展中使用依赖解析器来获取我正在寻找的配置值:

public static class HtmlHelperExtensions
{
    public static MvcHtmlString GetContentPath(this HtmlHelper htmlHelper, string relativeContentPath)
    {
        return GetContentPath(relativeContentPath, AutofacDependencyResolver.Current.ApplicationContainer.Resolve<IConfigurationWrapper>());
    }

    internal static MvcHtmlString GetContentPath(string relativeContentPath, IConfigurationWrapper configuration)
    {
        return new MvcHtmlString(string.Format("{0}/{1}", configuration.ContentServerPath, relativeContentPath););
    }
}

希望这至少可以帮助其他人!

-特洛吉

于 2013-10-01T05:22:45.053 回答