Monthly Archives: February 2010

Exploring System.Interactive

A couple of weeks ago i was working on an application that would transfer data through a couple of components as a List<object>. In essence, all we were doing over and over again was the following:

interface IMapper<tentity>
{
 TEntity FromObjectList(List<object> objectList);
 List<object> ToObjectList(TEntity entity);
}

My initial implementation (using EnumerableEx operators from Reactive Extensions) looked like this:

public TEntity FromObjectList(List<object> objectList)
{
 var entity = new TEntity();

 properties
  .Zip(objectList, (property, value) => AssignValueToProperty(entity, property, value))
  .Run();

 return entity;
}

int AssignValueToProperty(object entity, PropertyInfo property, object value)
{
 property.SetValue(entity, value, null);
 return 0;
}

public List<object> ToObjectList(TEntity entity)
{
 return properties
  .Select(property => property.GetValue(entity, null))
  .ToList();
 }

And the consumer code looks like this:

var person = new Person {  Id = 2, Score = 1.3, Name = "Tim", Title = "Sir" };

var personMapper = new Mapper<person>()
 .Map(x => x.Id)
 .Map(x => x.Score)
 .Map(x => x.Name)
 .Map(x => x.Title);

var data = personMapper.ToObjectList(person);
var clonedPerson = personMapper.FromObjectList(data);

Wait a minute, in most situations we simply want to map all properties on the object. Let’s create a mapper for this:

class AutoMapper<tentity> : Mapper<tentity> where TEntity : new()
{
 public AutoMapper()
 {
  typeof(TEntity).GetProperties().Run(property => Map(property));
 }
}

And now we don’t have to waste time doing the same thing over and over again! Because we always need to map all properties of our types we ended up with the following:

public static class Mapper
{
 public static List<object> ToObjectsList<tentity>(this TEntity entity)
 {
  return entity.GetType().GetProperties()
   .Select(property => property.GetValue(entity, null))
   .ToList();
  }

 public static TEntity ToEntity<tentity>(this List<object> objectsList) where TEntity : new()
 {
  TEntity entity = new TEntity();
  entity.GetType().GetProperties()
   .Zip(objectsList, (property, value) =>{ property.SetValue(entity, value,null); return 0;})
   .Run();
  return entity;
 }
}

Learned something from Resharper: Enumerable.OfType<TResult>

A couple of weeks ago i discovered Enumerable.OfType<TResult> when i let Resharper rewrite my code as a Linq statement. Here is the original code:

var selectedPersons = new List<personSelectItem>();
foreach(var selectedItem in selectedItems)
{
 var selectedPerson = selectedItem as PersonSelectItem;
 if (selectedPerson == null) continue;
 selectedPersons.Add(selectedPerson);
}

And here is how it looks after the rewrite:

var selectedPersons = selectedItems.OfType<personSelectItem>().ToList();

Yup, the Resharper license was definitely worth it’s money.

Calculate EndpointAddress for Silverlight client

Because Silverlight checks the origin it considers http://localhost and http://127.0.0.1 as different locations. In case you want your visitors to be able to use both addresses you can recalculate the address as following:

EndpointAddress GetEndpointAddress(EndpointAddress endpointAddress)
{
 var scheme = Application.Current.Host.Source.GetComponents(UriComponents.Scheme, UriFormat.Unescaped);
 var serverAndPort = Application.Current.Host.Source.GetComponents(UriComponents.HostAndPort, UriFormat.Unescaped);
 var pathAndQuery = endpointAddress.Uri.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
 return new EndpointAddress(scheme + "://" + serverAndPort + pathAndQuery);
}

And you can use this method as following:

var client = new DirectoryServiceClient();
client.Endpoint.Address = GetEndpointAddress(client.Endpoint.Address);
client.GetMessageCompleted += ClientGetMessageCompleted;
client.GetMessageAsync();

Clever TemplateFile hack

In my current project i use TemplateFileTask (MSBuild Community Tasks Project) to generate configuration files. I ran into the problem that i don’t want to expose a MEX endpoint in production. This is my initial template file:

 <endpoint address="" binding="ws2007HttpBinding" contract="DemoService.IFileService" />
 ${MexEndpoint}
</service>

And here is my initial msbuild task:

<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
 <Target Name="GenerateConfigFiles">
  <PropertyGroup>
   <MexEndpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
   </MexEndpoint>
  </PropertyGroup>

  <PropertyGroup Condition=" '$(Env)'=='Production' ">
   <MexEndpoint></MexEndpoint>
  </PropertyGroup>

  <ItemGroup>
   <Tokens Include="MexEndpoint">
    <ReplacementValue>$(MexEndpoint)</ReplacementValue>
   </Tokens>
  </ItemGroup>

  <TemplateFile Template="Web.template.config" OutputFileName="Web.config" Tokens="@(Tokens)" />
 </Target>
</Project>

This results in the following configuration file: (WCF does not like the xml namespace declaration):

 <endpoint address="" binding="ws2007HttpBinding" contract="DemoService.IFileService" />
 <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
</service>

I noticed that a smart collegue of mine came up with the following template file:

 <endpoint address="" binding="ws2007HttpBinding" contract="DemoService.IFileService" />
 <${MexBegin}endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /${MexEnd}>
</service>

And this is how he defines the MexBegin and MexEnd properties in msbuild:

<PropertyGroup>
 <MexBegin></MexBegin>
 <MexEnd></MexEnd>
</PropertyGroup>

<PropertyGroup Condition=" '$(Env)'=='Production' ">
 <MexBegin>!--</MexBegin>
 <MexEnd>--</MexEnd>
</PropertyGroup>

This leads to a nice MEX endpoint for all environments and in Production we get the following:

<!--endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /-->

Perhaps it is cleaner to implement my own TemplateFileTask but untill then this clever hack does the job ;)

Another missing method for IEnumerable<T>

Currently there are two overloads for OrderBy on Enumerable:

  • OrderBy(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
  • OrderBy(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)

Because i don’t want to implement an IComparer<TKey> each time i have implemented the following class:

class DelegateComparer<t> : IComparer<t>
{
 public Func<t, T, int> CompareFunction { get; set; }

 public DelegateComparer(Func<t, T, int> compareFunction)
 {
  CompareFunction = compareFunction;
 }

 public int Compare(T x, T y)
 {
  return CompareFunction(x, y);
 }
}

And now i can define a nice extension method:

public static IOrderedEnumerable<tsource> OrderBy<tsource, TKey>(this IEnumerable<tsource> source, Func<tsource, TKey> keySelector, Func<tkey, TKey, int> compareFunction)
{
 var comparer = new DelegateComparer<tkey>(compareFunction);
 return source.OrderBy(keySelector, comparer);
}

Verify that a X509Certificate can be used for key exchange

Here is another method that earned it’s place in my ever growing toolbox:

public static bool CanDoKeyExchange(this X509Certificate2 certificate)
{
 if (!certificate.HasPrivateKey) return false;

 var privateKey = certificate.PrivateKey as RSACryptoServiceProvider;
 if (privateKey == null) return false;

 var canDoKeyExchange = privateKey.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange;
 return canDoKeyExchange;
}