<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>VincentH on .NET &#187; Solutions Factory Features</title>
	<atom:link href="http://vincenth.net/blog/archive/category/factory/features/feed" rel="self" type="application/rss+xml" />
	<link>http://vincenth.net/blog</link>
	<description>Software : Factories &#38; Architecture</description>
	<lastBuildDate>Thu, 26 Nov 2009 16:30:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Managing Environment-Specific web.config, app.config and EntLib Config Files</title>
		<link>http://vincenth.net/blog/archive/2009/11/26/managing-environment-specific-web-config-app-config-and-entlib-config-files.aspx</link>
		<comments>http://vincenth.net/blog/archive/2009/11/26/managing-environment-specific-web-config-app-config-and-entlib-config-files.aspx#comments</comments>
		<pubDate>Thu, 26 Nov 2009 16:09:58 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[Solutions Factory Features]]></category>
		<category><![CDATA[Solutions Factory Usage]]></category>

		<guid isPermaLink="false">http://vincenth.net/blog/archive/2009/11/26/managing-environment-specific-web-config-app-config-and-entlib-config-files.aspx</guid>
		<description><![CDATA[When you need to deploy a solution to multiple environments (e.g. separate Development, Test, Acceptation and Production or DTAP environments), you often have a set of environment-specific settings that you need to manage.

Since version 2.1 the Macaw Solutions Factory supports environment-specific web.config, app.config and EntLib config files.

Recommendations

Managing environment specific settings is risky, because by definition [...]]]></description>
			<content:encoded><![CDATA[<p>When you need to deploy a solution to multiple environments (e.g. separate Development, Test, Acceptation and Production or DTAP environments), you often have a set of environment-specific settings that you need to manage.
</p>
<p>Since version 2.1 the <a href="http://solutionsfactory.macaw.nl/">Macaw Solutions Factory</a> supports environment-specific web.config, app.config and EntLib config files.
</p>
<h2>Recommendations<br />
</h2>
<p>Managing environment specific settings is risky, because by definition you cannot test these settings anywhere else.
</p>
<p>For this reason, the Microsoft .NET Architecture Style (MAST) recommends to minimize the number of environment specific settings that your solution needs by design.
</p>
<p>Secondly, MAST recommends that you further reduce risk by avoiding duplication of environment specific settings in multiple config files within the same environment. Instead, try to place these settings as much as possible in one central repository for each environment, e.g. in a service, a database or a SharePoint list (the last one has the added benefit of a free management UI).
</p>
<p>Still, some technologies require settings in configuration files. To support this, the Factory allows you to manage environment-specific web.config, app.config and MS Enterprise Library (EntLib) settings.
</p>
<p>Note that each MAST product has separate app.config, web.config and entlib config files. However to further reduce duplication of config files when maintaining multiple Factory products in the same environment, it is possible to share config files from a single location in source control across multiple MAST products, by using e.g. Externals in Subversion source control or NTFS Junctions when using TFS source control.
</p>
<h2>To add an environment-specific app.config or web.config file:<br />
</h2>
<ol>
<li>Browse to the folder where your shared app.config or web.config file is located.<br /><img src="http://vincenth.net/blog/wp-content/uploads/112609_1610_ManagingEnv1.png" alt=""/><br />It should be located in a subfolder under the _ConfigFiles folder for the product dependency folder that contains  your Visual Studio solution.
</li>
<li>Create the new app / web config file in this folder and prefix the file name with the environment name (this can be anything, e.g. &#8216;production&#8217; or a specific machine name)<br /><img src="http://vincenth.net/blog/wp-content/uploads/112609_1610_ManagingEnv2.png" alt=""/>
		</li>
<li>For each machine that should use this configuration, specify the new environment-specific web / app config file name in the machine configuration file.<br /><img src="http://vincenth.net/blog/wp-content/uploads/112609_1610_ManagingEnv3.png" alt=""/><br />Note that a sample.production.machine.config file is supplied with the Factory.
</li>
</ol>
<p>Now when you deploy a deployment package on any of these machines, or when you build a solution in Visual Studio on any of these machines, the environment-specific version of the config file will be deployed to the runtime locations as the web.config or app.config file.
</p>
<h2>To add a new environment to MS Enterprise Library settings:<br />
</h2>
<p>We leverage the built-in EntLib feature &#8216;Environmental Overrides&#8217;.
</p>
<ol>
<li>Select &#8216;Edit Enterprise Library product configuration&#8217; in the Factory Guide:
</li>
<li>Create a new Environment, e.g. &#8216;Test&#8217;:<br /><img src="http://vincenth.net/blog/wp-content/uploads/112609_1610_ManagingEnv4.png" alt=""/>
<p><span style="background-color:yellow">Be sure to follow the naming convention</span> for the environment-specific files as indicated below:<br /><img src="http://vincenth.net/blog/wp-content/uploads/112609_1610_ManagingEnv5.png" alt=""/><br />When you click &#8216;Save&#8217;, the environment delta file will be created:<br /><img src="http://vincenth.net/blog/wp-content/uploads/112609_1610_ManagingEnv6.png" alt=""/>
		</li>
<li>Now you can specify an override for any EntLib setting, for the Test environment. First select the setting, then select the value &#8216;Override Properties&#8217; for &#8216;Override on Test&#8217;, and finally supply the override value for the setting.
<p>E.g. to override a database connection string:<br /><img src="http://vincenth.net/blog/wp-content/uploads/112609_1610_ManagingEnv7.png" alt=""/>
		</li>
<li>Now add an override value for the Test environment for the Application Setting &#8216;MastEnvironmentMachineNames&#8217;:<br /><img src="http://vincenth.net/blog/wp-content/uploads/112609_1610_ManagingEnv8.png" alt=""/><br />The MastEnvironmentMachineNames value is a comma-separated list of names of the machines that make up this environment. Wildcards * and ? are supported. These are the same machine names that are used in the filename of the machine configuration files.
<p>Note that when a machine name does not match any override value of MastEnvironmentMachineNames, the base EntLib configuration without any overrides will be used.
		</li>
<li>Select &#8216;Save&#8217; to save all override settings in the Test.dconfig file. Also right-Click the (Test) environment and select &#8216;Save Merged Configuration&#8217; to create the environment-specific EntLib configuration file :<br /><img src="http://vincenth.net/blog/wp-content/uploads/112609_1610_ManagingEnv9.png" alt=""/><br />
			<img src="http://vincenth.net/blog/wp-content/uploads/112609_1610_ManagingEnv10.png" alt=""/><br />Don&#8217;t forget to add both the &lt;Environment&gt;.dconfig and the Entlib-&lt;Environment&gt;-Product.exe.config to source control.
</li>
</ol>
<p>Now the correct environment-specific version of the EntLib configuration file will be deployed when you deploy a MAST package on a machine, or when you select the &#8216;Deploy Enterprise Library product configuration&#8217; action in the Factory Guide:<br /><img src="http://vincenth.net/blog/wp-content/uploads/112609_1610_ManagingEnv11.png" alt=""/>
	</p>
<h2>To edit or add values in an existing environment-specific EntLib file:<br />
</h2>
<ol>
<li>First open the base EntLib configuration via the &#8216;Edit Enterprise Library product configuration &#8216; action in the Factory Guide. It will open without any environment overrides loaded.
</li>
<li>Then right-click the Environments node, select &#8216;Open Environment Delta&#8217; and open the appropriate &lt;Environment&gt;.dconfig file:<br /><img src="http://vincenth.net/blog/wp-content/uploads/112609_1610_ManagingEnv12.png" alt=""/>
		</li>
<li>Once you are done editing and adding new override values, save both the Entlib .dconfig file and the merged configuration file again.
</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://vincenth.net/blog/archive/2009/11/26/managing-environment-specific-web-config-app-config-and-entlib-config-files.aspx/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Detect 32 or 64 bits Windows &#8211; regardless of WoW64 &#8211; with the PowerShell OSArchitecture function</title>
		<link>http://vincenth.net/blog/archive/2009/11/02/detect-32-or-64-bits-windows-regardless-of-wow64-with-the-powershell-osarchitecture-function.aspx</link>
		<comments>http://vincenth.net/blog/archive/2009/11/02/detect-32-or-64-bits-windows-regardless-of-wow64-with-the-powershell-osarchitecture-function.aspx#comments</comments>
		<pubDate>Mon, 02 Nov 2009 15:09:32 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Solutions Factory Features]]></category>

		<guid isPermaLink="false">http://vincenth.net/blog/?p=181</guid>
		<description><![CDATA[In 64-bits versions of Windows Operating Systems, a subsystem called Windows on Windows 64 (WoW64) enables you to run 32 bits applications. Even to date, many Windows applications only exist in a 32 bits version – not the least of which is Microsoft&#8217;s own Visual Studio(!)
The purpose of WoW64 is to hide many of the [...]]]></description>
			<content:encoded><![CDATA[<p>In 64-bits versions of Windows Operating Systems, a subsystem called <a href="http://en.wikipedia.org/wiki/WoW64">Windows on Windows 64</a> (WoW64) enables you to run 32 bits applications. Even to date, many Windows applications only exist in a 32 bits version – not the least of which is Microsoft&#8217;s own Visual Studio(!)</p>
<p>The purpose of WoW64 is to hide many of the structural differences between 32 bits and 64 bits Windows for 32 bits applications. This is a good thing. Most of the time, anyway&#8230;</p>
<p>However, when your PowerShell script runs in a 32 bits process on a 64 bits OS, and you want to integrate with 64-bits applications (e.g. you want to integrate SharePoint or SQL Server within Visual Studio), WoW64 can get in the way.</p>
<p>E.g., WoW64 hides the 64 bit registry and changes the environment variables for processor architecture and for the program files folder – in short, WoW64 hides that you are running on a 64 bits OS.</p>
<p>To detect a 64 bits OS from PowerShell on Vista, W2008 and later Windows versions, we could use WMI:</p>

<div class="wp_syntax"><div class="code"><pre class="powershell" style="font-family:monospace;"><span style="color: #000000;">&#40;</span><span style="color: #008080; font-weight: bold;">Get-WMIObject</span> win32_operatingsystem<span style="color: #000000;">&#41;</span>.OSArchitecture</pre></div></div>

<p>However, this is not supported on W2003.</p>
<p>Fortunately, Microsoft provided an alternative, which is supported on all Windows versions that have Wow64: the <strong>IsWow64Process</strong> function. Since this is an unmanaged API call to Kernel32.dll, we need to do some extra work to call this in PowerShell.</p>
<p>We can write a simple managed C# wrapper around IsWow64Process:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">using</span> <span style="color: #008080;">System</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Runtime.InteropServices</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> Kernel32
<span style="color: #000000;">&#123;</span>
    <span style="color: #000000;">&#91;</span>DllImport<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;kernel32.dll&quot;</span>, SetLastError <span style="color: #008000;">=</span> <span style="color: #0600FF;">true</span>, CallingConvention <span style="color: #008000;">=</span> CallingConvention.<span style="color: #0000FF;">Winapi</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
    <span style="color: #000000;">&#91;</span><span style="color: #0600FF;">return</span><span style="color: #008000;">:</span> MarshalAs<span style="color: #000000;">&#40;</span>UnmanagedType.<span style="color: #FF0000;">Bool</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
    <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #0600FF;">extern</span> <span style="color: #FF0000;">bool</span> IsWow64Process<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#91;</span><span style="color: #0600FF;">In</span><span style="color: #000000;">&#93;</span> IntPtr hProcess, <span style="color: #000000;">&#91;</span><span style="color: #0600FF;">Out</span><span style="color: #000000;">&#93;</span> <span style="color: #0600FF;">out</span> <span style="color: #FF0000;">bool</span> lpSystemInfo<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">// This overload returns True if the current process is running on Wow, False otherwise</span>
    <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">bool</span> CurrentProcessIsWow64<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        <span style="color: #FF0000;">bool</span> retVal<span style="color: #008000;">;</span>
        <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #008000;">!</span><span style="color: #000000;">&#40;</span>IsWow64Process<span style="color: #000000;">&#40;</span><span style="color: #000000;">System.<span style="color: #0000FF;">Diagnostics</span></span>.<span style="color: #0000FF;">Process</span>.<span style="color: #0000FF;">GetCurrentProcess</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Handle</span>, <span style="color: #0600FF;">out</span> retVal<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">throw</span> <span style="color: #008000;">new</span> Exception<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;IsWow64Process() failed&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
        <span style="color: #0600FF;">return</span> retVal<span style="color: #008000;">;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>When we use the PowerShell <a href="http://vincenth.net/blog/archive/2009/10/27/call-inline-c-from-powershell-with-invokecsharp.aspx">InvokeCSharp</a> function, we can put this C# inline in our PowerShell script:</p>

<div class="wp_syntax"><div class="code"><pre class="powershell" style="font-family:monospace;"><span style="color: #0000FF;">Function</span> global:CurrentProcessIsWOW64
<span style="color: #000000;">&#123;</span>
    <span style="color: #008000;"># Use some inline C# code to call the unmanaged IsWow64Process() function in Kernel32.dll and return its result:</span>
    <span style="color: #800080;">$code</span> <span style="color: pink;">=</span> <span style="color: pink;">@</span><span style="color: #800000;">&quot;
        using System;
        using System.Runtime.InteropServices;
&nbsp;
        public class Kernel32
        {
            [DllImport(&quot;</span>kernel32.dll<span style="color: #800000;">&quot;, SetLastError = true, CallingConvention = CallingConvention.Winapi)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool lpSystemInfo);
&nbsp;
            // This overload returns True if the current process is running on Wow, False otherwise
            public bool CurrentProcessIsWow64()
            {
                bool retVal;
                if (!(IsWow64Process(System.Diagnostics.Process.GetCurrentProcess().Handle, out retVal))) { throw new Exception(&quot;</span>IsWow64Process<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> failed<span style="color: #800000;">&quot;); }
                return retVal;
            }
        }
&quot;</span><span style="color: pink;">@</span>
    InvokeCSharp <span style="color: pink;">-</span>code <span style="color: #800080;">$code</span> <span style="color: #008080; font-style: italic;">-class</span> <span style="color: #800000;">'Kernel32'</span> <span style="color: pink;">-</span>method <span style="color: #800000;">'CurrentProcessIsWow64'</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #0000FF;">Function</span> global:ProcessArchitecture
<span style="color: #000000;">&#123;</span>
    <span style="color: #0000FF;">switch</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#91;</span>System.IntPtr<span style="color: #000000;">&#93;</span>::Size<span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        <span style="color: #000000;">4</span> <span style="color: #000000;">&#123;</span> <span style="color: #000000;">32</span> <span style="color: #000000;">&#125;</span>
        <span style="color: #000000;">8</span> <span style="color: #000000;">&#123;</span> <span style="color: #000000;">64</span> <span style="color: #000000;">&#125;</span>
        default <span style="color: #000000;">&#123;</span> <span style="color: #0000FF;">throw</span> <span style="color: #800000;">&quot;Unknown Process Architecture: $([System.IntPtr]::Size * 8) bits&quot;</span> <span style="color: #000000;">&#125;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #0000FF;">Function</span> global:OSArchitecture
<span style="color: #000000;">&#123;</span>
    <span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span>ProcessArchitecture<span style="color: #000000;">&#41;</span> <span style="color: #FF0000;">-eq</span> <span style="color: #000000;">32</span><span style="color: #000000;">&#41;</span> <span style="color: #FF0000;">-and</span> <span style="color: #000000;">&#40;</span>CurrentProcessIsWOW64<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #000000;">64</span> <span style="color: #000000;">&#125;</span> <span style="color: #0000FF;">else</span> <span style="color: #000000;">&#123;</span> ProcessArchitecture <span style="color: #000000;">&#125;</span>
    <span style="color: #008000;"># Note that on Vista, W2008 and later Windows versions, we could use (Get-WMIObject win32_operatingsystem).OSArchitecture.</span>
    <span style="color: #008000;"># We don't use that because we also support W2003</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>So there you have it, some simple PowerShell functions to detect the process architecture and the OS architecture, regardless of whether or not you are running under WoW64.</p>
<p>P.S. I also added these functions to the global functions in the <a href="http://solutionsfactory.macaw.nl/">Macaw Solutions Factory</a>, so they can be leveraged by anyone who wants to extend the Factory.</p>
]]></content:encoded>
			<wfw:commentRss>http://vincenth.net/blog/archive/2009/11/02/detect-32-or-64-bits-windows-regardless-of-wow64-with-the-powershell-osarchitecture-function.aspx/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Call inline C# from PowerShell with InvokeCSharp</title>
		<link>http://vincenth.net/blog/archive/2009/10/27/call-inline-c-from-powershell-with-invokecsharp.aspx</link>
		<comments>http://vincenth.net/blog/archive/2009/10/27/call-inline-c-from-powershell-with-invokecsharp.aspx#comments</comments>
		<pubDate>Tue, 27 Oct 2009 11:58:52 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Solutions Factory Features]]></category>

		<guid isPermaLink="false">http://vincenth.net/blog/?p=174</guid>
		<description><![CDATA[Out of the box PowerShell 1.0 makes it very easy to call any managed code in an assembly. However, one of the strong points of a scripted language such as PowerShell is that you can debug and extend it in any environment without the need for development tools or additional source code. This is especially [...]]]></description>
			<content:encoded><![CDATA[<p>Out of the box PowerShell 1.0 makes it very easy to call any managed code in an assembly. However, one of the strong points of a scripted language such as PowerShell is that you can debug and extend it in any environment without the need for development tools or additional source code. This is especially valuable in scripts that integrate heavily with production environments, e.g. with automated deployment scripts such as we use in the <a href="http://solutionsfactory.macaw.nl/">Macaw Solutions Factory</a>.</p>
<p>Ideally you would want the ability to call any C# source code from PowerShell, either inline or as a separate source file, effectively adding the maintainability benefits of a scripted language to C#. Based on <a href="http://www.leeholmes.com/blog/LibraryForInlineCInMSH.aspx">a library created by Lee Holmes</a> I created an improved PowerShell 1.0 function called <strong>InvokeCSharp</strong> that does just this.</p>
<p>Note that in PowerShell V2, this functionality is available through the built-in <a href="http://technet.microsoft.com/en-us/library/dd315241.aspx">Add-Type cmdlet</a>. </p>
<p>InvokeCSharp is completely self-contained and can be used in any PowerShell script.</p>
<h2>Usage</h2>
<p>Here are some simple examples on how to use InvokeCSharp:</p>
<p>Let&#8217;s say we have a file <strong>MyClass.cs</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">using</span> <span style="color: #008080;">System</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> MyClass
<span style="color: #000000;">&#123;</span>
    <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">string</span> AString<span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF;">public</span> MyClass<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">string</span> aString<span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        AString <span style="color: #008000;">=</span> aString<span style="color: #008000;">;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Then we can invoke it like this in PowerShell:</p>

<div class="wp_syntax"><div class="code"><pre class="powershell" style="font-family:monospace;"><span style="color: #008000;"># Create a class instance from a .cs file, passing a parameter to the class constructor:</span>
<span style="color: #008000;"># Note that the class name can be omitted here, since it is implied from the .cs file name</span>
<span style="color: #800080;">$myClassInstance</span> <span style="color: pink;">=</span> InvokeCSharp <span style="color: #FF0000;">-file</span> <span style="color: #800000;">'.\MyClass.cs'</span> <span style="color: pink;">-</span>parameters <span style="color: #800000;">'A text'</span></pre></div></div>

<p>Or we can put some C# code inline in the PowerShell script itself, and invoke it:</p>

<div class="wp_syntax"><div class="code"><pre class="powershell" style="font-family:monospace;"><span style="color: #008000;"># Call some simple inline code. Note that you could also wrap the code in a namespace,</span>
<span style="color: #008000;"># add using statements and reference other assemblies.</span>
<span style="color: #800080;">$code</span> <span style="color: pink;">=</span> <span style="color: pink;">@</span><span style="color: #800000;">&quot;
	public class MyClass2
	{
		public static int MyStaticMethod(int a, int b)
		{
			return a * b;
		}
	}
&quot;</span><span style="color: pink;">@</span>
<span style="color: #800080;">$result</span> <span style="color: pink;">=</span> InvokeCSharp <span style="color: pink;">-</span>code <span style="color: #800080;">$code</span> <span style="color: #008080; font-style: italic;">-class</span> <span style="color: #800000;">'MyClass2'</span> <span style="color: pink;">-</span>method <span style="color: #800000;">'MyStaticMethod'</span> <span style="color: pink;">-</span>parameters <span style="color: #000000;">3</span><span style="color: pink;">,</span> <span style="color: #000000;">7</span> <span style="color: #008000;"># Will return 21</span></pre></div></div>

<p>Although these are very simple examples, all the rich goodness of PowerShell &#8211; .NET integration is available. Passing any type of parameters back and forth is simple and completely transparent. All C# features can be used; e.g. you can use the C# DllImport attribute to call unmanaged API&#8217;s when COM interop is not available or not preferred.</p>
<p>After initial compilation the performance is equivalent to calling compiled assemblies from PowerShell.</p>
<h2>Extending the Macaw Solutions Factory PowerShell scripts with inline C#</h2>
<p>I added InvokeCSharp to the global functions in the <a href="http://solutionsfactory.macaw.nl/">Macaw Solutions Factory</a>. This makes it possible to simply extend or modify any Factory script – including the scripts that deploy a MAST Product from a package to (production) machines.</p>
<p>For anyone who is more adept with C# than with PowerShell this will make it easier to extend the Factory scripts. This also enables leveraging existing C# libraries from PowerShell while keeping the entire solution maintainable as a script.</p>
<h2>Improvements</h2>
<p>The improvements I added to InvokeCSharp when compared to the original version are:</p>
<ul>
<li>The C# code you specify is completely self-contained; no more C# wrapper code where your code is pasted into. This improves readability and maintainability of inline C# code.</li>
<li>Simpler parameter passing; no more wrapper code needed for parameters and return values.</li>
<li>Automatically un-wraps parameters that PowerShell wraps in a PSObject. This eliminates the need to explicitly cast parameters to make them strongly typed on each call to InvokeCSharp, and to always wrap them in @().<br />
Figuring this one out was interesting; it required diving in the innards of the <a href="http://msdn.microsoft.com/en-us/library/ms714419(VS.85).aspx">PowerShell Extended Type System</a> (ETS) which gets in the way when you work with .NET reflection classes from PowerShell. PowerShell tries to make the ETS transparent to the PowerShell user, which in general is a good thing but in this case meant it was hard to see what was happening.</li>
<li>Adds support for calling static methods, including overloaded methods, without creating a class instance.</li>
<li>Adds support for creating a class instance and providing constructor parameters.</li>
<li>Caches compiled assemblies instead of class instances. This improves performance because it eliminates duplicate compilation when the same C# code is called more than once. In addition to assembly caching you can of course also cache the object instances using any of the standard PowerShell mechanisms; however this is better handled outside the InvokeCSharp function.</li>
<li>Support for inline C# and separate C# source files; the latter allows you to easily edit the C# in Visual Studio, e.g. to use IntelliSense and compile the source to catch compile time errors.</li>
</ul>
<h2>PowerShell Source</h2>
<p>So here are the goods &#8211; the complete PowerShell source for InvokeCSharp:</p>

<div class="wp_syntax"><div class="code"><pre class="powershell" style="font-family:monospace;"><span style="color: #008000;">#&amp;lt; # #.Synopsis #   Create a class instance and/or invoke a method on C# source code. #   For details, see: #   http://vincenth.net/blog/archive/2009/10/27/call-inline-c-from-powershell-with-invokecsharp.aspx  #.Description #   This function compiles the provided C# source code (only if necessary, compiled #   assemblies are cached). The code can be supplied either inline in a string or #   in a source file. Relative source filename paths are interpreted #   relative to the parent folder of the calling script. #   This enables simple organization and reference of related .ps1 and .cs files. # #   If a method name is specified, that method is invoked with any supplied #   parameters and the function then returns the result of the method. #   Both static and nonstatic methods are supported, including overloaded #   methods. # #   If no method name is specified, an instance of the specified class is #   created, passing any supplied parameters to the class constructor, and the #   function then returns the class instance. You can then program against the #   class instance in standard PowerShell fashion. # #   If necessary for compilation, you can specify names of any referenced #   assemblies. #.Parameter code #   The complete C# source code - effectively this is an inline C# source file. #   Note that it is possible but not necessary to declare classes within a #   namespace. #   Either the code parameter or the file parameter must be specified. #.Parameter file #   Absolute or relative path to a C# source file. Relative paths (beginning #   with '.\' or '..\') are interpreted relative to the folder that contains #   the calling script (i.e. the script that calls this function). #   Either the code parameter or the file parameter must be specified. #.Parameter class #   The name of the class to be instantiated / that contains the method to #   be invoked. Include the namespace in which the class is declared, if any. #   If you specify the -file parameter and the class name is identical to the #   file name, you can omit the -class parameter. #.Parameter method #   Either the name of the method to be invoked, '()' to invoke a  #   constructor to create and resturn a class instance, or '' to return #   the cached assembly. The last option allows you to precompile assemblies #   without calling a method or creating a class instance. #     #   If the specified method is not static, an instance of the class will #   be created on the fly. #.Parameter parameters #   To pass parameters to the constructor or method, specify them as an #   array of objects (e.g. with the comma operator or @() ). #.Parameter reference #   If necessary, specify an array of assembly filenames to be added as #   assembly references when the source code is compiled. #.Parameter forceCompile #   Specify this switch to force recompilation. This is useful if you specify #   the file parameter and the file contents has changed (when specifying a #   source file name, the cache key is the file name only - changes to the file #   do not automatically cause cache invalidation). #.Returns #   Either the cached assembly, a class instance or a method result (depending  #   on the value specified for the method parameter). #.Example #   # Create a class instance from a .cs file, passing a parameter to the class constructor: #   # Note that the class name can be omitted here, since it is implied from the .cs file name #   $myClassInstance = InvokeCSharp -file '.\MyClass.cs' -parameters 'A text' #     #   # Call some simple inline code. Note that you could also wrap the code in a namespace,  #   # add using statements and reference other assemblies. #   $code = @&quot; #       public class MyClass2 #       { #           public static int MyStaticMethod(int a, int b) #           { #               return a * b; #           } #       } #   &quot;@ #   $result = InvokeCSharp -code $code -class 'MyClass2' -method 'MyStaticMethod' -parameters 3, 7 # Will return 21 ##&amp;gt;</span>
<span style="color: #0000FF;">function</span> global:InvokeCSharp
<span style="color: #000000;">&#123;</span>
    <span style="color: #0000FF;">param</span><span style="color: #000000;">&#40;</span>
        <span style="color: #000000;">&#91;</span><span style="color: #008080;">string</span><span style="color: #000000;">&#93;</span> <span style="color: #800080;">$code</span> <span style="color: pink;">=</span> <span style="color: #800000;">''</span><span style="color: pink;">,</span>
        <span style="color: #000000;">&#91;</span><span style="color: #008080;">string</span><span style="color: #000000;">&#93;</span> <span style="color: #800080;">$file</span> <span style="color: pink;">=</span> <span style="color: #800000;">''</span><span style="color: pink;">,</span>
        <span style="color: #000000;">&#91;</span><span style="color: #008080;">string</span><span style="color: #000000;">&#93;</span> <span style="color: #800080;">$class</span> <span style="color: pink;">=</span> <span style="color: #800000;">''</span><span style="color: pink;">,</span>
        <span style="color: #000000;">&#91;</span><span style="color: #008080;">string</span><span style="color: #000000;">&#93;</span> <span style="color: #800080;">$method</span> <span style="color: pink;">=</span> <span style="color: #800000;">'()'</span><span style="color: pink;">,</span>
        <span style="color: #000000;">&#91;</span><span style="color: #008080;">Object</span><span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span><span style="color: #000000;">&#93;</span> <span style="color: #800080;">$parameters</span> <span style="color: pink;">=</span> <span style="color: #800080;">$null</span><span style="color: pink;">,</span>
        <span style="color: #000000;">&#91;</span>string<span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span><span style="color: #000000;">&#93;</span> <span style="color: #800080;">$reference</span> <span style="color: pink;">=</span> <span style="color: pink;">@</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: pink;">,</span>
        <span style="color: #000000;">&#91;</span><span style="color: #008080;">switch</span><span style="color: #000000;">&#93;</span> <span style="color: #800080;">$forceCompile</span>
    <span style="color: #000000;">&#41;</span>
&nbsp;
    <span style="color: #008000;"># Stores a cache of generated assemblies. If this library is dot-sourced</span>
    <span style="color: #008000;"># from a script, these objects go away when the script exits.</span>
    <span style="color: #0000FF;">if</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">-not</span> <span style="color: #000000;">&#40;</span><span style="color: #008080; font-weight: bold;">Test-Path</span> Variable:\macaw.solutionsfactory.assemblycache<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        $<span style="color: #000000;">&#123;</span>GLOBAL:macaw.solutionsfactory.assemblycache<span style="color: #000000;">&#125;</span> <span style="color: pink;">=</span> <span style="color: pink;">@</span><span style="color: #000000;">&#123;</span><span style="color: #000000;">&#125;</span>
    <span style="color: #000000;">&#125;</span>
&nbsp;
    <span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #800080;">$code</span> <span style="color: #FF0000;">-eq</span> <span style="color: #800000;">''</span><span style="color: #000000;">&#41;</span> <span style="color: #FF0000;">-and</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$file</span> <span style="color: #FF0000;">-eq</span> <span style="color: #800000;">''</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0000FF;">throw</span> <span style="color: #800000;">'Neither code nor file are specified. Specify either one or the other.'</span> <span style="color: #000000;">&#125;</span>
&nbsp;
    <span style="color: #008000;"># If a source file was specified, see if it was already loaded, compiled and cached:</span>
    <span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$file</span> <span style="color: #FF0000;">-ne</span> <span style="color: #800000;">''</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        <span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$code</span> <span style="color: #FF0000;">-ne</span> <span style="color: #800000;">''</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0000FF;">throw</span> <span style="color: #800000;">'Both code and file are specified. Specify either one or the other.'</span> <span style="color: #000000;">&#125;</span>
&nbsp;
        <span style="color: #008000;"># We interpret the current directory as the directory containing the calling script, instead of the currect directory of the current process.</span>
        <span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$file</span>.StartsWith<span style="color: #000000;">&#40;</span><span style="color: #800000;">'.'</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#123;</span>
            <span style="color: #800080;">$callingScriptFolder</span> <span style="color: pink;">=</span> <span style="color: #008080; font-weight: bold;">Split-Path</span> <span style="color: #008080; font-style: italic;">-path</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #008080; font-weight: bold;">Get-Variable</span> MyInvocation <span style="color: #008080; font-style: italic;">-Scope</span> <span style="color: #000000;">1</span><span style="color: #000000;">&#41;</span>.Value<span style="color: #000000;">&#41;</span>.MyCommand.Path <span style="color: #008080; font-style: italic;">-Parent</span>
            <span style="color: #800080;">$file</span> <span style="color: pink;">=</span> <span style="color: #008080; font-weight: bold;">Join-Path</span> <span style="color: #008080; font-style: italic;">-Path</span> <span style="color: #800080;">$callingScriptFolder</span> <span style="color: #008080; font-style: italic;">-ChildPath</span> <span style="color: #800080;">$file</span>
        <span style="color: #000000;">&#125;</span>
&nbsp;
        <span style="color: #008000;"># If no class name is  specified, we assume by convention that the file name is equal to the class name.</span>
        <span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$class</span> <span style="color: #FF0000;">-eq</span> <span style="color: #800000;">''</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #800080;">$class</span> <span style="color: pink;">=</span> <span style="color: #000000;">&#91;</span>System.IO.Path<span style="color: #000000;">&#93;</span>::GetFileNameWithoutExtension<span style="color: #000000;">&#40;</span><span style="color: #800080;">$file</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#125;</span>
&nbsp;
        <span style="color: #008000;"># Use the real full path as the cache key:</span>
        <span style="color: #800080;">$file</span> <span style="color: pink;">=</span> <span style="color: #000000;">&#91;</span>System.IO.Path<span style="color: #000000;">&#93;</span>::GetFullPath<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #008080; font-weight: bold;">Convert-Path</span> <span style="color: #008080; font-style: italic;">-path</span> <span style="color: #800080;">$file</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
        <span style="color: #800080;">$cacheKey</span> <span style="color: pink;">=</span> <span style="color: #800080;">$file</span>
    <span style="color: #000000;">&#125;</span>
    <span style="color: #0000FF;">else</span>
    <span style="color: #000000;">&#123;</span>
        <span style="color: #008000;"># See if the code has already been compiled and cached</span>
        <span style="color: #800080;">$cacheKey</span> <span style="color: pink;">=</span> <span style="color: #800080;">$code</span>
    <span style="color: #000000;">&#125;</span>
    <span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$class</span> <span style="color: #FF0000;">-eq</span> <span style="color: #800000;">''</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0000FF;">throw</span> <span style="color: #800000;">'Required parameter missing: class'</span> <span style="color: #000000;">&#125;</span>
&nbsp;
    <span style="color: #008000;"># See if the code must be (re)compiled:</span>
    <span style="color: #800080;">$cachedAssembly</span> <span style="color: pink;">=</span> $<span style="color: #000000;">&#123;</span>macaw.solutionsfactory.assemblycache<span style="color: #000000;">&#125;</span><span style="color: #000000;">&#91;</span><span style="color: #800080;">$cacheKey</span><span style="color: #000000;">&#93;</span>
    <span style="color: #0000FF;">if</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #800080;">$cachedAssembly</span> <span style="color: #FF0000;">-eq</span> <span style="color: #800080;">$null</span><span style="color: #000000;">&#41;</span> <span style="color: #FF0000;">-or</span> <span style="color: #800080;">$forceCompile</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        <span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$code</span> <span style="color: #FF0000;">-eq</span> <span style="color: #800000;">''</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #800080;">$code</span> <span style="color: pink;">=</span> <span style="color: #000000;">&#91;</span>System.IO.File<span style="color: #000000;">&#93;</span>::ReadAllText<span style="color: #000000;">&#40;</span><span style="color: #800080;">$file</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#125;</span>
        <span style="color: #008080; font-weight: bold;">Write-Verbose</span> <span style="color: #800000;">&quot;Compiling C# code:<span style="color: #008080; font-weight: bold;">`r</span><span style="color: #008080; font-weight: bold;">`n</span>$code<span style="color: #008080; font-weight: bold;">`r</span><span style="color: #008080; font-weight: bold;">`n</span>&quot;</span>
&nbsp;
        <span style="color: #008000;"># Obtains an ICodeCompiler from a CodeDomProvider class.</span>
        <span style="color: #800080;">$provider</span> <span style="color: pink;">=</span> <span style="color: #008080; font-weight: bold;">New-Object</span> Microsoft.CSharp.CSharpCodeProvider 
&nbsp;
        <span style="color: #008000;"># Get the location for System.Management.Automation DLL</span>
        <span style="color: #800080;">$dllName</span> <span style="color: pink;">=</span> <span style="color: #000000;">&#91;</span><span style="color: #008080;">PsObject</span><span style="color: #000000;">&#93;</span>.Assembly.Location
&nbsp;
        <span style="color: #008000;"># Configure the compiler parameters</span>
        <span style="color: #800080;">$compilerParameters</span> <span style="color: pink;">=</span> <span style="color: #008080; font-weight: bold;">New-Object</span> System.CodeDom.Compiler.CompilerParameters 
&nbsp;
        <span style="color: #800080;">$assemblies</span> <span style="color: pink;">=</span> <span style="color: pink;">@</span><span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;System.dll&quot;</span><span style="color: pink;">,</span> <span style="color: #800080;">$dllName</span><span style="color: #000000;">&#41;</span>
        <span style="color: #800080;">$compilerParameters</span>.ReferencedAssemblies.AddRange<span style="color: #000000;">&#40;</span><span style="color: #800080;">$assemblies</span><span style="color: #000000;">&#41;</span>
        <span style="color: #800080;">$compilerParameters</span>.ReferencedAssemblies.AddRange<span style="color: #000000;">&#40;</span><span style="color: #800080;">$reference</span><span style="color: #000000;">&#41;</span>
        <span style="color: #800080;">$compilerParameters</span>.IncludeDebugInformation <span style="color: pink;">=</span> <span style="color: #800080;">$true</span>
        <span style="color: #800080;">$compilerParameters</span>.GenerateInMemory <span style="color: pink;">=</span> <span style="color: #800080;">$true</span> 
&nbsp;
        <span style="color: #008000;"># Invokes compilation.</span>
        <span style="color: #800080;">$compilerResults</span> <span style="color: pink;">=</span> <span style="color: #800080;">$provider</span>.CompileAssemblyFromSource<span style="color: #000000;">&#40;</span><span style="color: #800080;">$compilerParameters</span><span style="color: pink;">,</span> <span style="color: #800080;">$code</span><span style="color: #000000;">&#41;</span>
&nbsp;
        <span style="color: #008000;"># Write any errors if generated.</span>
        <span style="color: #0000FF;">if</span><span style="color: #000000;">&#40;</span><span style="color: #800080;">$compilerResults</span>.Errors.Count <span style="color: #FF0000;">-gt</span> <span style="color: #000000;">0</span><span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#123;</span>
            <span style="color: #800080;">$errorLines</span> <span style="color: pink;">=</span> <span style="color: #800000;">&quot;&quot;</span>
            <span style="color: #0000FF;">foreach</span><span style="color: #000000;">&#40;</span><span style="color: #800080;">$error</span> <span style="color: #0000FF;">in</span> <span style="color: #800080;">$compilerResults</span>.Errors<span style="color: #000000;">&#41;</span>
            <span style="color: #000000;">&#123;</span>
                <span style="color: #800080;">$errorLines</span> <span style="color: pink;">+=</span> <span style="color: #800000;">&quot;<span style="color: #008080; font-weight: bold;">`n</span><span style="color: #008080; font-weight: bold;">`t</span>&quot;</span> <span style="color: pink;">+</span> <span style="color: #800080;">$error</span>.Line <span style="color: pink;">+</span> <span style="color: #800000;">&quot;:<span style="color: #008080; font-weight: bold;">`t</span>&quot;</span> <span style="color: pink;">+</span> <span style="color: #800080;">$error</span>.ErrorText
            <span style="color: #000000;">&#125;</span>
            <span style="color: #008080; font-weight: bold;">Write-Error</span> <span style="color: #800080;">$errorLines</span>
        <span style="color: #000000;">&#125;</span>
        <span style="color: #008000;"># There were no errors.  Store the resulting assembly in the cache.</span>
        <span style="color: #0000FF;">else</span>
        <span style="color: #000000;">&#123;</span>
            $<span style="color: #000000;">&#123;</span>macaw.solutionsfactory.assemblycache<span style="color: #000000;">&#125;</span><span style="color: #000000;">&#91;</span><span style="color: #800080;">$cacheKey</span><span style="color: #000000;">&#93;</span> <span style="color: pink;">=</span> <span style="color: #800080;">$compilerResults</span>.CompiledAssembly
        <span style="color: #000000;">&#125;</span>
&nbsp;
        <span style="color: #800080;">$cachedAssembly</span> <span style="color: pink;">=</span> $<span style="color: #000000;">&#123;</span>macaw.solutionsfactory.assemblycache<span style="color: #000000;">&#125;</span><span style="color: #000000;">&#91;</span><span style="color: #800080;">$cacheKey</span><span style="color: #000000;">&#93;</span>
    <span style="color: #000000;">&#125;</span>
&nbsp;
    <span style="color: #008000;"># Prevent type mismatch issues caused by PowerShell wrapping of managed objects in PSObject.</span>
    <span style="color: #008000;"># We need to explicitly unwrap those objects because otherwise the .NET reflection classes will</span>
    <span style="color: #008000;"># not find the constructor or method whose signature matches the specified parameters.</span>
    <span style="color: #008000;"># This unwrapping eliminates the need to always wrap all your parameters in @() and to explicitly</span>
    <span style="color: #008000;"># cast each parameter to the correct type in each call to InvokeCSharp.</span>
    <span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$parameters</span> <span style="color: #FF0000;">-ne</span> <span style="color: #800080;">$null</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        <span style="color: #0000FF;">for</span><span style="color: #000000;">&#40;</span><span style="color: #800080;">$i</span> <span style="color: pink;">=</span> <span style="color: #000000;">0</span>; <span style="color: #800080;">$i</span> <span style="color: #FF0000;">-lt</span> <span style="color: #800080;">$parameters</span>.Length; <span style="color: #800080;">$i</span><span style="color: pink;">++</span><span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#123;</span>
            <span style="color: #800080;">$parameters</span><span style="color: #000000;">&#91;</span><span style="color: #800080;">$i</span><span style="color: #000000;">&#93;</span> <span style="color: pink;">=</span> <span style="color: #000000;">&#91;</span>System.Management.Automation.LanguagePrimitives<span style="color: #000000;">&#93;</span>::ConvertTo<span style="color: #000000;">&#40;</span> `
                <span style="color: #800080;">$parameters</span><span style="color: #000000;">&#91;</span><span style="color: #800080;">$i</span><span style="color: #000000;">&#93;</span><span style="color: pink;">,</span> `
                <span style="color: #000000;">&#91;</span>System.<span style="color: #008080; font-weight: bold;">Type</span><span style="color: #000000;">&#93;</span>::GetType<span style="color: #000000;">&#40;</span><span style="color: #800080;">$parameters</span><span style="color: #000000;">&#91;</span><span style="color: #800080;">$i</span><span style="color: #000000;">&#93;</span>.GetType<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.FullName<span style="color: #000000;">&#41;</span> `
            <span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#125;</span>
    <span style="color: #000000;">&#125;</span>
&nbsp;
    <span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$method</span> <span style="color: #FF0000;">-eq</span> <span style="color: #800000;">''</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;"># We return the assembly</span>
    <span style="color: #000000;">&#123;</span>
        <span style="color: #800080;">$result</span> <span style="color: pink;">=</span> <span style="color: #800080;">$cachedAssembly</span>
    <span style="color: #000000;">&#125;</span>
    <span style="color: #0000FF;">elseif</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$method</span> <span style="color: #FF0000;">-eq</span> <span style="color: #800000;">'()'</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;"># We create and return a class instance</span>
    <span style="color: #000000;">&#123;</span>
        <span style="color: #800080;">$result</span> <span style="color: pink;">=</span> <span style="color: #800080;">$cachedAssembly</span>.CreateInstance<span style="color: #000000;">&#40;</span><span style="color: #800080;">$class</span><span style="color: pink;">,</span> <span style="color: #800080;">$false</span><span style="color: pink;">,</span> <span style="color: #000000;">&#91;</span>System.Reflection.BindingFlags<span style="color: #000000;">&#93;</span>::CreateInstance<span style="color: pink;">,</span> <span style="color: #800080;">$null</span><span style="color: pink;">,</span> <span style="color: #800080;">$parameters</span><span style="color: pink;">,</span> <span style="color: #800080;">$null</span><span style="color: pink;">,</span> <span style="color: pink;">@</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#125;</span>
    <span style="color: #0000FF;">else</span> <span style="color: #008000;"># We invoke the method and return the method result</span>
    <span style="color: #000000;">&#123;</span>
        <span style="color: #800080;">$classType</span> <span style="color: pink;">=</span> <span style="color: #800080;">$cachedAssembly</span>.GetType<span style="color: #000000;">&#40;</span><span style="color: #800080;">$class</span><span style="color: #000000;">&#41;</span>
&nbsp;
        <span style="color: #800080;">$parameterTypes</span> <span style="color: pink;">=</span> <span style="color: pink;">@</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
        <span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$parameters</span> <span style="color: #FF0000;">-ne</span> <span style="color: #800080;">$null</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0000FF;">foreach</span><span style="color: #000000;">&#40;</span><span style="color: #800080;">$p</span> <span style="color: #0000FF;">in</span> <span style="color: #800080;">$parameters</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #800080;">$parameterTypes</span> <span style="color: pink;">+=</span> <span style="color: #800080;">$p</span>.GetType<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span>
&nbsp;
        <span style="color: #800080;">$methodInfo</span> <span style="color: pink;">=</span> <span style="color: #800080;">$classType</span>.GetMethod<span style="color: #000000;">&#40;</span><span style="color: #800080;">$method</span><span style="color: pink;">,</span> <span style="color: #000000;">&#91;</span>System.<span style="color: #008080; font-weight: bold;">Type</span><span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span><span style="color: #000000;">&#93;</span><span style="color: #800080;">$parameterTypes</span><span style="color: #000000;">&#41;</span>
        <span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$methodInfo</span>.IsStatic<span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#123;</span>
            <span style="color: #800080;">$instance</span> <span style="color: pink;">=</span> <span style="color: #800080;">$null</span>
        <span style="color: #000000;">&#125;</span>
        <span style="color: #0000FF;">else</span>
        <span style="color: #000000;">&#123;</span>
            <span style="color: #800080;">$instance</span> <span style="color: pink;">=</span> <span style="color: #800080;">$cachedAssembly</span>.CreateInstance<span style="color: #000000;">&#40;</span><span style="color: #800080;">$class</span><span style="color: pink;">,</span> <span style="color: #800080;">$false</span><span style="color: pink;">,</span> <span style="color: #000000;">&#91;</span>System.Reflection.BindingFlags<span style="color: #000000;">&#93;</span>::CreateInstance<span style="color: pink;">,</span> <span style="color: #800080;">$null</span><span style="color: pink;">,</span> <span style="color: #800080;">$null</span><span style="color: pink;">,</span> <span style="color: #800080;">$null</span><span style="color: pink;">,</span> <span style="color: pink;">@</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#125;</span>
        <span style="color: #800080;">$result</span> <span style="color: pink;">=</span> <span style="color: #800080;">$methodInfo</span>.Invoke<span style="color: #000000;">&#40;</span><span style="color: #800080;">$instance</span><span style="color: pink;">,</span> <span style="color: #800080;">$parameters</span><span style="color: #000000;">&#41;</span>;
    <span style="color: #000000;">&#125;</span>
&nbsp;
   <span style="color: #0000FF;">return</span> <span style="color: #800080;">$result</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://vincenth.net/blog/archive/2009/10/27/call-inline-c-from-powershell-with-invokecsharp.aspx/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Factory Feature –  Create Component</title>
		<link>http://vincenth.net/blog/archive/2009/09/15/factory-feature-%e2%80%93-create-component.aspx</link>
		<comments>http://vincenth.net/blog/archive/2009/09/15/factory-feature-%e2%80%93-create-component.aspx#comments</comments>
		<pubDate>Tue, 15 Sep 2009 15:56:30 +0000</pubDate>
		<dc:creator>Vincent</dc:creator>
				<category><![CDATA[Solutions Factory Features]]></category>

		<guid isPermaLink="false">http://vincenth.net/blog/archive/2009/09/15/factory-feature-%e2%80%93-create-component.aspx</guid>
		<description><![CDATA[With Create Component you can quickly add instances of the sample template components to your existing solution. You simply select the component type and specify the name of the new component; all other actions are automated. The component is created automatically in the correct project and folder, its namespace is set accordingly, and if the [...]]]></description>
			<content:encoded><![CDATA[<p>With Create Component you can quickly add instances of the sample template components to your existing solution. You simply select the component type and specify the name of the new component; all other actions are automated. The component is created automatically in the correct project and folder, its namespace is set accordingly, and if the correct project is not present in the solution it is added on the fly with all correct namespaces, project settings etc.</p>
<p>Create Component is a feature that was added to the <a href="http://solutionsfactory.macaw.nl">Macaw Solutions Factory</a> in version 2.1.</p>
<p style="margin-left: 36pt">Note: there are several series of Macaw Solutions Factory posts, on multiple blogs.<br />
You can read all posts on the <a href="http://solutionsfactory.macaw.nl">Macaw Solutions Factory site</a>, or use <a href="http://app.feed.informer.com/digest3/SX6KV6S6UP.rss"><span style="color: blue; text-decoration: underline;">this feed</span></a><img src="http://vincenth.net/blog/wp-content/uploads/091509_1455_FactoryFeat1.png" alt="" />.</p>
<p>Basically, the Create Components feature allows you to think and work quickly at the logical level when creating components. You do not need to think about which project, folder, project items or settings are needed to implement the component. Instead, all that stuff is generated for you; you can start directly with implementing the component&#8217;s internals.</p>
<p>The Create Component feature only works on MSBuild-based projects, so this feature is not available in the Bts2006 and the Sql2008 or Sql2005 SS*S solutions.</p>
<p>This is how Create Component works in detail:</p>
<ol>
<li>You start by creating a baseline solution with the MAST Solution Builder, by selecting an action in the Factory Guide under &#8216;Create Functional Area&#8217;.<br />
<img src="http://vincenth.net/blog/wp-content/uploads/091509_1455_FactoryFeat2.png" alt="" /><br />
All you need to do now is type the name of the new Functional Area (VS solution), and select which components types (VS projects) the Functional Area should contain initially.<br />
<span style="background-color:yellow">Note</span> that you only need to select the component types (projects) of which you know for sure that you will need them; you can add component types to an existing solution any time you want.<br />
When you click Create, the new solution is built and all namespaces, project settings etc are set to the correct values.After you close the solution builder window, you will be asked whether you want to remove the sample components and sample code from the new solution:<br />
<img src="http://vincenth.net/blog/wp-content/uploads/091509_1455_FactoryFeat3.png" alt="" /></p>
<p>And whether you want to open the new solution:<br />
<img src="http://vincenth.net/blog/wp-content/uploads/091509_1455_FactoryFeat4.png" alt="" /></p>
<p>After you make these choices, the Product.config file will be opened in VS instance where you selected the &#8216;Create Functional Area&#8217; action, and the new Functional Area will be added automatically to the first non-Templates machine role:<br />
<img src="http://vincenth.net/blog/wp-content/uploads/091509_1455_FactoryFeat5.png" alt="" /><br />
If you have more than one machine role – other than Templates &#8211; in your product, you may want to move the Functional Area to a different machine role now.</li>
<li>When the new solution is opened in VS you will see a node &#8216;Create Component&#8217; in the Factory Guide, with a lot of actions in it:<br />
<img src="http://vincenth.net/blog/wp-content/uploads/091509_1455_FactoryFeat6.png" alt="" />In any non-Templates solution these Create Component actions are generated on the fly, based on the Sample components in the Templates Functional Area for the current Product Dependency.<br />
E.g. in the DotNet3Templates.sln you can easily recognize the sample components that correspond to the actions in above screenshot:<br />
<img src="http://vincenth.net/blog/wp-content/uploads/091509_1455_FactoryFeat7.png" alt="" /></p>
<p>For each project item in a template solution whose name starts with &#8216;Sample&#8217;, an action is generated under Create Component. The name of the action specifies both the project name and the component name (without &#8216;Sample&#8217;).<br />
If a template project does not contain any sample components, an action is generated to only add the project to your solution (e.g. &#8216;New OperationalManagement&#8217; in the above screenshot).</p>
<p>You can easily modify the template solutions to change, add or remove sample components. You need to select the &#8220;<em>Refresh &#8216;Create Component&#8217; actions</em>&#8221; action to regenerate the actions after you make this type of changes.</li>
<li>When you execute a Create Component action, you are prompted for the component name and everything else is done automatically:<br />
<img src="http://vincenth.net/blog/wp-content/uploads/091509_1455_FactoryFeat8.png" alt="" /><br />
When you select OK, the component is added and it is opened in the editor:<br />
<img src="http://vincenth.net/blog/wp-content/uploads/091509_1455_FactoryFeat9.png" alt="" />If necessary, the proper project for the new component will be created on the fly. You can see whether this will happen beforehand in the name prompt dialog:<br />
<img src="http://vincenth.net/blog/wp-content/uploads/091509_1455_FactoryFeat10.png" alt="" /><br />
When you select OK, the MAST solution builder window will open and the new project will be created:<br />
<img src="http://vincenth.net/blog/wp-content/uploads/091509_1455_FactoryFeat11.png" alt="" /><br />
As you can see in the log window the solution builder performs a lot of actions automatically, e.g. setting namespaces and project properties, and adding the project target to the FxCop project file for this solution.</p>
<p>When you close the MAST solution builder window, the new component will be added and it is opened in the editor:<br />
<img src="http://vincenth.net/blog/wp-content/uploads/091509_1455_FactoryFeat12.png" alt="" /></p>
<p> </li>
<li>The new component that you added contains example code, to show you a typical implementation pattern.<br />
This sample code is marked with &#8220;region Sample&#8221; and &#8220;endregion Sample&#8221; texts – the exact syntax is specific for the file type (.cs, .xml, .sql, .aspx, .ascx etc.).<br />
If you do not need the sample code, you can quickly remove it from a new component by selecting the Factory Guide action &#8220;Remove Sample Content From Active Document&#8221;:<br />
<img src="http://vincenth.net/blog/wp-content/uploads/091509_1455_FactoryFeat13.png" alt="" /></li>
</ol>
<p>Even though the description of what Create Component does for you is quite long, using it is really quick and simple:</p>
<ol>
<li>Click on the Create Component action for the component type that you want to add</li>
<li>Supply the name for the new component</li>
</ol>
<p>Easy does it. Njoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://vincenth.net/blog/archive/2009/09/15/factory-feature-%e2%80%93-create-component.aspx/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
