需要替代我的IDisposable Hack

时间:2013-05-06 11:27:04

标签: c# asp.net-mvc razor

我目前有一个场景,我重新使用html代码块。我基本上有一个div容器,我在整个网站上重复使用该容器及其变体。

容器由以下html组成:

<div class="c_wrapper">
    <div class="c_content">
        CONTENT GOES HERE
    </div>
</div>

* 请注意,容器比我指定的要多,这是一个基本框架。

而不是在每个页面上多次重新键入容器代码,我使用IDisposable使它更容易一点:

public static class Container
{
    public static ContainerHelper BeginContainer(this HtmlHelper content, int containerSize)
    {
        return new ContainerHelper(content, containerSize);
    }
}

public class ContainerHelper : IDisposable
{
    private readonly HtmlHelper _content;
    public ContainerHelper(HtmlHelper content, int containerSize)
    {
        _content = content;
        var sb = new StringBuilder();
        sb.Append("<div class=\"container_" + containerSize + "\">");
        _content.ViewContext.Writer.WriteLine(sb.ToString());
    }

    public void Dispose()
    {
        var sb = new StringBuilder();
        sb.Append("</div>");
        _content.ViewContext.Writer.WriteLine(sb.ToString());
    }
}

这意味着每当我想使用容器时,我现在可以简单地使用以下内容:

@using (Html.BeginContainer(24))
{
   <span>hello world... and other content here</span>
}

我想更进一步,我意识到IDisposable不是理想的解决方案。

我希望能够做到以下几点:

@Html.Container(24)
{
   <span>hello world... and other content here</span>
}

有关如何实现这一目标的任何建议?如果无法实现,建议如何在不使用IDisposable的情况下完成我的第一个例子。

我正在使用MVC 3/4和C#。

感谢名单

2 个答案:

答案 0 :(得分:2)

让你的帮助方法接受委托。 Phil Haack在detail

中对此表示反对
public static HelperResult Container(int containerSize, Func<dynamic, HelperResult> template)
{
    return new HelperResult(writer => template(null).WriteTo(writer));
}


@Html.Container(24, @<span>hello world... and other content here</span>)

这只会输出您传入的内容。要使用div标记打包,请调用writer

中的HelperResult参数

Func<dynamic, HelperResult>的原因是传递给方法的标记始终作为委托传递,该委托采用单个参数并返回HelperResult。在这种情况下,由于您没有传入任何数据,我使用dynamic来保持简单,但如果您从上面读取链接,您将看到您可以传入任何类型的对象,它可以可以通过名为item的特殊变量访问。

答案 1 :(得分:0)

那很聪明。但是,这种编码最终可能会给您带来一些麻烦。假设一位同事试图使用你的课程而不知道它是如何工作的(如何关闭div)。还假设总有一天你会忘记你在那里做了什么,并尝试在using区块之外使用它。

我的建议:不要在Dispose方法中做任何与真实处理无关的逻辑。这是一个方法,只做它应该做的事情。相反,有一个静态方法,可以在div中获取你想要的任何东西。这个方法必须包装你的html。就像这样:

public static string myMethod(string input)
{
    string result = "<div>" +
      // ...snip
      + input +
      // ...snip
      + "</div>";
    return result;
}