<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>Sean Howell - Blogs at Near Infinity</title>


        <link>http://www.nearinfinity.com/blogs/</link>
        <description>Employee Blogs</description>
        <language>en</language>
        <copyright>Copyright 2011</copyright>
        <lastBuildDate>Sun, 20 Feb 2011 21:49:24 -0500</lastBuildDate>
        <generator>http://www.sixapart.com/movabletype/</generator>
        <docs>http://www.rssboard.org/rss-specification</docs>
        
        <item>
            <title>Modeling multiple logical views of a document</title>
            <description><![CDATA[<p align="LEFT" style="margin-bottom: 0in"><font size="3" style="font-size: 13pt"><font size="3"><b>Problem:</b></font><b>
</b><font size="3"><span style="font-weight: normal"> The domain model
contains the idea of a document, and one of the documents in the
model has multiple purposes. By purpose, I mean that the physical
document is filled out with different data depending on who the
document is for. Each purpose may or may not have different logic
associated with the creation. The document abstractions should be
easily testable to make document creation as robust as possible.</span></font></font></p>
<p align="LEFT" style="margin-bottom: 0in"><font size="3" style="font-size: 13pt"><font size="3"><span style="font-weight: normal">	</span></font><font size="3"><b>A
Solution: </b></font><font size="3"><span style="font-weight: normal">One
solution that I found was based on the template method from the GoF
book. The intent of this solution was to simplify the creation of the
known views of the document. The key idea of the solution is to put
as much of the logic involved in document creation into to the base
class. </span></font></font>
</p>
<p align="LEFT" style="margin-bottom: 0in"><font size="3" style="font-size: 13pt"><font size="3"><span style="font-weight: normal">	</span></font><font size="3"><b>Implementation:
</b></font></font>
</p>
<pre class="prettyprint">abstract class Document
{
	IDictionary<string, string=""> FormTextFields
	{
		get
		{
			return new Dictionary<string, string="">
			{
				{ "NameField", this.NameField },
				{ "AgeField", this.AgeField }
			};
		}
	}
	
	private string NameField
	{
		get
		{
			if(this.DocumentType == DocumentType.Big)
			{
				return "Big name";
			}
			else if(this.DocumentType == DocumentType.Small)
			{
				return "Small name";
			}
			
			return string.Empty;
		}
	}
	
	private string AgeField
	{
		get
		{
			if(this.DocumentType == DocumentType.Big)
			{
				return "42";
			}
			
			return string.Empty;
		}
	}
	
	protected abstract DocumentType DocumentType { get; }
}

class BigDocument : Document
{
	protected override DocumentType DocumentType
	{
		get
		{
			return DocumentType.Big;
		}
	}
}
</string,></string,></pre>
<p align="LEFT" style="margin-bottom: 0in"><font size="3" style="font-size: 13pt"><font size="3"><b>	Benefits:
</b></font><font size="3"><span style="font-weight: normal">As
previously stated, the main purpose of the base class is to simplify
the creation of the subclasses. This solution does just that by
reducing the amount of work needed to create a new subclass. The
subclasses have only two main actions required for creation. The
first action is to define the type of the document which is an
abstract method in the base class. The second action, not shown in the subclass, is the
validation of the specific concrete document type. Just doing these
two actions, as oppose to adding new creation logic, speeds up the
creation of new subclasses.</span></font></font></p>
<p align="LEFT" style="margin-bottom: 0in"><font size="3" style="font-size: 13pt"><font size="3"><span style="font-weight: normal">	Two
other benefits to this solution are centralization of the logic for
document creation and having reduced unit testing needs for the subclasses.
When the logic of the document creation is centralized into a single
base class, reasoning about the document creation becomes easier. Problems arising from document creation are easier to track down. The
document base class becomes the focal point for the majority of  the
unit tests written for document creation. The focal point reduces the
need to test the subclasses since the vast majority of the behavior
is in the base.</span></font></font></p>
<p align="LEFT" style="margin-bottom: 0in"><font size="3" style="font-size: 13pt"><font size="3"><span style="font-weight: normal">	</span></font><font size="3"><b>Drawbacks:</b></font><font size="3"><span style="font-weight: normal">
A large drawback of placing all the logic relating to the document
creation in the base is that the rules for creation have to be
completely available. If the rules of the creation of the document
are not known then the base class will be incomplete. When the base
class is incomplete, it has to be reopened every time a new rule is
found. The problem of adding rules leads to the main drawback of the
solution: extensibility. This solution is in no way extensible since
all the logic is congregated in the base class. This drawback does
pose problems, however with a little rejiggering the impact of this
drawback can be minimized. One possible fix, that will reduce the
extensibility problem, but will increase the work to create a
subclass, is to add an abstract method to the base that filters the
dictionary before it is sent out.&nbsp;</span></font></font>
</p> 
<pre class="prettyprint">abstract class Document
{
	IDictionary<string, string=""> FormTextFields
	{
		get
		{
			return new Dictionary<string, string="">
			{
				{ "NameField", this.NameField },
				{ "AgeField", this.AgeField }
			};
		}
	}
	
	protected abstract IDictionary<string,string> FilterTextFields(IDictionary<string,string> textFields);
}

class SmallDocument : Document
{
	protected override IDictionare<string, string=""> FilterTextFields(IDictionary<string,string> textFields)
	{
		textFields["NameField"] = SmallLogic();
		return textFields;
	}
	
	protected override DocumentType DocumentType
	{
		get
		{
			return DocumentType.Small;
		}
	}
}
</string,string></string,></string,string></string,string></string,></string,></pre>]]></description>
            <link>http://www.nearinfinity.com/blogs/sean_howell/modeling_multiple_logical_view.html</link>
            <guid>http://www.nearinfinity.com/blogs/sean_howell/modeling_multiple_logical_view.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">General</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Domain modeling</category>
            
            <pubDate>Sun, 20 Feb 2011 21:49:24 -0500</pubDate>
        </item>
        
        <item>
            <title>Sharepoint ASP .Net Ajax Configuration</title>
            <description><![CDATA[In the world of web development, there is a little thing called ajax. Ajax is so simple because it is built in to Javascript. I like to use ajax to make web applications that look like they are not stuck in the past. Tools like jQuery make ajax so simple with its commands like:<div><pre class="prettyprint">$.get $.post $.load</pre>ASP .Net has, what they tout as ultra simple, the update panel for ajax post backs to the server. But, this tool is not as simple as it seems. While deceptively simple to stick on a page and wire up to the code behind, it takes much more to make this tool work.<div><br /><div>Like everything else in the Microsoft world, to make ASP .Net have ajax requires a dll and, through reading the documentation, a crap load of changes to the web.config file. Sure, it is easy to get the web.config all nice and set up if you have Visual Studios do it for you. Just create a new Web Site and start debugging the website. Voila, all of the configuration setting needed to use ajax are there.<br /></div><div><br /></div><div>But, for those whose have to do through code for, say, a Sharepoint web site that has to be deployed anywhere, they feel the pain of drudging through the required assembly strings and making SPWebConfigModifications. So, the first step on the path to Sharepoint ajaxiness is to go out to all the dlls and collect all the assembly strings needed:</div><div><br /><pre class="prettyprint">const string scriptResourceHandler = "System.Web.Handlers.ScriptResourceHandler,System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
const string scripthandlerfactory = "ScriptHandlerFactory";
const string scripthandlerfactoryappservice = "ScriptHandlerFactoryAppService";
const string scriptresource = "ScriptResource";
const string scriptModuleAssembly = "System.Web.Handlers.ScriptModule,System.Web.Extensions,Version=3.5.0.0,Culture=Neutral,PublicKeyToken=31bf3856ad364e35";
const string webScriptAssembly = "System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35";
const string webExtensionAssembly = "System.Web.Extensions,Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"</pre>After you have done that, or just copied the above assemblies, those assemblies have to be added to the web.config. That is where the SPWebConfigModification comes into play. First, you'll want to clear the modifications otherwise, modifications might appear for items that are long gone.&nbsp;</div><div><br /><pre class="prettyprint">webApp.WebConfigModifications.Clear();</pre>After that is set up, there is quite a bit to add to the WebConfigModification collection. Here OWNER, is something you set somewhere else and keep handy for when you have to remove all of the changes from the web.config.</div><div><br /><pre class="prettyprint">webApp.WebConfigModifications.Add(CreateControlSection());		webApp.WebConfigModifications.Add(CreateSafeControl(webExtensionAssembly,"System.Web.UI"));
webApp.WebConfigModifications.Add(CreateAjaxAssembly(webExtensionAssembly));			webApp.WebConfigModifications.Add(CreateHttpScriptHandler(scriptModuleAssembly,"ScriptModule"));
webApp.WebConfigModifications.Add(CreateScriptResource(scriptResourceHandler,"ScriptResource.axd","GET,HEAD"))
webApp.WebConfigModifications.Add(CreateScriptResource(webScriptAssembly,"*_AppService.axd","*"));
webApp.WebConfigModifications.Add(CreateScriptResource(webScriptAssembly,"*.asmx","*"));
webApp.WebConfigModifications.Add(CreateWebServerSection());
webApp.WebConfigModifications.Add(CreateWebServerHandlerSection());
webApp.WebConfigModifications.Add(RemoveWebServiceHandler(scripthandlerfactory));
webApp.WebConfigModifications.Add(RemoveWebServiceHandler(scripthandlerfactoryappservice));
webApp.WebConfigModifications.Add(RemoveWebServiceHandler(scriptresource));
webApp.WebConfigModifications.Add(CreateWebServiceHandler(webScriptAssembly,"*.asmx","*",scripthandlerfactory));
webApp.WebConfigModifications.Add(CreateWebServiceHandler(webScriptAssembly,"*_AppService.axd","*",scripthandlerfactoryappservice));webApp.WebConfigModifications.Add(CreateWebServiceHandler(scriptResourceHandler,"ScriptResource.axd", "GET,HEAD", scriptresource));
webApp.Farm.Services.GetValue<spwebservice>().ApplyWebConfigModifications();
webApp.Update();
/* Thus begins the many methods to add each little piece of the web.config */
private SPWebConfigModification CreateScriptResource(string assembly,string path,string verb) {
      return new SPWebConfigModification {
		Path = "configuration/system.web/httpHandlers",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture,"add[@verb='{2}'][@path='{1}'][@type='{0}'][@validate='false']",assembly,path,verb),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format("<add verb="{2}" path="{1}" type="{0}" validate="false">", assembly,path,verb)
	};
}

private SPWebConfigModification CreateWebServiceHandler(string assembly,string path,string verb,string name) {
	return new SPWebConfigModification {
		Path = "configuration/system.webServer/handlers",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture,"add[@verb='{2}'][@path='{1}'][@type='{0}'][@preCondition='integratedMode'][@name='{3}']",assembly,path,verb,name),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format("<add verb="{2}" path="{1}" type="{0}" precondition="integratedMode" name="{3}">", assembly,path,verb,name)
	};
}
private SPWebConfigModification RemoveWebServiceHandler(string name) {
	return new SPWebConfigModification {
		Path = "configuration/system.webServer/handlers",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture,"add[@name='{0}']",name),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format("<remove name="{0}">",name)
	};
}

