<?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>Tech Talk - Driessen HRM _ Payroll &#187; .NET</title>
	<atom:link href="http://www.driessen.nl/techtalk/category/net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.driessen.nl/techtalk</link>
	<description>Techtalk over Driessen HRM _ Payroll</description>
	<lastBuildDate>Fri, 12 Aug 2011 14:29:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Multi UI-platform Model View Presenter</title>
		<link>http://www.driessen.nl/techtalk/model-view-presenter-in-windows-forms/</link>
		<comments>http://www.driessen.nl/techtalk/model-view-presenter-in-windows-forms/#comments</comments>
		<pubDate>Tue, 29 Mar 2011 10:10:18 +0000</pubDate>
		<dc:creator>Randy Keyers</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Algemeen]]></category>

		<guid isPermaLink="false">http://www.driessen.nl/techtalk/?p=1107</guid>
		<description><![CDATA[Er is inmiddels een vrijwel onuitputtelijke lijst met programmeermodellen: MVP, MVC, MVVM, MVPP enzovoorts. Allemaal met hun eigen voors- en tegens. RAP wordt op dit moment gebouwd op basis van MVC (Model View Controller), de overige (wat meer data-entry) applicaties worden gebouwd op MVP (Model View Presenter). Maar dan ECHT multi UI platform, met behulp van ons [...]]]></description>
			<content:encoded><![CDATA[<p>Er is inmiddels een vrijwel onuitputtelijke lijst met programmeermodellen: MVP, MVC, MVVM, MVPP enzovoorts. Allemaal met hun eigen voors- en tegens.<br />
RAP wordt op dit moment gebouwd op basis van MVC (Model View Controller), de overige (wat meer data-entry) applicaties worden gebouwd op MVP (Model View Presenter). Maar dan ECHT multi UI platform, met behulp van ons Driessen framework.<span id="more-1107"></span></p>
<p>Voor degenen voor wie het niet duidelijk is wat Model View Presenter doet, zal ik het even toelichten.</p>
<p><strong>Model</strong> staat voor het Model Domain: Het (business) probleem dat je op probeert te lossen.<br />
<strong>View</strong> staat voor de UI waarmee je met de gebruiker gaat communiceren.<br />
<strong>Presenter</strong> staat voor de laag tussen die je Model fysiek van de View scheidt. Deze laag zorgt ervoor dat je Model niet afhankelijk is van je UI. In de praktijk blijkt deze laag ook uitermate geschikt voor unittesting. Je bent immers niet langer afhankelijk van je UI om je businesslogic te kunnen testen.</p>
<p>In de praktijk zal bestaat het Model vaak uit een of meer data entiteiten en businessrules. De view bestaat uit een interface die de mogelijkheden die de UI heeft omschrijft. De UI (Windows/WPF/Silverlight/Web/???) implementeert de view interface. De presenter zorgt voor de communicatie tussen de view interface en het model.</p>
<div id="attachment_1127" class="wp-caption aligncenter" style="width: 421px"><a href="http://www.driessen.nl/techtalk/wp-content/uploads/2011/03/MVP-Schematic-Model.png"><img class="size-full wp-image-1127" title="MVP Schematic Model" src="http://www.driessen.nl/techtalk/wp-content/uploads/2011/03/MVP-Schematic-Model.png" alt="MVP Schematic Model" width="411" height="650" /></a><p class="wp-caption-text">MVP Schematic Model</p></div>
<p><strong>Voorbeeld:</strong><br />
Als voorbeeld gebruik ik een zeer vereenvoudigde manier om persoonsgegevens te muteren.</p>
<p>UI wordt geladen en roept op de Presenter een Initialize method aan. De presenter gebruikt het Model om de juiste gegevens te verzamelen. Vervolgens roept de presenter op de View de FillFields method aan en geeft de data als parameter mee. De UI die de View implementeert weet hoe de data weergegeven moet worden.</p>
<p>Vervolgens wordt er op OK geklikt. De OK button roept op de Presenter de SaveData method aan met de data, waarna de Presenter aan het Model opdracht geeft om eventuele wijzigingen op te slaan. Als hierbij een regel overtreden wordt, dan ontvangt de Presenter van het Model een validatie waarschuwing. De Presenter roept op de View een method aan aan met het validatiebericht, waarop de UI zorgt dat de melding getoond wordt.</p>
<p>Op deze manier is het zelfs mogelijk om twee hele verschillende UI&#8217;s dezelfde taak te laten uitvoeren. Als de UI de View inteface implementeert en de juiste calls op de presenter maakt zal het gewoon werken. De UI is in feite nog maar een heel dun schilletje dat geen enkele logica meer bevat.</p>
<p>Klinkt makkelijk he?</p>
<p>Is het deels ook. Deels ook helemaal niet. Dat komt door de fundamenteel verschillende manieren waarop een UI platform kan werken.<br />
Als je je namelijk bij het ontwerp van je MVP classes en interfaces alleen richt op Windows Forms applicaties dan kom je jezelf onherroepelijk tegen als je deze classes wil gebruiken in een ASP.NET Webforms applicatie. Je hebt namelijk waarschijnlijk je hele ontwerp erop gebaseerd dat je state hebt. En dat heb je in ASP.NET niet op dezelfde manier zoals je dat in een Windows Forms applicatie. ASP.NET is in de basis zo stateless als maar zijn kan. &#8216;Gewoon&#8217; even wat data in memory houden is er dus niet bij. Met statics moet je in ASP.NET Webforms rekening houden met multithreading.</p>
<p>Ok, dan vliegen we het toch aan vanuit de hoek van ASP.NET Webforms? Als je je bij het ontwerp van je MVP classes en interfaces alleen richt op ASP.NET Webforms dan kom je jezelf waarschijnlijk ook tegen. Je hebt het state probleem namelijk zojuist waarschijnlijk opgelost door gebruik te maken van je SessionState of Cache, wat het gebruik van deze classes en interfaces in een Windows Forms applicatie (bij het gebrek aan deze twee middelen) op zijn zachtst gezegd tot een uitdaging maakt.</p>
<p><strong>I bring to you: Stateless Windows Forms.</strong><br />
Als je dus geen gebruik mag maken van de &#8216;statehulpmiddelen&#8217; van ASP.NET, dan is ASP.NET WebForms tot nu toe helaas stateless. Daar doe je weinig aan. Bij Windows Forms heb je, hoewel het in het begin misschien wat vreemd aanvoelt, de keuze. Als je er rekening mee houdt dat je MVP classes en interfaces geen gebruik mogen maken van de state die Windows Forms biedt, maar ook niet van de technieken die ASP.NET biedt om het state(less) probleem op te lossen, dan kom je al een heel eind. Om jezelf te dwingen om hier rekening mee te houden doe je er goed aan om je Views en Presenters in een apart project onder te brengen waarbij je System.Windows.?? en System.Web.?? weigert te referencen. Bij je Model (data en businesslogic) hield je hier (als het goed is) al rekening mee.</p>
<p><strong>Oplossing in het Driessen Framework<br />
</strong>Met  bovengenoemde uitdaging in het achterhoofd hebben we in het framework een kleine &#8216;MVP Suite&#8217; gebouwd die het voor de develpers makkelijk moet maken om applicaties standaard op MVP op te tuigen. Zo is straks een eventuele overstap van Windows Forms naar WPF ook eenvoudiger.</p>
<p>Het klinkt misschien vrij complex maar de daadwerkelijke implementatie is eigenlijk een lachertje, als je het concept maar snapt.</p>
<p><strong>Model<br />
</strong>Voor het Model hebben we in het Driessen Framework een BaseModel class gebouwd. De specifieke model class zal hiervan inheriten en bevat, naast de data entiteit en eventuele gerelateerde gegevens, de businesslogic voor het domain model. Deze class is gebouwd volgens stateless sessions, maar zonder gebruik te maken van SessionState of Caching. In Web gebruik je wel het SessionId om de sessie voor de dataclass te identificeren. In Windows bepaald het entry form een SessionId door een GUID hiervoor te genereren. De data wordt gecached via een custom caching systeem dat dus multi-platform werkt. Dit systeem zorgt er bijvoorbeeld ook automatisch voor voor dat disposes op het juiste moment plaatsvinden.</p>
<pre class="brush: csharp; title: ; notranslate">
 /// &lt;summary&gt;
/// Base model for MVP projects that is able to work stateless/cross-session
/// Inherit: MyModel:BaseModel&lt;MyModel&gt;
/// &lt;/summary&gt;
/// &lt;typeparam name=&quot;TModelType&quot;&gt;The type of the model that inherits this BaseModel&lt;/typeparam&gt;
/// &lt;example&gt;
/// How to implement:
/// MyModel:BaseModel&lt;MyModel&gt;;
/// {
///    OtherEntityGrid otherEntityGrid;
///
///     public override Init(IBaseClass baseClass, IList&lt;RelatedItem&gt;relatedItems)
///     {
///         base.Init(baseClass, relatedItems);
///
///         otherEntityGrid = new OtherEntityGrid(baseClass.Core);
///         AutoDispose.Add(otherEntityGrid);
///     }
/// }
///
/// How to retrieve an instance:
/// MyModel myModel = MyModel.GetInstance(sessionId);
///
/// if (!myModel.Initialized)
/// {
///     myModel.Init(baseClass);
/// }
/// &lt;/example&gt;
public class BaseModel&lt;TModelType&gt; : IDisposable
where TModelType : IDisposable
{
   #region Instance Members

    private readonly DisposableList autoDispose = new DisposableList();

    /// &lt;summary&gt;
   /// Auto dispose list for the Model to use to automatically dispose resources
   /// &lt;/summary&gt;
   protected IList&lt;IDisposable&gt; AutoDispose
   {
      get
      {
         return autoDispose;
      }
   }

   /// &lt;summary&gt;
   /// True after the Init method was called
   /// &lt;/summary&gt;
   public virtual bool Initialized
   {
      get;
      private set;
   }

   /// &lt;summary&gt;
   /// The baseclass used for editing
   /// &lt;/summary&gt;
   public virtual IBaseClass BaseClass
   {
      get;
      private set;
   }

   /// &lt;summary&gt;
   /// The related items of the class
   /// &lt;/summary&gt;
   public virtual IList&lt;RelatedItem&gt; RelatedItems
   {
      get;
      private set;
   }

   /// &lt;summary&gt;
   /// Initializes the model
   /// &lt;/summary&gt;
   /// &lt;param name=&quot;baseClass&quot;&gt;The main baseclass of the model (optional)&lt;/param&gt;
   /// &lt;param name=&quot;relatedItems&quot;&gt;Related items for the model (optional)&lt;/param&gt;
   public virtual void Init(IBaseClass baseClass = null, IList&lt;RelatedItem&gt; relatedItems = null)
   {
      Initialized = true;
      BaseClass = baseClass;
      RelatedItems = relatedItems;
   }

   #endregion

   #region Static Members

   /// &lt;summary&gt;
   /// The default cache session id
   /// &lt;/summary&gt;
   private const string defaultSesionId = &quot;[DefaultSession]&quot;;

   /// &lt;summary&gt;
   /// The cache for session support
   /// &lt;/summary&gt;
   private static volatile DisposableDictionary&lt;string, TModelType&gt; cache = new DisposableDictionary&lt;string, TModelType&gt;();

   /// &lt;summary&gt;
   /// Gets an instance from the cache for the provided session (or for the default session)
   /// Creates a new instance if no instance exists for the session yet
   /// &lt;/summary&gt;
   /// &lt;param name=&quot;sessionId&quot;&gt;The session to get an instance for (optional)&lt;/param&gt;
   /// &lt;returns&gt;The instance for the provided session (or the default session instance)&lt;/returns&gt;
   public static TModelType GetInstance(string sessionId = defaultSesionId)
   {
      EnsureCache();

      TModelType returnValue;
      if (!cache.TryGetValue(sessionId, out returnValue))
      {
         returnValue = Activator.CreateInstance&lt;TModelType&gt;();
         cache.Add(sessionId,returnValue);
      }
      return returnValue;

   }

   /// &lt;summary&gt;
   /// Disposes the content for the session
   /// &lt;/summary&gt;
   /// &lt;param name=&quot;sessionId&quot;&gt;The session to dispose the content for (optional)&lt;/param&gt;
   public static void Dispose(string sessionId = defaultSesionId)
   {
      TModelType itemToDispose;

      if (cache != null &amp;&amp; cache.TryGetValue(sessionId, out itemToDispose))
      {
         itemToDispose.Dispose();
         cache.Remove(sessionId);
      }
   }

   /// &lt;summary&gt;
   /// Disposes the entire content of the cache
   /// &lt;/summary&gt;
   public static void DisposeAll()
   {
      if (cache != null)
      {
         cache.Dispose();
         if (cache.Count &gt; 0)
               cache.Clear();
      }
   }

   /// &lt;summary&gt;
   /// Ensures the existance of the cache
   /// &lt;/summary&gt;
   private static void EnsureCache()
   {
      if (cache == null)
         cache = new DisposableDictionary&lt;string, TModelType&gt;();
   }
   #endregion

   #region IDisposable

   /// &lt;summary&gt;
   /// Disposes the instance
   /// &lt;/summary&gt;
   public void Dispose()
   {
      Dispose(true);
      GC.SuppressFinalize(this);
   }

   /// &lt;summary&gt;
   /// Disposes the instance
   /// &lt;/summary&gt;
   /// &lt;param name=&quot;disposing&quot;&gt;Disposes managed objects&lt;/param&gt;
   protected virtual void Dispose(bool disposing)
   {
      if (disposing)
         autoDispose.Dispose();
   }
   #endregion

   }
}
</pre>
<p><strong>View<br />
</strong>Voor communicatie vanuit de businessrules naar de UI hebben we een 2-tal simpele call mechanismen in een standaard View interface gegoten waarmee een eenvoudig bericht of een validation result naar de UI doorgegeven kan worden. De UI bepaalt op welke manier dit weergegeven wordt, afhankelijk van het platform waarop gewerkt wordt.</p>
<pre class="brush: csharp; title: ; notranslate">
/// &lt;summary&gt;
/// The MVP view base
/// &lt;/summary&gt;
public interface IViewBase
{
   /// &lt;summary&gt;
   /// Shows a message
   /// &lt;/summary&gt;
   /// &lt;param name=&quot;messageText&quot;&gt;The message text&lt;/param&gt;
   /// &lt;param name=&quot;icon&quot;&gt;The message icon&lt;/param&gt;
   void ShowMessage(string messageText, ShowMessageIcon icon = ShowMessageIcon.Information);
   /// &lt;summary&gt;
   /// Shows the validation result
   /// &lt;/summary&gt;
   /// &lt;param name=&quot;validationResult&quot;&gt;The validationreuslt&lt;/param&gt;
   void ShowMessage(ValidationResult&lt;ValidationMessage&gt; validationResult);
}
</pre>
<p><strong></strong><strong>Presenter<br />
</strong>Voor de presenters hebben we in het framework een base class gemaakt die het BaseModel kan managen en initialiseren. De presenter zorgt zelf dat hij steeds de juiste data voor de huidige session paraat heeft staan als hij een call ontvangt.</p>
<pre class="brush: csharp; title: ; notranslate">
/// &lt;summary&gt;
/// Base Presenter class
/// &lt;/summary&gt;
/// &lt;typeparam name=&quot;TView&quot;&gt;The view corresponding to the presenter&lt;/typeparam&gt;
/// &lt;typeparam name=&quot;TModelType&quot;&gt;The type of the model&lt;/typeparam&gt;
public class PresenterBase&lt;TView, TModelType&gt;
where TView:IViewBase
where TModelType:BaseModel&lt;TModelType&gt;
{
  /// &lt;summary&gt;
  /// The view corresponding to the presenter
  /// &lt;/summary&gt;
  protected TView View
  {
    get;
    private set;
  }
  /// &lt;summary&gt;
  /// The model for the presenter
  /// &lt;/summary&gt;
  protected TModelType Model
  {
    get;
    private set;
  }
  /// &lt;summary&gt;
  /// The session ID
  /// &lt;/summary&gt;
  protected string SessionId
  {
     get;
     set;
  }
  /// &lt;summary&gt;
  /// Constructor
  /// &lt;/summary&gt;
  /// &lt;param name=&quot;view&quot;&gt;The view corresponding to the presenter&lt;/param&gt;
  public PresenterBase(TView view)
  {
    View = view;
  }
  /// &lt;summary&gt;
  /// Initializes the presenter and gets the Data class instance for the session
  /// &lt;/summary&gt;
  /// &lt;param name=&quot;sessionId&quot;&gt;The session ID to get the Data class instance for&lt;/param&gt;
  /// &lt;param name=&quot;baseClass&quot;&gt;A baseclass to work with (optional, not used at the framework level)&lt;/param&gt;
  public virtual void Init(string sessionId, IBaseClass baseClass = null)
  {
    SessionId = sessionId;
    Model = BaseModel&lt;TModelType&gt;.GetInstance(sessionId);
  }

 </pre>
<p>De combinatie van deze drie vormt een krachtig middel om ècht platform onafhankelijk het MVP concept te gebruiken.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.driessen.nl/techtalk/model-view-presenter-in-windows-forms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DevConnections 2010</title>
		<link>http://www.driessen.nl/techtalk/devconnections-2010/</link>
		<comments>http://www.driessen.nl/techtalk/devconnections-2010/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 16:48:54 +0000</pubDate>
		<dc:creator>Randy Keyers</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Algemeen]]></category>

		<guid isPermaLink="false">http://www.driessen.nl/techtalk/?p=1058</guid>
		<description><![CDATA[Om ons eens flink onder te dompelen in Visual Studio 2010 en .NET 4.0 hebben we in november 2010 de DevConnections in Las Vegas bezocht.. Een veel gehoorde vraag is: Waarom helemaal daarheen? Waarom gaan jullie niet gewoon naar de DevDays? De reden om sowieso jaarlijks naar de DevDays te gaan en in bijzondere gevallen ook naar een major [...]]]></description>
			<content:encoded><![CDATA[<p>Om ons eens flink onder te dompelen in Visual Studio 2010 en .NET 4.0 hebben we in november 2010 de <a title="DevConnections" href="http://www.devconnections.com" target="_blank">DevConnections </a>in Las Vegas bezocht..</p>
<p>Een veel gehoorde vraag is: Waarom helemaal daarheen? Waarom gaan jullie niet gewoon naar de <a title="Microsoft DevDays" href="http://www.techdays.nl/DevDays" target="_blank">DevDays</a>?<br />
De reden om sowieso jaarlijks naar de DevDays te gaan en in bijzondere gevallen ook naar een major event in het buitenland is tamelijk eenvoudig:</p>
<p>De DevDays is in mijn ogen met name erop gericht om mensen te laten weten wat er is, wat eraan komt en om ze aan de hand van pakkende voorbeelden te triggeren om eens wat dieper in de techniek te duiken. Dat is voor ons de reden om daar ook echt jaarlijks heen te willen. Je wil geen bruikbare technieken over het hoofd zien, of achter de feiten aanlopen.<span id="more-1058"></span>Major events zoals de <a href="http://www.vslive.com" target="_blank">VSLive!</a> en de DevConnections hebben voor een deel dezelfde strekking, maar voor het overgrote deel gaan ze nèt dat stapje verder. Een stukje &#8216;outside the comfort zone&#8217; van wat een technologie out-of-the-box kan. Als die geweldige nieuwe techniek (waarvan ons op de DevDays is verteld dat hij out-of-de-box de hele applicatie ongeveer voor je schrijft) in bepaalde gevallen onbruikbaar blijkt voor de wat grotere business processing applicaties, dan hoor je dat op deze events. En dat niet alleen: Er wordt ook uit de doeken gedaan hoe het dan wèl zou moeten of kunnen werken.</p>
<p>Mensen als <a title="Scott Guthrie" href="http://weblogs.asp.net/scottgu/" target="_blank">Scott Guthrie</a>, <a title="Brian Harry" href="http://blogs.msdn.com/b/bharry/" target="_blank">Brian Harry</a>, <a title="Billy Hollis" href="http://www.dotnetmasters.com/" target="_blank">Billy Hollis</a>, developers uit het Visual Studio team, de team lead van het C# compiler team, UI guru <a title="Mark Miller" href="http://community.devexpress.com/blogs/markmiller/default.aspx" target="_blank">Mark Miller</a> (DevExpress) en nog veel meer vak idioten waarvoor dit dagelijkse kost is, staan voor je klaar. Niet alleen tijdens de sessies, maar ook daar buiten zijn ze te porren voor een bakkie of een lunch.</p>
<p>In oktober 2007 waren we ook al in Las Vegas te vinden op de VSLive! waar we ons hebben vastgebeten in UI design, quality assurance en application lifecycle management met Team Foundation Server. De resultaten hiervan maken nu deel uit van onze dagelijkse werkzaamheden. De manier van samenwerken, de hoge kwaliteit en de manier waarop we Team Foundation Server &#8216;uitnutten&#8217; komt voor een groot gedeelte vanuit de VSLive!.</p>
<p>Waar we ons op de DevConnections 2010 mee hebben laten doorweken zijn in grote lijnen de do&#8217;s and dont&#8217;s van Silverlight, Windows Phone 7 development, MVC 3.0 en het Entity Framework.<br />
Eerste resultaat: De nieuwe versie van onze RAP applicatie zal gebaseerd zijn op MVC 3.0 in combinatie met het Entity Framework.</p>
<p>Patrick heeft nog een aantal <a title="Microsoft Lync" href="http://office.microsoft.com/nl-nl/lync/" target="_blank">Microsoft Lync</a> sessies bijgewoond, met als resultaat dat er nu op onze bureaus telefoons staan met een USB kabel in plaats van een telefoonstekker. Onze uitdaging is natuurlijk om hier uiteindelijk een koppeling op te maken vanuit onze software&#8230;</p>
<p>Gekkenhuis dus; Wanneer gaan we weer?!?</p>
<p>Op persoonlijke titel zou ik nog nog wel eens naar de <a title="Microsoft PDC" href="http://www.microsoftpdc.com" target="_blank">Microsoft PDC </a>willen. Daar doet Steve Ballmer himself de keynote <img src='http://www.driessen.nl/techtalk/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .<br />
Dat staat bij mij op hoog mijn persoonlijke &#8216;things to definitely do&#8217; lijstje. Wie weet&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.driessen.nl/techtalk/devconnections-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Op zoek naar collega&#8217;s in het .NET Magazine</title>
		<link>http://www.driessen.nl/techtalk/op-zoek-naar-collegas-in-het-net-magazine/</link>
		<comments>http://www.driessen.nl/techtalk/op-zoek-naar-collegas-in-het-net-magazine/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 10:07:57 +0000</pubDate>
		<dc:creator>Patrick Adriaansen</dc:creator>
				<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://www.driessen.nl/techtalk/?p=1012</guid>
		<description><![CDATA[Er staat een advertentie in de .NET Magazine waarin we nieuwe collega&#8217;s zoeken. We zijn op zoek naar nieuwe C# .NET developers. De gelukkige die hier mag komen werken valt daarbij meteen met zijn neus in de boter. Naast natuurlijk zulke fijne collega&#8217;s (kuch), mag hij/zij ook direct mee naar de DevConnections 2010 in Las [...]]]></description>
			<content:encoded><![CDATA[<p>Er staat een advertentie in de .NET Magazine waarin we nieuwe collega&#8217;s zoeken. We zijn op zoek naar nieuwe C# .NET developers.</p>
<p>De gelukkige die hier mag komen werken valt daarbij meteen met zijn neus in de boter. Naast natuurlijk zulke fijne collega&#8217;s (kuch), mag hij/zij ook direct mee naar de DevConnections 2010 in Las Vegas. Lijkt me een prima reden om direct te solliciteren.</p>
<p style="text-align: center;"><img class="size-full wp-image-1020 aligncenter" title="vegas_advertentie" src="http://www.driessen.nl/techtalk/wp-content/uploads/2010/06/vegas_advertentie.jpg" alt="vegas_advertentie" width="157" height="222" /></p>
<p>De advertentie kun je <a href="http://www.driessen.nl/techtalk/wp-content/uploads/2010/06/CNET_LasVegas_DevConnections.pdf">hier</a> vinden.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.driessen.nl/techtalk/op-zoek-naar-collegas-in-het-net-magazine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Donkere uithoeken van .NET</title>
		<link>http://www.driessen.nl/techtalk/donkere-uithoeken-van-net/</link>
		<comments>http://www.driessen.nl/techtalk/donkere-uithoeken-van-net/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 13:04:31 +0000</pubDate>
		<dc:creator>Randy Keyers</dc:creator>
				<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://www.driessen.nl/techtalk/?p=884</guid>
		<description><![CDATA[Voor het bouwen van een maatwerk web-portal voor een van onze klanten, kwam ik tot de ogenschijnlijke kleine uitdaging om een stuk java-script aan te maken in C# code. Piece of cake… Totdat er een new-line in de javascript kwam te staan, die de browser niet (zomaar) slikte.]]></description>
			<content:encoded><![CDATA[<p><strong>De uitdaging</strong><br />
Voor het bouwen van een maatwerk web-portal voor een van onze klanten, kwam ik tot de ogenschijnlijke kleine uitdaging om een stuk java-script aan te maken in C# code. Piece of cake… Totdat er een new-line in de java-script kwam te staan, die de browser niet (zomaar) slikte.</p>
<p>In het voorbeeld dat ik hieronder aanhaal gebruik ik het ‘OnClientClick’ event van een Button. Daar komt ter bevestiging een “Weet u het zeker” melding in te staan, alvorens de server-side event afgaat. Het OnClientClick event is eigenlijk een string property die gevuld mag worden met java-script. Voor een “Weet u het zeker” melding zou daar het volgende in kunnen komen te staan:</p>
<pre class="brush: jscript; light: true; title: ; notranslate">
return confirm('Weet u het zeker.');
</pre>
<p>Als in de confirmatietekst een new-line (“\r\n”) staat, dan gaat het niet zomaar lukken. De new-line moet ge-escaped worden naar:</p>
<pre class="brush: jscript; light: true; title: ; notranslate">
return confirm('Weet u het zeker.\\r\\nAlle data gaat verloren');
</pre>
<p><strong>De eerste oplossing</strong><br />
In eerste instantie zegt mijn intuïtie dat ASP.NET vast ergens wel een method heeft die dit voor me doet. Zo is er de HttpServerUtility.HtmlEncode, en de HttpServerUtility.UrlEncode. Deze zijn hier echter niet voor geschikt.</p>
<p>In een vorig project werd het opgelost door middel van enkele string-replace aanroepen. Zie onderstaand voorbeeld:</p>
<pre class="brush: csharp; title: ; notranslate">
/// &lt;summary&gt;
/// Build a javascript string, to be used in a javascript.|
/// &lt;/summary&gt;
/// &lt;param&gt;The raw value to create a javascript string for.&lt;/param&gt;
/// &lt;returns&gt;The javascript string.&lt;/returns&gt;
private static string BuildJavascriptString(string rawValue)
{
    string escapedValue =
        rawValue
        .Replace(&quot;\\&quot;, &quot;\\\\&quot;)
        .Replace(&quot;\'&quot;, &quot;\\\'&quot;)
        .Replace(&quot;\&quot;&quot;, &quot;\\\&quot;&quot;)
        .Replace(&quot;\r&quot;, &quot;\\r&quot;)
        .Replace(&quot;\n&quot;, &quot;\\n&quot;);
    return string.Format(&quot;'{0}'&quot;, escapedValue);
}
</pre>
<p>Het gebruik van deze method ziet er als volgt uit:</p>
<pre class="brush: csharp; title: ; notranslate">
MyButton.OnClientClick = string.Format(&quot;return confirm({0});&quot;,
    BuildJavascriptString(confirmMessage));
</pre>
<p><strong>De echte oplossing</strong><br />
Het is en blijft echter vreemd dat zoveel string-replace aanroepen nodig zijn. Het zou wellicht op te lossen zijn met een regular expression, maar zelfs dan zit ik nog op het verkeerde spoor. En zijn nu alle varianten afgedekt? Blijft dit werken in de toekomst? Dit moet toch beter kunnen!</p>
<p>Ergens in een donkele hoek van alle Microsoft assemblies in de <a title=".NET Global Assembly Cache" href="http://en.wikipedia.org/wiki/Global_Assembly_Cache">GAC</a>, staat de Microsoft.JScript assembly. Laat deze nou toevallig een method hebben die lijkt op de java-script escape method. Door de method BuildJavascriptString te vervangen door onderstaande, weet ik zeker dat ik er nooit meer naar om hoef te kijken.</p>
<pre class="brush: csharp; title: ; notranslate">
/// &lt;summary&gt;
/// Build a javascript string, to be used in a javascript.
/// &lt;/summary&gt;
/// &lt;param&gt;The raw value to create a javascript string for.&lt;/param&gt;
/// &lt;returns&gt;The javascript string.&lt;/returns&gt;
private static string BuildJavascriptString(string rawValue)
{
    return string.Format(&quot;unescape('{0}')&quot;,
        Microsoft.JScript.GlobalObject.escape(rawValue));
}
</pre>
<p>Bovenstaande method is overigens in ons framework geadopteerd, met een uitbreiding voor booleans, integers, doubles en nullables:</p>
<pre class="brush: csharp; title: ; notranslate">
/// &lt;summary&gt;
/// Convert a value, regardless of it's type, to be used in a javascript.
/// &lt;/summary&gt;
/// &lt;typeparam&gt;The type of the parameter.&lt;/typeparam&gt;
/// &lt;param&gt;The value to convert.&lt;/param&gt;
/// &lt;returns&gt;A javascript string which represents the specified value.&lt;/returns&gt;
public static string ConvertValueToJavaScript&lt;T&gt;(T value)
{
    string valueAsJavaScriptString = string.Empty;

    if (value == null)
        valueAsJavaScriptString = &quot;null&quot;;
    else if (typeof(T) == typeof(bool))
        valueAsJavaScriptString =
            value.ToString().ToLowerInvariant();
    else if (typeof(T) == typeof(string))
        valueAsJavaScriptString =
            &quot;unescape('{0}')&quot;.FormatInvariant(
            Microsoft.JScript.GlobalObject
                .escape(value as string));
    else
        valueAsJavaScriptString = Convert.ToString(value,
            CultureInfo.InvariantCulture);

    return valueAsJavaScriptString;
}
</pre>
<p><strong>Java-script syntax verifiëren met C#</strong><br />
In diezelfde donkere uithoek zit ook een java-script compiler, die run-time gebruikt kan worden om java-script te complileren en verifiëren. Hiermee is het mogelijk om een unit-test te schrijven, die alle java-script bestanden opzoekt in het project, en verifieërd. Maar voor deze vonst gaan de credits naar Mads Kristensen, zie zijn blog-post: <a title="Verify JavaScript syntax using C#" href="http://madskristensen.net/post/Verify-JavaScript-syntax-using-C.aspx">Verify JavaScript syntax using C#</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.driessen.nl/techtalk/donkere-uithoeken-van-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Visual Studio 2010 / Team Foundation Server 2010</title>
		<link>http://www.driessen.nl/techtalk/visual-studio-2010-team-foundation-server-2010/</link>
		<comments>http://www.driessen.nl/techtalk/visual-studio-2010-team-foundation-server-2010/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 14:48:51 +0000</pubDate>
		<dc:creator>Randy Keyers</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[TFS]]></category>

		<guid isPermaLink="false">http://www.driessen.nl/techtalk/?p=845</guid>
		<description><![CDATA[Om straks vlekkeloos over te kunnen stappen van Visual Studio 2008 en Team Foundation Server 2008 naar de 2010 versies van deze producten ben ik de afgelopen 2 weken bezig geweest met het inventariseren en testen met de Beta 2 release van beide producten. Visual Studio Ik moet zeggen dat het er allemaal erg goed [...]]]></description>
			<content:encoded><![CDATA[<p>Om straks vlekkeloos over te kunnen stappen van Visual Studio 2008 en Team Foundation Server 2008 naar de 2010 versies van deze producten ben ik de afgelopen 2 weken bezig geweest met het inventariseren en testen met de Beta 2 release van beide producten.</p>
<p><strong>Visual Studio</strong></p>
<p>Ik moet zeggen dat het er allemaal erg goed uit ziet. Ik had wel liever gezien dat ze tijd hadden gestoken in bijvoorbeeld een multithreaded compiler dan om de hele UI in WPF te gieten maar ach, het gaat vlot genoeg.</p>
<p>Buiten natuurlijk de language support voor C# 4.0 zijn er toch 3 nieuwe zaken die er voor mij echt uitspringen in deze versie van Visual Studio.</p>
<p><em>Run Impacted Tests</em><br />
Een hele welkome toevoeging op Visual Studio Team System (ik gebruik op dit moment beta 2 van de Ultimate edition) is de &#8216;Run Impacted Tests&#8217; feature. Ik heb er even mee geëxperimenteerd en het werkt fantastisch!<br />
Na een build bekijkt visual studio welke unittests (direct of indirect) geraakt worden door de code die gewijzigd is.  Vervolgens kun je ervoor kiezen om alleen de &#8216;Impacted Unittests&#8217; te draaien. Zo weet je zeker dat je geen gerelateerde unittests over het hoofd ziet, zonder alle unittests te hoeven draaien.</p>
<p><em>Intellisense</em><br />
De intellisense is ook wat intelligenter geworden door een contains filter op het gedeelte van je invoer te zetten. Een member hoeft dus niet langer te beginnen met je invoer.</p>
<p><img class="alignnone size-full wp-image-855" title="Intellisense2008" src="http://www.driessen.nl/techtalk/wp-content/uploads/2009/11/Intellisense2008.png" border="1" alt="Intellisense2008" width="190" height="190" /> �<br />
<em>Visual Studio 2008<br />
</em></p>
<p><img title="Intellisense2010" src="http://www.driessen.nl/techtalk/wp-content/uploads/2009/11/Intellisense2010.png" border="1" alt="Intellisense2010" width="266" height="84" /><br />
<em>Visual Studio 2010</em></p>
<p><em><br />
Code Analysis</em><br />
Er zijn bovendien een hoop nieuwe Code Analysis rules bijgekomen die voor ons een zeer welkome toevoeging zijn op de bestaande set rules en onze custom rules. Aan 90% van de nieuwe rules voldeden we al zonder het in de gaten te hebben. 5% van de nieuwe rules is bij ons eigenlijk niet van toepassing. De overige 5% van de nieuwe rules zijn wel in lijn met onze guidelines, dus die zouden feitelijk geen meldingen moeten geven. Maargoed, we zijn allemaal mensen dus er kan wel eens wat doorheen glipppen. Het aantal meldingen die hierdoor ontstaan is dusdanig beperkt dat we toch wel trots op onszelf kunnen zijn. Deze gaan we dus aanpakken en oplossen.</p>
<p> Ook het nieuwe &#8216;Ruleset&#8217; concept dat met Visual Studio 2010 geïntroduceerd wordt is zeer welkom. Dit helpt om zelf vaste sets te maken waar de code in projecten aan moet voldoen, zonder dit steeds op ieder nieuw project handmatig een voor een in te moeten stellen. Ook is een &#8216;minimium requirement&#8217; ruleset op te geven bij de Check-In policy van Team Foundation server, wat ook enkele onhebbelijkheden uit het verleden opheft.</p>
<p> </p>
<p><strong>Team Foundation Server</strong></p>
<p>Team Foundation server is eenvoudiger te beheren en biedt tools om aan Team Project inrichting te sleutelen zonder Visual Studio daarbij nodig te hebben.<br />
TFS Web Access zit nu geintegreerd in de Team Foundation installatie, maar als ik zie wat er allemaal voor &#8216;neat features&#8217; beschikbaar zijn gekomen direct op de Project Portal (zoals het beheren van de User Stories en Tasks) denk ik niet dat TFS Web Access nog nodig is. Team Foundation Server is nu toch wel volwassen te noemen.</p>
<p>Bij Driessen valt met de komst van Team Foundation Server 2010 het doek voor de Scrum project template van Conchango die we tot nu toe gebruikten voor project planning. De MSF for Agile project template dekt de lading om volgens het Scrum principe te werken ruimschoots.<br />
Ik verwacht dat ook onze product owners hier op korte termijn goed mee uit de voeten kunnen.</p>
<p><img class="alignnone size-full wp-image-846" title="capacity overview" src="http://www.driessen.nl/techtalk/wp-content/uploads/2009/11/capacity-overview.JPG" alt="capacity overview" width="628" height="347" /><br />
<em><strong>Sprint Planning met Excel in Team Foundation Server 2010. Even wennen maar het werkt toch wel erg lekker!</strong><br />
Een goed overzicht met de workload op iedere developer. Marco blijkt wat teveel hooi op zijn vork te hebben genomen, dus moet er  wat werk van Marco naar de andere developers gezet worden.</em></p>
<p> Al met al dus genoeg om naar uit te kijken. Ook de proefconversies van onze projecten die ik tot nu toe heb gedaan zien er goed uit. We wachten in spanning af tot Q1 2010.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.driessen.nl/techtalk/visual-studio-2010-team-foundation-server-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

