<?xml version="1.0" encoding="UTF-8"?><feed
	xmlns="http://www.w3.org/2005/Atom"
	xmlns:thr="http://purl.org/syndication/thread/1.0"
	xml:lang="en-AU"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>
	<title type="text">Krzysztof Koźmic</title>
	<subtitle type="text">on building software and distributed team culture</subtitle>

	<updated>2022-12-18T23:29:10Z</updated>

	<link rel="alternate" type="text/html" href="https://kozmic.net" />
	<id>https://kozmic.net/feed/atom/</id>
	<link rel="self" type="application/atom+xml" href="https://kozmic.net/feed/atom/" />

	<generator uri="https://wordpress.org/" version="6.4.5">WordPress</generator>
<icon>https://i0.wp.com/kozmic.net/wp-content/uploads/2020/09/cropped-myAvatar.png?fit=32%2C32&#038;ssl=1</icon>
	<entry>
		<author>
			<name>Krzysztof</name>
					</author>

		<title type="html"><![CDATA[I&#8217;m on Mastodon &#8211; https://mastodon.au/@kko]]></title>
		<link rel="alternate" type="text/html" href="https://kozmic.net/2022/12/19/im-on-mastodon-https-mastodon-au-kko/" />

		<id>https://kozmic.net/?p=1164</id>
		<updated>2022-12-18T23:29:10Z</updated>
		<published>2022-12-18T23:28:05Z</published>
		<category scheme="https://kozmic.net" term="General" /><category scheme="https://kozmic.net" term="Personal" />
		<summary type="html"><![CDATA[Yes, I&#8217;ve hardly posted here in the last several years. I&#8217;ve been on Twitter since 2008, and in the early years it was complimentary to this blog, but over time more and more discussions migrated over there, from blog comments. It was more engaging, faster flowing and had a lower barrier of entry. It also [&#8230;]]]></summary>

					<content type="html" xml:base="https://kozmic.net/2022/12/19/im-on-mastodon-https-mastodon-au-kko/"><![CDATA[<p>Yes, I&#8217;ve hardly posted here in the last several years. I&#8217;ve been on Twitter since 2008, and in the early years it was complimentary to this blog, but over time more and more discussions migrated over there, from blog comments. It was more engaging, faster flowing and had a lower barrier of entry. It also allowed me to reach and interact with people who never read this blog.</p>
<p>With time, I got less and less active, but still used it daily (with some exceptions and detox periods) in a more passive form, relying heavily on its Lists feature (and TweetDeck client) and DMs.</p>
<p>It was (still is) a tool I value, and more precisely, I value the thoughts and information people who use it choose to share.</p>
<p>Lately, more and more of those people have been either abandoning it, getting kicked out, or at the very least creating a backup on another network, usually <a href="https://en.wikipedia.org/wiki/Mastodon_(social_network)" rel="noopener" target="_blank">Mastodon</a>.</p>
<p>So have I, at <a href="https://mastodon.au/@kko" rel="noopener" target="_blank">https://mastodon.au/@kko</a>. My use remains largely unchanged and passive, but there is some of that vibe that early Twitter had</p>
]]></content>
		
					<link rel="replies" type="text/html" href="https://kozmic.net/2022/12/19/im-on-mastodon-https-mastodon-au-kko/#comments" thr:count="1" />
			<link rel="replies" type="application/atom+xml" href="https://kozmic.net/2022/12/19/im-on-mastodon-https-mastodon-au-kko/feed/atom/" thr:count="1" />
			<thr:total>1</thr:total>
			</entry>
		<entry>
		<author>
			<name>Krzysztof</name>
					</author>

		<title type="html"><![CDATA[Writing better code reviews]]></title>
		<link rel="alternate" type="text/html" href="https://kozmic.net/2020/09/02/writing-better-code-reviews/" />

		<id>http://kozmic.net/?p=1074</id>
		<updated>2020-09-02T01:10:55Z</updated>
		<published>2020-09-02T01:07:55Z</published>
		<category scheme="https://kozmic.net" term="Bookmarks" />
		<summary type="html"><![CDATA[In a distributed team, like ours, Pull Request reviews are one of the main ways we communicate about code. That makes it crucial they are clear, helpful, respectful, concise and actionable. This tweet pointed me to https://conventionalcomments.org/ which is an interesting compendium of tips for how to make them so. I&#8217;m not 100% sold of [&#8230;]]]></summary>

					<content type="html" xml:base="https://kozmic.net/2020/09/02/writing-better-code-reviews/"><![CDATA[<p>In a distributed team, <a href="https://www.sage.com/en-us/ai-labs/" target="_blank" rel="noopener noreferrer">like ours</a>, Pull Request reviews are one of the main ways we communicate about code. That makes it crucial they are clear, helpful, respectful, concise and actionable.</p>
<p>This tweet pointed me to <a href="https://conventionalcomments.org/" target="_blank" rel="noopener noreferrer">https://conventionalcomments.org/</a> which is an interesting compendium of tips for how to make them so.</p>
<p>I&#8217;m not 100% sold of the rigidity it implies (I might have to use the approach for a while to form a stronger opinion), but even ignoring that part, it&#8217;s a good resource, so this post is really little more than a bookmark for me. However, as it might be useful to others, I decided to post it here.</p>
<blockquote class="twitter-tweet" data-dnt="true">
<p dir="ltr" lang="en">I really like getting a code review from someone who uses this. Im going to give it try myself this morning<a href="https://twitter.com/hashtag/git?src=hash&amp;ref_src=twsrc%5Etfw">#git</a> <a href="https://twitter.com/hashtag/codereview?src=hash&amp;ref_src=twsrc%5Etfw">#codereview</a> <a href="https://twitter.com/hashtag/developer?src=hash&amp;ref_src=twsrc%5Etfw">#developer</a> <a href="https://twitter.com/hashtag/programming?src=hash&amp;ref_src=twsrc%5Etfw">#programming</a> <a href="https://t.co/l3HnbHzLS5">https://t.co/l3HnbHzLS5</a></p>
<p>— Linda Lawton <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f1e9-1f1f0.png" alt="🇩🇰" class="wp-smiley" style="height: 1em; max-height: 1em;" /> = <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f970.png" alt="🥰" class="wp-smiley" style="height: 1em; max-height: 1em;" /> (@LindaLawtonDK) <a href="https://twitter.com/LindaLawtonDK/status/1300681156879319040?ref_src=twsrc%5Etfw">September 1, 2020</a></p></blockquote>
]]></content>
		
			</entry>
		<entry>
		<author>
			<name>Krzysztof</name>
					</author>

		<title type="html"><![CDATA[Using Bower and NancyFx together]]></title>
		<link rel="alternate" type="text/html" href="https://kozmic.net/2014/03/25/using-bower-and-nancyfx-together/" />

		<id>http://kozmic.net/?p=917</id>
		<updated>2014-03-25T12:20:31Z</updated>
		<published>2014-03-25T12:19:20Z</published>
		<category scheme="https://kozmic.net" term="Tools" /><category scheme="https://kozmic.net" term="angularjs" /><category scheme="https://kozmic.net" term="bower" /><category scheme="https://kozmic.net" term="nancyfx" />
		<summary type="html"><![CDATA[In .NET land, for package management we&#8217;re pretty much all settled on using Nuget. It&#8217;s close to ubiquitous, which means, that pretty much any .NET open source (or not) library, can be found there. There are a few most popular non-.NET packages too. This category contains mostly JavaScript/CSS libraries, which tend to be used in [&#8230;]]]></summary>

					<content type="html" xml:base="https://kozmic.net/2014/03/25/using-bower-and-nancyfx-together/"><![CDATA[<p>In .NET land, for package management we&#8217;re pretty much all settled on using Nuget. It&#8217;s close to ubiquitous, which means, that pretty much any .NET open source (or not) library, can be found there.</p>
<p>There are a few most popular non-.NET packages too. This category contains mostly JavaScript/CSS libraries, which tend to be used in the front-end of projects using .NET on the backend.</p>
<p>While Nuget is great to help you get your foot in the water of the great and broad JavaScript ecosystem, you&#8217;ll soon find its suffering from a few drawbacks:</p>
<ul>
<li>The JavaScript packages on Nuget only cover a small subset of the ecosystem</li>
<li>The packages on Nuget are usually <em>unofficial</em>, that is maintained by people not affiliated with the projects, and they can lag behind the official releases</li>
</ul>
<p><a href="http://bower.io/">Bower</a> is to web (JavaScript/CSS) packages, what Nuget is to .NET.</p>
<p>On a recent project we used NancyFx to build out .NET backend services, and SPA client (based mostly on AngularJs). We used Nuget for our .NET packages and Bower for the client. This post shows how to set Bower up on Windows, and integrate it into a Nancy project.</p>
<h2>Getting started</h2>
<p>To get Bower you&#8217;ll need to have Node and Git installed. Also make sure both of them are in your <code>PATH</code>. Once this is done simply open your command prompt and type</p>
<blockquote><p>
  <code>npm i -g bower</code>
</p></blockquote>
<p>After this finishes, you can type <code>bower -v</code> to confirm Bower is installed (and see the version)</p>
<p>Once this is done, let&#8217;s open Visual Studio and create a new Nancy Project (I used one of Nancy <a href="http://visualstudiogallery.msdn.microsoft.com/f1e29f61-4dff-4b1e-a14b-6bd0d307611a">Visual Studio Templates</a>)<br />
<a href="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_template.jpg"><img fetchpriority="high" decoding="async" src="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_template.jpg?resize=620%2C346" alt="Nancy Visual Studio Template" width="620" height="346" class="alignnone size-full wp-image-923" srcset="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_template.jpg?w=929&amp;ssl=1 929w, https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_template.jpg?resize=300%2C167&amp;ssl=1 300w" sizes="(max-width: 620px) 100vw, 620px" data-recalc-dims="1" /></a><br />
This will give you a simple starting website.<br />
<a href="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_solution_structure.jpg"><img decoding="async" src="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_solution_structure.jpg?resize=292%2C312" alt="nancy_solution_structure" width="292" height="312" class="alignnone size-full wp-image-922" srcset="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_solution_structure.jpg?w=292&amp;ssl=1 292w, https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_solution_structure.jpg?resize=280%2C300&amp;ssl=1 280w" sizes="(max-width: 292px) 100vw, 292px" data-recalc-dims="1" /></a><br />
For static content, like the .css and .js files Bower manages, the convention in Nancy is to stick them in the <code>/Content</code> folder. (<a href="https://github.com/NancyFx/Nancy/wiki/Managing-static-content">see the doco</a>)</p>
<p>Let&#8217;s try using Bower to fetch Angular. Open your command prompt and make sure you&#8217;re in your solution directory.</p>
<h2>Bower 101</h2>
<p>There really are very few Bower commands you&#8217;ll need</p>
<blockquote><p>
  <code>bower seearch angular</code> will find all matching packages (there are quite  a few)<br />
  <a href="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_bower_search.jpg"><img decoding="async" src="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_bower_search.jpg?resize=620%2C273" alt="Bower serach results for angular" width="620" height="273" class="alignnone size-full wp-image-926" srcset="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_bower_search.jpg?w=677&amp;ssl=1 677w, https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_bower_search.jpg?resize=300%2C132&amp;ssl=1 300w" sizes="(max-width: 620px) 100vw, 620px" data-recalc-dims="1" /></a><br />
  <code>bower install angular</code> will install the package (if you&#8217;re getting errors make sure Git is in your <code>PATH</code>)<br />
  <a href="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_bower_take_one.jpg"><img loading="lazy" decoding="async" src="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_bower_take_one.jpg?resize=620%2C273" alt="bower install angular" width="620" height="273" class="alignnone size-full wp-image-924" srcset="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_bower_take_one.jpg?w=677&amp;ssl=1 677w, https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_bower_take_one.jpg?resize=300%2C132&amp;ssl=1 300w" sizes="(max-width: 620px) 100vw, 620px" data-recalc-dims="1" /></a><br />
  You&#8217;ll notice, however that instead of <code>Content</code> the package is installed into <code>bower_components</code>
</p></blockquote>
<h3>the <code>.bowerrc</code> file</h3>
<p>We can change the default directory where Bower puts the packages by creating a <code>.bowerrc</code> file in our solution directory, and putting the following in it:</p>
<pre class="brush: jscript; title: ; notranslate">
{
  &quot;directory&quot; : &quot;Web/Content&quot;
}
</pre>
<p>Save the file, remove the <code>bower_components</code> folder and let&#8217;s install the package again.</p>
<p><a href="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_bower_take_two.jpg"><img loading="lazy" decoding="async" src="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_bower_take_two.jpg?resize=620%2C273" alt="bower install angular again" width="620" height="273" class="alignnone size-full wp-image-927" srcset="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_bower_take_two.jpg?w=677&amp;ssl=1 677w, https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_bower_take_two.jpg?resize=300%2C132&amp;ssl=1 300w" sizes="(max-width: 620px) 100vw, 620px" data-recalc-dims="1" /></a><br />
Notice this time the package ended up where we told it to.</p>
<p>Bower is agnostic to Visual Studio, so it will not add the packages to your solution. You&#8217;ll need to select <em>Show All Files</em> in Solution Explorer, click on the <code>angular</code> folder and select <em>Include in Project</em>.<br />
<a href="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_bower_visual_studio.jpg"><img loading="lazy" decoding="async" src="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_bower_visual_studio.jpg?resize=291%2C378" alt="angular include in Solution" width="291" height="378" class="alignnone size-full wp-image-925" srcset="https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_bower_visual_studio.jpg?w=291&amp;ssl=1 291w, https://i0.wp.com/kozmic.net/wp-content/uploads/2014/03/nancy_bower_visual_studio.jpg?resize=230%2C300&amp;ssl=1 230w" sizes="(max-width: 291px) 100vw, 291px" data-recalc-dims="1" /></a><br />
The reality is, it took you much longer to read this post, than it will take you to do the tasks described.</p>
<p>This is the approach I&#8217;ve taken and it seems to be working well for us. Do you have a different workflow? Let me know if the comments.</p>
]]></content>
		
					<link rel="replies" type="text/html" href="https://kozmic.net/2014/03/25/using-bower-and-nancyfx-together/#comments" thr:count="2" />
			<link rel="replies" type="application/atom+xml" href="https://kozmic.net/2014/03/25/using-bower-and-nancyfx-together/feed/atom/" thr:count="2" />
			<thr:total>2</thr:total>
			</entry>
		<entry>
		<author>
			<name>Krzysztof</name>
					</author>

		<title type="html"><![CDATA[Strongly typed app settings with Castle DictionaryAdapter]]></title>
		<link rel="alternate" type="text/html" href="https://kozmic.net/2014/03/22/strongly-typed-app-settings-with-castle-dictionaryadapter/" />

		<id>http://kozmic.net/?p=906</id>
		<updated>2014-03-21T23:09:33Z</updated>
		<published>2014-03-21T23:07:53Z</published>
		<category scheme="https://kozmic.net" term=".NET" /><category scheme="https://kozmic.net" term="Castle" /><category scheme="https://kozmic.net" term="Uncategorized" />
		<summary type="html"><![CDATA[A while ago (almost 4 years ago, to be precise) Ben Hall wrote a blogpost about using Castle DictionaryAdapter to build a simple, strongly typed wrapper aroud application settings. While extremely simple, and gets the job done, there are a few ways it can be improved. With that, this blogpost can be treated as an [&#8230;]]]></summary>

					<content type="html" xml:base="https://kozmic.net/2014/03/22/strongly-typed-app-settings-with-castle-dictionaryadapter/"><![CDATA[<p>A while ago (almost 4 years ago, to be precise) Ben Hall <a href="http://blog.benhall.me.uk/2010/07/improving-testability-with-castle/">wrote a blogpost</a> about using Castle DictionaryAdapter to build a simple, strongly typed wrapper aroud application settings.</p>
<p>While extremely simple, and gets the job done, there are a few ways it can be improved. With that, this blogpost can be treated as an introduction to Castle DictionaryAdapter (which sadly has precisely zero documentation).</p>
<p>While the apprpach is really simple, we&#8217;re going to take a detailed look and take it slowly, which is why this post is fairly long. Buckle up.</p>
<h2>What is DictionaryAdapter</h2>
<p>In a nutshell DictionaryAdapter is a simple tool to provide strongly typed wrappers around <code>IDictionary&lt;string , object&gt;</code></p>
<p>Here&#8217;s a simple example:</p>
<pre class="brush: csharp; title: ; notranslate">
// we have a dictionary...
var dictionary = new Dictionary&lt;string, object&gt;
{
	{ &quot;Name&quot;, &quot;Stefan&quot; },
	{ &quot;Age&quot;, 30 }
};

// ...and an adapter factory
factory = new DictionaryAdapterFactory();

// we build the adapter for the dictionary
var adapter = factory.GetAdapter&lt;IPerson&gt;(dictionary);

Debug.Assert(adapter.Name == &quot;Stefan&quot;);
</pre>
<h2>Wrapping app settings</h2>
<p>While the project is called DictionaryAdapter in fact it can do a bit more than just wrap dictionaries (as in <code>IDictionary</code>). It can be used to wrap <code>XmlNode</code>s or <code>NameValueCollection</code>s like <code>Configuration.AppSettings</code> and this last scenario, is what we&#8217;re going to concentrate on.</p>
<h2>The goals</h2>
<p>We&#8217;ve got a few goals in mind for that project:</p>
<ul>
<li>strongly typed &#8211; we don&#8217;t want our settings to be all just <code>string</code>s</li>
<li>grouped &#8211; settings that go together, should come together (think username and password should be part of a single object)</li>
<li>partitioned &#8211; settings that are separate should be separate (think SQL database connection string and Azure service bus url)</li>
<li>fail fast &#8211; when a required setting is missing we want to know ASAP, not much later, deep in the codebase when we first try to use it</li>
<li>simple to use &#8211; we want the junior developer who joins the team next week to be able to use it properly.</li>
</ul>
<p>With that in mind, let&#8217;s get to it.</p>
<h3>Getting started</h3>
<p>DictionaryAdapter lives in <code>Castle.Core</code> (just like DynamicProxy), so to get started we need to get the package from Nuget:</p>
<blockquote><p>
  Install-Package Castle.Core
</p></blockquote>
<p>Once this is done and you&#8217;re not using Resharper make sure to add <code>using Castle.Components.DictionaryAdapter;</code> to make the right types available.</p>
<h3>The config file</h3>
<p>Here&#8217;s our config file, we&#8217;ll be dealing with. Notice it follows a simple naming convention with prefixes to make it easy to group common settings together. This is based on a real project.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;configuration&gt;
  &lt;appSettings&gt;
    &lt;add key=&quot;environment-type&quot; value=&quot;Local&quot; /&gt;
    &lt;add key=&quot;environment-log-minimum-level&quot; value=&quot;Debug&quot; /&gt;
    &lt;add key=&quot;auth0-client-id&quot; value=&quot;abc123abc&quot; /&gt;
    &lt;add key=&quot;auth0-client-secret&quot; value=&quot;123abc123abc&quot; /&gt;
    &lt;add key=&quot;auth0-domain&quot; value=&quot;abc123.auth0.com&quot; /&gt;
    &lt;add key=&quot;auth0-database-connection-name&quot; value=&quot;ABC123&quot; /&gt;
    &lt;add key=&quot;auth0-token-expiration-seconds&quot; value=&quot;3600&quot; /&gt;
  &lt;/appSettings&gt;
&lt;/configuration&gt;
</pre>
<p>As you can see we have two sets of settings here. One for general environment configuration, and another one for integration with <a href="https://auth0.com/">Auth0</a>.</p>
<h3>Config interfaces</h3>
<p>Now let&#8217;s proceed to creating our interfaces, exposing the configuration values to our application. We follow a naming convention where the name of config value corresponds to type/property on the interface. This makes it trivial to see which config value maps to which property on which interface.</p>
<p>For clarity I&#8217;d also recommend putting the interfaces in a designated namespace, like <code>MyApp.Configuration</code>.</p>
<pre class="brush: csharp; title: ; notranslate">
public interface IEnvironment
{
    EnvironmentType Type { get; }
    LogEventLevel LogMinimumLevel { get; }
}

public interface IAuth0
{
    string ClientId { get; }
    string ClientSecret { get; }
    string Domain { get; }
    string DatabaseConnectionName { get; }
    int TokenExpirationSeconds { get; }
}
</pre>
<p>Having the interfaces and the config we can start writing the code to put the two together</p>
<h2>Bare minimum</h2>
<p>Let&#8217;s rewrite the code from the beginning of the post to use our config file and interfaces. If you&#8217;re not using Resharper you&#8217;ll have to manually add a reference to <code>System.Configuration.dll</code> for the following to work.</p>
<pre class="brush: csharp; title: ; notranslate">
var factory = new DictionaryAdapterFactory();

var environment = factory.GetAdapter&lt;IEnvironment&gt;(ConfigurationManager.AppSettings);

Debug.Assert(environment.Type == EnvironmentType.Local);
</pre>
<p>If we run it now, we&#8217;ll get a failure. DictionaryAdapter doesn&#8217;t know about our naming convention, so we have to teach it how to map the type/property to a config value.</p>
<h2>Implementing <code>DictionaryBehaviorAttribute</code></h2>
<p>There are two ways to customise how DictionaryAdapter operates.</p>
<ul>
<li>Transparent, using an overload to <code>GetAdapter</code> and passing a <code>PropertyDescriptor</code> with customisations there.</li>
<li>
<p>Declarative, using attributes on the adapter interfaces to specify the desired behaviour. If you&#8217;ve used Action Filters in ASP.NET MVC, it will feel familiar.</p>
</li>
</ul>
<p>In this example we&#8217;re going to use the latter. To begin, we need to create a new attribute, inheriting from <code>DictionaryBehaviorAttribute</code>, and apply it to our two interfaces</p>
<pre class="brush: csharp; title: ; notranslate">
public class AppSettingWrapperAttribute : DictionaryBehaviorAttribute, IDictionaryKeyBuilder
{
    private readonly Regex converter = new Regex(&quot;(&#x5B;A-Z])&quot;, RegexOptions.Compiled);

    public string GetKey(IDictionaryAdapter dictionaryAdapter, string key, PropertyDescriptor property)
    {
        var name = dictionaryAdapter.Meta.Type.Name.Remove(0, 1) + key;
        var adjustedKey = converter.Replace(name, &quot;-$1&quot;).Trim('-');
        return adjustedKey;
    }
}
</pre>
<p>We create the attribute and implement <code>IDictionaryKeyBuilder</code> interface, which tells DictionaryAdapter we want to have a say at mapping the property to a proper key in the dictionary. Using a trivial regular expression we map <code>NameLikeThis</code> to <code>Name-Like-This</code>.</p>
<p>Having done that, if we run the application again, the assertion will pass.</p>
<h2>Fail Fast</h2>
<p>If we remove the <code>environment-log-minimum-level</code> setting from the config file, and run the app again, it will still pass just fine. In fact, since <code>LogEventLevel</code> (which comes from Serilog logging framework) in an enum, therefore a value type, if we read the property everything will seem to have worked just fine. A default value for the enum will be returned.</p>
<p>This is not the behaviour that we want. We want to fail fast, that is if the value is not present or not valid, we want to know. To do it, we need two modifications to our <code>AppSettingWrapperAttribute</code></p>
<h3>Eager fetching</h3>
<p>First we want the adapter to eagerly fetch values for every property on the interface. That way if something is wrong, we&#8217;ll know, even before we try to access the property in our code.</p>
<p>To do that, we implement one more interface &#8211; <code>IPropertyDescriptorInitializer</code>. It comes with a single method, which we implement as follows:</p>
<pre class="brush: csharp; title: ; notranslate">
public void Initialize(PropertyDescriptor propertyDescriptor, object&#x5B;] behaviors)
{
    propertyDescriptor.Fetch = true;
}
</pre>
<h3>Validating missing properties</h3>
<p>To ensure that each setting has a value, we need to insert some code into the process of reading the values from the dictionary. To do that, there is another interface we need to implement: <code>IDictionaryPropertyGetter</code>. This will allow us to inspect the value that has been read, and throw a helpful exception if there is no value.</p>
<pre class="brush: csharp; title: ; notranslate">
public object GetPropertyValue(IDictionaryAdapter dictionaryAdapter, string key, object storedValue, PropertyDescriptor property, bool ifExists)
{
    if (storedValue != null) return storedValue;
    throw new InvalidOperationException(string.Format(&quot;App setting \&quot;{0}\&quot; not found!&quot;, key.ToLowerInvariant()));
}
</pre>
<p>If we run the app now, we&#8217;ll see that it fails, as we expect, telling us that we forgot to set <code>environment-log-minimum-level</code> in our config file.</p>
<h2>Wrapping up</h2>
<p>That&#8217;s it. Single attribute and a minimal amount of bootstrap code is all that&#8217;s needed to get nice, simple to use wrappers around application settings.</p>
<p>Additional bonus is, that this is trivial to integrate with your favourite IoC container.</p>
<p>All code is available in <a href="https://gist.github.com/kkozmic/7858f4e666df223e7fc4">this gist</a>.</p>
]]></content>
		
					<link rel="replies" type="text/html" href="https://kozmic.net/2014/03/22/strongly-typed-app-settings-with-castle-dictionaryadapter/#comments" thr:count="2" />
			<link rel="replies" type="application/atom+xml" href="https://kozmic.net/2014/03/22/strongly-typed-app-settings-with-castle-dictionaryadapter/feed/atom/" thr:count="2" />
			<thr:total>2</thr:total>
			</entry>
		<entry>
		<author>
			<name>Krzysztof</name>
					</author>

		<title type="html"><![CDATA[On C# dynamic and calling base type&#8217;s methods]]></title>
		<link rel="alternate" type="text/html" href="https://kozmic.net/2013/11/27/on-c-dynamic-and-calling-base-types-methods/" />

		<id>http://kozmic.net/?p=887</id>
		<updated>2013-11-27T12:18:05Z</updated>
		<published>2013-11-27T12:14:26Z</published>
		<category scheme="https://kozmic.net" term="c#" />
		<summary type="html"><![CDATA[The dynamic keyword has been part of the C# language for quite a while now. I thought I know it well, yet I stumbled upon an interesting case that surprised me. The code that works Here&#8217;s a piece of code that I started with. This code works like you would expect. public interface ICanQuack { [&#8230;]]]></summary>

					<content type="html" xml:base="https://kozmic.net/2013/11/27/on-c-dynamic-and-calling-base-types-methods/"><![CDATA[<p>The dynamic keyword has been part of the C# language for quite a while now. I thought I know it well, yet I stumbled upon an interesting case that surprised me.</p>
<h3>The code that works</h3>
<p>Here&#8217;s a piece of code that I started with. This code works like you would expect.</p>
<pre class="brush: csharp; title: ; notranslate">
public interface ICanQuack
{
    void Fly&lt;T&gt;(T map);
    void Quack();
}

public class Duck : ICanQuack
{
    public void Fly&lt;T&gt;(T map)
    {
        Console.WriteLine(&quot;Flying using a {0} map ({1})&quot;, typeof (T).Name, map);
    }

    public void Quack()
    {
        Console.WriteLine(&quot;Quack Quack!&quot;);
    }
}

class Program
{
    private static ICanQuack quack;
    private static void Main(string&#x5B;] args)
    {
        SetUpQuack();

        var map = GetMap();

        quack.Fly((dynamic)map);

        Console.ReadKey(true);
    }

    private static void SetUpQuack()
    {
        quack = new Duck();
    }

    private static object GetMap()
    {
        return &quot;a map&quot;;
    }
}
</pre>
<p>Notice the use of <code>dynamic</code> to resolve the generic method type parameter at runtime. This code works and, as you probably guessed, prints:</p>
<blockquote><p>Flying using a String map (a map)</p></blockquote>
<h3>The innocent change that broke it</h3>
<p>Now, even though it&#8217;s a completely made up example instead of the real code, flying is something not just ducks do, so let&#8217;s extract an interface <code>ICanFly</code></p>
<pre class="brush: csharp; title: ; notranslate">
public interface ICanFly
{
    void Fly&lt;T&gt;(T map);
}

public interface ICanQuack : ICanFly
{
    void Quack();
}
</pre>
<p>Rest of the code stays the same.</p>
<p>Looks innocent enough right? Except it just broke out code. It we run it now we&#8217;ll get the following error<br />
<img loading="lazy" decoding="async" class="alignnone size-full wp-image-889" alt="Error" src="https://i0.wp.com/kozmic.net/wp-content/uploads/2013/11/dynamic_error1.jpg?resize=452%2C413" width="452" height="413" data-recalc-dims="1" /></p>
<h3>What happened</h3>
<p>Well, to be honest, I&#8217;m not quite sure I have a good explanation for the behaviour. Like I said, I was surprised myself that this code stops working now. When you use the <code>dynamic</code> keyword C# compiler tries to use all the information it has at compile time, to optimise the code it generates to support the dynamic invocation, so that it has less work to do at runtime. In this case, by definition, everything that implements <code>ICanQuack</code> also implements <code>ICanFly</code> but the binder seems to not bother checking the base interface. I&#8217;m sure <a href="http://msmvps.com/blogs/jon_skeet/" target="_blank">Jon Skeet</a> has a perfectly good explanation for it.</p>
<h3>How to <em>fix</em><em> it</em></h3>
<p>The exception message points us pretty clearly towards the problem &#8211; the runtime binder uses the static type information about <code>ICanQuack</code> to find the <code>Fly</code> method. Since the method is defined on the <code>ICanFly</code> interface, we need to give the binder a hint that <code>ICanFly</code> is where it should look.</p>
<p>To do that, we need to change the following code</p>
<pre class="brush: csharp; title: ; notranslate">
quack.Fly((dynamic)map);
</pre>
<p>into a bit uglier (but working!):</p>
<pre class="brush: csharp; title: ; notranslate">
((ICanFly)quack).Fly((dynamic)map);
</pre>
]]></content>
		
			</entry>
		<entry>
		<author>
			<name>Krzysztof</name>
					</author>

		<title type="html"><![CDATA[On strongly typed application settings with Castle DictionaryAdapter]]></title>
		<link rel="alternate" type="text/html" href="https://kozmic.net/2013/11/21/on-strongly-typed-application-settings-with-castle-dictionaryadapter/" />

		<id>http://kozmic.net/?p=875</id>
		<updated>2013-11-21T22:55:44Z</updated>
		<published>2013-11-21T11:50:58Z</published>
		<category scheme="https://kozmic.net" term=".NET" /><category scheme="https://kozmic.net" term="Castle" />
		<summary type="html"><![CDATA[Every non-trivial .NET application ends up using configuration file for its settings. It&#8217;s the standard mechanism that&#8217;s fairly well adopted across the community. That doesn&#8217;t mean however, that it&#8217;s simple to deal with. There have been many various approaches to dealing with the problem, including some from Microsoft. There are a few open source ones, [&#8230;]]]></summary>

					<content type="html" xml:base="https://kozmic.net/2013/11/21/on-strongly-typed-application-settings-with-castle-dictionaryadapter/"><![CDATA[<p>Every non-trivial .NET application ends up using configuration file for its settings. It&#8217;s the standard mechanism that&#8217;s fairly well adopted across the community. That doesn&#8217;t mean however, that it&#8217;s simple to deal with.</p>
<p>There have been many various approaches to dealing with the problem, including <a href="http://msdn.microsoft.com/en-us/library/wabtadw6%28v=vs.110%29.aspx" target="_blank">some from Microsoft</a>. There are a few open source ones, including <a href="https://github.com/uglybugger/ConfigInjector" target="_blank">one from my colleague, Andrew</a>.</p>
<h3>Yet another (not even original) approach</h3>
<p>This brings us to Castle DictionaryAdapter. Part of the Castle project that never got much traction, partially to poor (read non-existent) documentation. Somewhat similar to DynamicProxy, DictionaryAdapter concentrates on dynamically generating strongly typed wrappers around dictionaries or XML. The idea of using it for wrapping configuration values is not new. <a href="http://codebetter.com/benhall/2010/07/22/improving-testability-with-the-castle-dictionary-adapter/" target="_blank">Ben blogged about it</a> a few years ago, and I always liked the simplicity and readability of the approach, and how little effort it required.</p>
<p>I started working on a project recently, that has a whole bunch of different sets of config values, which led me to adding some small improvements to the approach.</p>
<h3>Not just one big Config God Object</h3>
<p>One common mistake (regardless of the approach) is that all the unrelated settings end up in a single massive configuration <a href="http://en.wikipedia.org/wiki/God_object" target="_blank">God Object</a>. There is nothing inherent about the DictionaryAdapter approach forcing you to go down that path. You can split your configuration logically across a few configuration interfaces</p>
<pre class="brush: csharp; title: ; notranslate">
public interface SmtpConfiguration
{
    string Name { get; set; }
    int Port { get; set; }
}

public interface SomeOtherConfig
{
    //stuff
}

// and in the config file:
</pre>
<pre class="brush: xml; title: ; notranslate">
&lt;appSettings&gt;
    &lt;add key=&quot;name&quot; value=&quot;value&quot; /&gt;
    &lt;add key=&quot;port&quot; value=&quot;25&quot;/&gt;
    &lt;!--  stuff --&gt;
&lt;/appSettings&gt;
</pre>
<p>Taking it a bit further, we might explicitly partition the values using prefixes:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;appSettings&gt;
    &lt;add key=&quot;smtp:name&quot; value=&quot;value&quot; /&gt;
    &lt;add key=&quot;smtp:port&quot; value=&quot;25&quot;/&gt;
    &lt;add key=&quot;stuff:something&quot; value=&quot;bla&quot;/&gt;
    &lt;!--  other stuff --&gt;
&lt;/appSettings&gt;
</pre>
<p>DictionaryAdapter knows how to properly resolve prefixed values using <code>KeyPrefixAttribute</code>.</p>
<pre class="brush: csharp; title: ; notranslate">
&#x5B;KeyPrefix(&quot;smtp:&quot;)]
public interface SmtpConfiguration
{
    string Name { get; set; }
    int Port { get; set; }
}
</pre>
<h3>Fail fast</h3>
<p>One other missing big, is shortening the feedback loop. We don&#8217;t want to learn we have an invalid or missing value at some later point in the application&#8217;s lifecycle when we try to read it for the first time. We want to know about it as soon as possible. Preferably, when the application starts up (and in a test).</p>
<p>The first problem, we could solve with <code>FetchAttribute</code> Which forces a property to be read when the adapter is constructed, therefore forcing exception in cases where, for example, your property is of type <code>TimeSpan</code> but your config value is not a valid representation of time span.</p>
<p>To solve the other problem we need a little bit of code. In fact, to simplify things, we can merge that with what <code>KeyPrefixAttribute</code> and <code>FetchAttribute</code> provide, to have all the functionality we need in a single type.</p>
<pre class="brush: csharp; title: ; notranslate">
public class AppSettingsAttribute : KeyPrefixAttribute, IDictionaryPropertyGetter, IPropertyDescriptorInitializer
{
    public AppSettingsAttribute(string keyPrefix) : base(keyPrefix)
    {
    }

    public object GetPropertyValue(IDictionaryAdapter dictionaryAdapter, string key, object storedValue,
        PropertyDescriptor property, bool ifExists)
    {
        if (storedValue == null &amp;&amp; IsRequired(ifExists))
        {
            throw new ArgumentException(&quot;No valid value for '&quot; + key + &quot;' found&quot;);
        }
        return storedValue;
    }

    public void Initialize(PropertyDescriptor propertyDescriptor, object&#x5B;] behaviors)
    {
        propertyDescriptor.Fetch = true;
    }

    private static bool IsRequired(bool ifExists)
    {
        return ifExists == false;
    }
}
</pre>
<p>Now our configuration interface changes to:</p>
<pre class="brush: csharp; title: ; notranslate">
&#x5B;AppSettings(&quot;smtp:&quot;)]
public interface SmtpConfiguration
{
    string Name { get; set; }
    int Port { get; set; }
}
</pre>
<p>Not only do we get a nice, readable, testable strongly typed access to our settings, that can easily be put in an IoC container. We also are going to get an early exception if we put an invalid value in the config, or we forget about doing it at all.</p>
<p>The full code is <a href="https://gist.github.com/kkozmic/7580276" target="_blank">on github</a>.</p>
]]></content>
		
			</entry>
		<entry>
		<author>
			<name>Krzysztof</name>
					</author>

		<title type="html"><![CDATA[On Castle Windsor and open generic component arity]]></title>
		<link rel="alternate" type="text/html" href="https://kozmic.net/2013/07/24/on-castle-windsor-and-open-generic-component-arity/" />

		<id>http://kozmic.net/?p=861</id>
		<updated>2013-07-24T10:55:32Z</updated>
		<published>2013-07-24T10:51:43Z</published>
		<category scheme="https://kozmic.net" term=".NET" /><category scheme="https://kozmic.net" term="Castle" /><category scheme="https://kozmic.net" term="Windsor" />
		<summary type="html"><![CDATA[In the previous post I said there&#8217;s one more new feature in Windsor 3.2 related to open generic components. Take the following class for example: public class Foo&#60;T, T2&#62; : IFoo&#60;T&#62; { } Notice it has arity of 2 (two generic parameters, T and T2) and the interface it implements has arity of 1. If [&#8230;]]]></summary>

					<content type="html" xml:base="https://kozmic.net/2013/07/24/on-castle-windsor-and-open-generic-component-arity/"><![CDATA[<p>In the <a href="http://kozmic.net/2013/07/23/on-castle-windsor-and-open-generic-components/">previous post</a> I said there&#8217;s one more new feature in Windsor 3.2 related to open generic components.</p>
<p>Take the following class for example:</p>
<pre class="brush: csharp; title: ; notranslate">
public class Foo&lt;T, T2&gt; : IFoo&lt;T&gt;
{
}
</pre>
<p>Notice it has arity of 2 (two generic parameters, <code>T</code> and <code>T2</code>) and the interface it implements has arity of 1.<br />
If we have a generic component for this class what should be supplied for <code>T2</code> when we want to use it as <code>IFoo&lt;Bar&gt;</code>?</p>
<p>By default, if we just register the component and then try to use it we&#8217;ll be greeted with an exception like the following:</p>
<blockquote><p>Requested type GenericsAndWindsor.IFoo`1[GenericsAndWindsor.Bar] has 1 generic parameter(s), whereas component implementation type GenericsAndWindsor.Foo`2[T,T2] requires 2.<br />
This means that Windsor does not have enough information to properly create that component for you.<br />
You can instruct Windsor which types it should use to close this generic component by supplying an implementation of IGenericImplementationMatchingStrategy.<br />
Please consut the documentation for examples of how to do that.</p></blockquote>
<h3>Specifying implementation generic arguments: IGenericImplementationMatchingStrategy</h3>
<p>The <code>IGenericImplementationMatchingStrategy</code> interface allows you to plug in your own logic telling Windsor how to close the implementation type for a given requested service. The following trivial implementation simply uses <code>string</code> for the other argument, therefore allowing the component to be successfully constructed.</p>
<pre class="brush: csharp; title: ; notranslate">
public class UseStringGenericStrategy : IGenericImplementationMatchingStrategy
{
	public Type&#x5B;] GetGenericArguments(ComponentModel model, CreationContext context)
	{
		return new&#x5B;]
		{
			context.RequestedType.GetGenericArguments().Single(),
			typeof (string)
		};
	}
}
</pre>
<p>The contract is quite simple, given a <code>ComponentModel</code> and  <code>CreationContext</code> (which will tell you what the requested closed type is) you return the right types to use for generic arguments when closing the implementation type of the <code>model</code>.</p>
<p>You hook it up in exactly the same way as <code>IGenericServiceStrategy</code> (and yes, there&#8217;s an overload that allows you to specify both).</p>
<pre class="brush: csharp; title: ; notranslate">
container.Register(Component.For(typeof (IFoo&lt;&gt;))
	.ImplementedBy(typeof (Foo&lt;,&gt;), new UseStringGenericStrategy())
	.LifestyleTransient());
</pre>
<p>Now the service will resolve successfully.<br />
<a href="https://i0.wp.com/kozmic.net/wp-content/uploads/2013/07/Screen-Shot-2013-07-24-at-8.42.36-PM.png"><img loading="lazy" decoding="async" src="https://i0.wp.com/kozmic.net/wp-content/uploads/2013/07/Screen-Shot-2013-07-24-at-8.42.36-PM.png?resize=470%2C41" alt="Generic component resolved" width="470" height="41" class="alignnone size-full wp-image-865" srcset="https://i0.wp.com/kozmic.net/wp-content/uploads/2013/07/Screen-Shot-2013-07-24-at-8.42.36-PM.png?w=470&amp;ssl=1 470w, https://i0.wp.com/kozmic.net/wp-content/uploads/2013/07/Screen-Shot-2013-07-24-at-8.42.36-PM.png?resize=300%2C26&amp;ssl=1 300w" sizes="(max-width: 470px) 100vw, 470px" data-recalc-dims="1" /></a></p>
]]></content>
		
			</entry>
		<entry>
		<author>
			<name>Krzysztof</name>
					</author>

		<title type="html"><![CDATA[On Castle Windsor and open generic components]]></title>
		<link rel="alternate" type="text/html" href="https://kozmic.net/2013/07/23/on-castle-windsor-and-open-generic-components/" />

		<id>http://kozmic.net/?p=853</id>
		<updated>2018-10-11T22:25:19Z</updated>
		<published>2013-07-23T11:27:48Z</published>
		<category scheme="https://kozmic.net" term="Castle" /><category scheme="https://kozmic.net" term="Windsor" />
		<summary type="html"><![CDATA[While Windsor supported open generics components since pretty much forever, there&#8217;s been some improvements in version 3.2 that I haven&#8217;t blogged about yet, but which can be pretty useful in some advanced scenarios. I&#8217;ll cover them in this and future blogpost. Just so we&#8217;re clear &#8211; what are open generic components? So what are open [&#8230;]]]></summary>

					<content type="html" xml:base="https://kozmic.net/2013/07/23/on-castle-windsor-and-open-generic-components/"><![CDATA[<p>While Windsor supported open generics components since pretty much forever, there&#8217;s been some improvements in version 3.2 that I haven&#8217;t blogged about yet, but which can be pretty useful in some advanced scenarios. I&#8217;ll cover them in this and future blogpost.</p>
<h3>Just so we&#8217;re clear &#8211; what are open generic components?</h3>
<p>So what are open generic components? Components based on a generic type where we don&#8217;t specify the generic arguments. Like the following:</p>
<pre class="brush: csharp; title: ; notranslate">
// register
container.Register(Component.For(typeof (IFoo&lt;&gt;))
	.ImplementedBy(typeof (Foo&lt;&gt;))
	.LifestyleTransient());

// will provide IFoo&lt;Bar&gt;, IFoo&lt;Baz&gt;, IFoo&lt;any_valid_type&gt;
</pre>
<p>In this case we say that the component provides <code>IFoo<></code> closed over <code>Bar</code>, <code>Baz</code> etc</p>
<h3>Being picky about what we&#8217;re closing over: IGenericServiceStrategy</h3>
<p>Sometimes we want to restrict the types we want our components to support. C# language allows us to use generic constraints to specify that, and Windsor will obviously respect that, but sometimes we need to go beyond what language provides.</p>
<p>One realistic example might be restricting to specific types from a given assembly, like in <a href="http://stackoverflow.com/questions/17795982/how-can-i-simplify-the-registration-of-a-large-set-of-closed-generic-versions-of">this StackOverflow question</a>.</p>
<p>Windsor 3.2 has a new hook point for just that &#8211; <code>IGenericServiceStrategy</code>, which allows you to plug custom logic to specify whether you want a component to support a given closed version of its open generic service.</p>
<p>Here&#8217;s a sample implementation limiting to types from a single assembly:</p>
<pre class="brush: csharp; title: ; notranslate">
public class OnlyFromAssemblyStrategy : IGenericServiceStrategy
{
	private readonly Assembly assembly;

	public OnlyFromAssemblyStrategy(Assembly assembly)
	{
		this.assembly = assembly;
	}

	public bool Supports(Type service, ComponentModel component)
	{
		return service.GetGenericArguments().Single().Assembly == assembly;
	}
}
</pre>
<p>To hook the strategy:</p>
<pre class="brush: csharp; title: ; notranslate">
container.Register(Component.For(typeof (IFoo&lt;&gt;))
	.ImplementedBy(typeof (Foo&lt;&gt;), new OnlyFromAssemblyStrategy(someAsembly))
	.LifestyleTransient());
</pre>
<p>Now when you need <code>IFoo&lt;SomeTypeFromWrongAssembly&gt;</code> either another component will need to supply it, or the dependency will not be satisfied (which, if the dependency is not optional, will result in exception).<br />
<a href="https://i0.wp.com/kozmic.net/wp-content/uploads/2013/07/exception.jpeg"><img loading="lazy" decoding="async" src="https://i0.wp.com/kozmic.net/wp-content/uploads/2013/07/exception.jpeg?resize=447%2C401" alt="Component Not Found exception" width="447" height="401" class="alignnone size-full wp-image-856" srcset="https://i0.wp.com/kozmic.net/wp-content/uploads/2013/07/exception.jpeg?w=447&amp;ssl=1 447w, https://i0.wp.com/kozmic.net/wp-content/uploads/2013/07/exception.jpeg?resize=300%2C269&amp;ssl=1 300w" sizes="(max-width: 447px) 100vw, 447px" data-recalc-dims="1" /></a></p>
]]></content>
		
			</entry>
		<entry>
		<author>
			<name>Krzysztof</name>
					</author>

		<title type="html"><![CDATA[On Nuget, Git and unignoring packages]]></title>
		<link rel="alternate" type="text/html" href="https://kozmic.net/2013/05/23/on-nuget-git-and-unignoring-packages/" />

		<id>http://kozmic.net/?p=837</id>
		<updated>2013-05-23T01:56:22Z</updated>
		<published>2013-05-23T01:54:57Z</published>
		<category scheme="https://kozmic.net" term=".NET" /><category scheme="https://kozmic.net" term="Git" /><category scheme="https://kozmic.net" term="git" /><category scheme="https://kozmic.net" term="Nuget" />
		<summary type="html"><![CDATA[Git has a helpful ability to ignore certain files. When working on .net projects, you normally want to ignore your .suo file, bin and obj folders etc. If you&#8217;re using the excellent GitExtensions it will even provide a default, reasonable .gitignore file for you. Problem is, that while you want to ignore certain patterns in [&#8230;]]]></summary>

					<content type="html" xml:base="https://kozmic.net/2013/05/23/on-nuget-git-and-unignoring-packages/"><![CDATA[<p>Git has a helpful ability to ignore certain files. When working on .net projects, you normally want to ignore your .suo file, bin and obj folders etc.</p>
<p>If you&#8217;re using the excellent GitExtensions it will even provide a default, reasonable .gitignore file for you.</p>
<p>Problem is, that while you want to ignore certain patterns in most of your project, generally you want none of those rules to apply to your nuget packages.</p>
<p>Everything in packages folder should be committed. Always. No exceptions.</p>
<p>To do that, you need to leverage a child .gitignore file.</p>
<p>Create a .gitignore file inside your packages folder and add the following line to it:</p>
<pre>!*</pre>
<p>This tells Git to disregard any ignore rules of the parent file. Now all your packages will be committed completely, without missing any of their functionality.</p>
]]></content>
		
					<link rel="replies" type="text/html" href="https://kozmic.net/2013/05/23/on-nuget-git-and-unignoring-packages/#comments" thr:count="11" />
			<link rel="replies" type="application/atom+xml" href="https://kozmic.net/2013/05/23/on-nuget-git-and-unignoring-packages/feed/atom/" thr:count="11" />
			<thr:total>11</thr:total>
			</entry>
		<entry>
		<author>
			<name>Krzysztof</name>
					</author>

		<title type="html"><![CDATA[On Windsor 3.2 release]]></title>
		<link rel="alternate" type="text/html" href="https://kozmic.net/2013/02/17/on-windsor-3-2-release/" />

		<id>http://kozmic.net/?p=826</id>
		<updated>2013-02-17T10:10:56Z</updated>
		<published>2013-02-16T22:39:15Z</published>
		<category scheme="https://kozmic.net" term="Castle" /><category scheme="https://kozmic.net" term="Windsor" /><category scheme="https://kozmic.net" term="release" />
		<summary type="html"><![CDATA[Windsor 3.2 release is now live on nuget and sourceforge. This release is mostly about bugfixes and incremental improvements and while some breaking changes were made, for vast majority of users this will be a drop-in update. The highlights of the release are in the documentation, so I won&#8217;t repeat them here. End of an era [&#8230;]]]></summary>

					<content type="html" xml:base="https://kozmic.net/2013/02/17/on-windsor-3-2-release/"><![CDATA[<p>Windsor 3.2 release is now live on <a title="Windsor on nuget" href="http://nuget.org/packages/castle.Windsor" target="_blank">nuget</a> and <a title="Windsor on SourceForge" href="https://sourceforge.net/projects/castleproject/files/latest/download" target="_blank">sourceforge</a>.</p>
<p>This release is mostly about bugfixes and incremental improvements and while some breaking changes were made, for vast majority of users this will be a drop-in update.</p>
<p>The highlights of the release <a title="What's new in Windsor 3.2" href="http://docs.castleproject.org/Windsor.Whats-New-In-Windsor-32.ashx" target="_blank">are in the documentation</a>, so I won&#8217;t repeat them here.</p>
<h3>End of an era</h3>
<p>It is the last release to support .NET 3.5 and Silverlight.</p>
<p>Also, I&#8217;m thinking of sunsetting (such a nice word) Remoting facility, Factory Support facility (the one that allows you to specify factory method via XML, not to be confused with Typed Factory facility), Event Wiring facility and Synchronize facility.</p>
<p>Obviously, Windsor being a community driven project, if someone wants to step in and take over any of these facilities we&#8217;ll keep updating them. Otherwise this will likely be their last release.</p>
]]></content>
		
					<link rel="replies" type="text/html" href="https://kozmic.net/2013/02/17/on-windsor-3-2-release/#comments" thr:count="3" />
			<link rel="replies" type="application/atom+xml" href="https://kozmic.net/2013/02/17/on-windsor-3-2-release/feed/atom/" thr:count="3" />
			<thr:total>3</thr:total>
			</entry>
	</feed>