private static SPWebConfigModification CreateHttpScriptHandler(string assembly,string name) {
	return new SPWebConfigModification {
		Path = "configuration/system.web/httpModules",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture, "add[@name='{0}'] [@type='{1}']",name, assembly),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format("<add name="{0}" type="{1}">",name, assembly)
	};
}

private static SPWebConfigModification CreateAssembly(string assembly) {
	return new SPWebConfigModification {
	        Path = "configuration/system.web/compilation/assemblies",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture, "add[@assembly='{0}']", assembly),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format(CultureInfo.InvariantCulture, "<add assembly="{0}">", assembly)
	};
}
private static SPWebConfigModification CreateAjaxAssembly(string assembly) {
	return new SPWebConfigModification {
		Path = "configuration/system.web/pages/controls",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture, "add[@tagPrefix='{0}'][@namespace='{1}'][@assembly='{2}']","asp","System.Web.UI", assembly),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format(CultureInfo.InvariantCulture, "<add tagprefix="{0}" namespace="{1}" assembly="{2}">","asp","System.Web.UI", assembly)
	};
}
private static SPWebConfigModification CreateSafeControl(string assembly, string nameSpace) {
	return new SPWebConfigModification {
		Path = "configuration/SharePoint/SafeControls",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture, "SafeControl[@Assembly='{0}'][@Namespace='{1}'][@TypeName='*'][@Safe='True']", assembly, nameSpace),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format(CultureInfo.InvariantCulture, "<safecontrol assembly="{0}" namespace="{1}" typename="*" safe="True">", assembly,				nameSpace)
	};
}
private static SPWebConfigModification CreateControlSection() {
	return new SPWebConfigModification {
		Path = "configuration/system.web/pages",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureSection,
		Name = "controls",
		Value =@"<controls></controls>",
		Sequence = 0,
		Owner = OWNER
	};
}
private static SPWebConfigModification CreateWebServerSection() {
	return new SPWebConfigModification {
		Path = "configuration",
	        Type = SPWebConfigModification.SPWebConfigModificationType.EnsureSection,
		Name = "system.webServer",
		Value =@"<system.webserver></system.webserver>",
		Sequence = 0,
		Owner = OWNER
	};
}
private static SPWebConfigModification CreateWebServerHandlerSection() {
       return new SPWebConfigModification {
		Path = "configuration/system.webServer",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureSection,
		Name = "handlers",
		Value =@"<handlers></handlers>",
		Sequence = 0,
		Owner = OWNER
	};		
}</safecontrol></add></add></add></remove></add></add></spwebservice></pre><br />So, why on earth does it take that much code to generate the xml required to use ajax in Sharepoint?</div></div></div>]]></description>
            <link>http://www.nearinfinity.com/blogs/sean_howell/sharepoint_asp_net_ajax_configuration.html</link>
            <guid>http://www.nearinfinity.com/blogs/sean_howell/sharepoint_asp_net_ajax_configuration.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Web Development</category>
            
            
            <pubDate>Tue, 02 Feb 2010 18:34:17 -0500</pubDate>
        </item>
        
    </channel>
</rss>

