빼꼼...

안녕하세요 웹지니입니다! 흐헤헤 -ㅅ-;;;
어제 있었던 북한의 도발 때문에 많이들 불안하셨을 것으로 생각합니다.
저로서는 조금 더 부지런히, 열심히 살아야겠다고 다시 한 번 추스르게 된 계기가 되었어요.
뭐... 이번 포스트를 꼭 그래서 올리는 건 아니구요...-ㅅ-;;

예전에 블로그를 통해 Custom HtmlHelper 메서드를 구현하는 것과 관련된 글을 올린 적이 있었어요. 벌써 1년도 넘게 지난 시점이군요. 당시 HtmlHelper 클래스의 확장 메서드를 구현하면서 최종적으로 태그를 생성하는 과정에서 ASP.NET MVC가 제공하는 TagBuilder 클래스를 사용했었는데요.

오늘 포스트는 요즘 유행(?)하는 Fluent Interface 패턴 형태로 TagBuilder 클래스를 손쉽게 활용할 수 있도록 확장하는 내용을 담아봅니다. Fluent Interface 패턴을 활용하면 매우 읽기 쉬운 코드를 작성할 수 있다는 장점이 있지요. 해서 한 번 만들어 봤습니다. 이름하야 FluentTagBuilder!!



Implementing FluentTagBuilder

아시는 분은 아시겠지만 Fluent Interface의 핵심은 메서드가 자기 자신 혹은 관련된 다른 객체의 인스턴스를 리턴하는 것입니다. 즉, 메서드 호출 시 스스로를 계속 리턴하여 연속적으로 메서드를 호출할 수 있도록 구현하는 것이지요. 실질적으로 HTML 태그를 생성하는 기능은 TagBuilder가 이미 훌륭하게 구현하고 있으니 그냥 맡겨버리고 우리는 이 TagBuilder 클래스의 인스턴스를 계속해서 리턴하는 Wrapper 메서드만을 구현해주면 됩니다. 일단 코드를 좀 살펴볼까요?

public class FluentTagBuilder : TagBuilder
{
	public FluentTagBuilder(string tagName)
		: base(tagName)
	{ }

	public FluentTagBuilder Append(FluentTagBuilder innerTag)
	{
		base.InnerHtml += innerTag.ToString();
		return this;
	}

	public FluentTagBuilder AppendHtml(string html)
	{
		base.InnerHtml += html;
		return this;
	}

	public FluentTagBuilder AppendText(string html) {
		  base.InnerHtml += HttpUtility.HtmlEncode(html);
		  return this;
	}

	public FluentTagBuilder With(FluentTagBuilder tagBuilder)
	{
		base.InnerHtml = tagBuilder.ToString();
		return this;
	}

	public FluentTagBuilder With(string attribute, string attributeValue)
	{
		base.Attributes.Add(attribute, attributeValue);
		return this;
	}

	public FluentTagBuilder With(IDictionary attributes)
	{
		base.MergeAttributes(attributes);
		return this;
	}

	public FluentTagBuilder And(string attribute, string attributeValue)
	{
		base.Attributes.Add(attribute, attributeValue);
		return this;
	}

	public FluentTagBuilder AndIf(bool condition, string attribute, string attributeValue)
	{
		if (condition)
		{
			base.Attributes.Add(attribute, attributeValue);
		}
		return this;
	}
}
예제 코드에서 크게 어렵거나 이해가 안 가는 부분은 없으실거라 생각해요. 그러면 실제로 어떻게 사용하는지를 알아볼까요? 예전 포스트에서 구현했던 이미지를 포함하는 링크를 생성하는 ImageLink 메서드를 FluentTagBuilder 클래스를 이용하면 아래와 같이 구현할 수 있습니다.

public static MvcHtmlString ImageLink(
	this HtmlHelper helper, 
	string imageUrl, 
	string actionName, 
	string controllerName, 
	RouteValueDictionary routeValues, 
	IDictionary imgAttributes, 
	IDictionary htmlAttributes)
{
	UrlHelper urlHelper = new UrlHelper(helper.ViewContext.RequestContext);
	string resolvedImageUrl = urlHelper.Content(imageUrl);

	string url = UrlHelper.GenerateUrl(
		null, actionName, controllerName, routeValues, helper.RouteCollection,
		helper.ViewContext.RequestContext, true
	);
	
	FluentTagBuilder imageTagBuilder = new FluentTagBuilder("img")
		.With(imgAttributes)
		.With("src", resolvedImageUrl);

	return MvcHtmlString.Create(new FluentTagBuilder("a")
		.Append(imageTagBuilder)
		.With("href", url)
		.With(htmlAttributes)
		.ToString()
	);
}
18번 라인부터 27번 라인까지의 코드가 바로 FluentTagBuilder 클래스를 이용하여 태그를 생성하는 부분입니다. 예전 포스트와 비교할 때 코드가 확연히 줄어들었을 뿐 아니라 코드를 이해하기도 더 쉬워진 것 같죠?

아직 어딘가에 살아있음을 보여주기 위한 짧은 포스트는 여기서 마치고 이만 물러갑니다.
멋진 하루 보내시기 바랍니다!
Posted by 웹지니 트랙백 0 : 댓글 6