使用 IoC 框架,我需要从注入的类到扩展方法中获取值
本文关键字:扩展 方法 获取 注入 框架 IoC 使用 | 更新日期: 2023-09-27 18:33:20
我有一个相当小的网站,我已经到了需要将我的绝对路径转换为html中的相对路径的地步。 我正在将AutoFac用于我的IoC,并且我构建了一个包装器来在整个项目中注入我的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 转换来获取任何更改,然后再部署代码并相应地修改配置。
有人以前遇到过这样的事情并且有一个好的解决方案吗? 提前感谢!
考虑允许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();
}
}
}
因此,经过几个小时的研究,我最终在扩展中使用了依赖项解析器来获取我正在寻找的配置值:
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););
}
}
希望这至少可以帮助其他人!
-特罗吉