Programming Languages Hacks

Importanti regole per linguaggi di programmazione rilevanti come Java, C, C++, C#…

  • Subscribe

  • Lettori

    I miei lettori abituali

  • Twitter

Convert Event-Based Asynchronous to Task

Posted by Ricibald on 29th November 2015

Convert Event-Based Asynchronous to Task

The following example shows how to expose an arbitrary sequence of Event-Based Asynchronous Pattern (EAP) operations as one task by using a TaskCompletionSource<TResult>.

The example also shows how to use a CancellationToken to invoke the built-in cancellation methods.

When to use it:

  • you have a mix of Events and Tasks and you need to uniform them
  • you have an Event that needs to be treated using your already-done Task background processing
  • you have a complex flow of Events and you need to simplify the code readability

This extension method do the work:

public static class TaskExt
{
    public static async Task<TEventArgs> FromEvent<TEventArgs>(
        Action<EventHandler<TEventArgs>> registerEvent,
        Action action,
        Action<EventHandler<TEventArgs>> unregisterEvent,
        CancellationToken token)
    {
        var tcs = new TaskCompletionSource<TEventArgs>();
        EventHandler<TEventArgs> handler = (sender, args) => tcs.TrySetResult(args);
        registerEvent(handler);

        try 
        {
            using (token.Register(() => tcs.SetCanceled()))
            {
                action();
                return await tcs.Task;
            }
        }
        finally
        {
            unregisterEvent(handler);
        }   
    }
}

So if you have this class with this event:

public class LdapProvider {
    public event EventHandler<string> Authenticated;
    public void Authenticate(string username, string password) {
        // show the browser...
    }
    //... called back from the browser
    public void AuthenticateCallback(string token) {
        if(Autenticated != null)
            Authenticated(token);
    }
}

You can call this class using events in this way:

// save Token from ldapProvider when the event Autenticate fires
var ldapProvider = new LdapProvider();
ldapProvider.Authenticate("username", "password");
ldapProvider.Authenticated += (sender, token) => this.Token = ldapProvider.Token;
// wait for event be fired...

It can be converted in this way:

public static class LdapProviderExtensions {
    public static async Task<string> AuthenticateAsync(this LdapProvider ldapProvider, string username, string password) { 
        await TaskEx.FromEvent<string> (
            handler => ldapProvider.Authenticated += new EventHandler<string> (handler), 
            () => ldapProvider.Authenticate("username", "password"),
            handler => ldapProvider.Authenticated -= new EventHandler<string> (handler),
            CancellationToken.None);
    }
}


And used in this simple way:

// save Token from ldapProvider when the event Autenticate fires
var ldapProvider = new LdapProvider();
var token = await ldapProvider.AuthenticateAsync("username", "password");
// you have the token without saving it in a property...

Posted in .net | 1 Comment »

.NET: convertire due tipi generici

Posted by Ricibald on 4th November 2014

Come convertire in modo generico un tipo in un altro tipo?

Immaginiamo di dover convertire un tipo generico MyCustomType in un altro tipo (es. string). Ci sono diversi modi: dal semplice ToString() a un cast verso string. Finche si converte da MyCustomType verso string non è un problema, ma quando si procede al contrario questo non è possibile poiché string è fuori dal nostro controllo.

Per queste casistiche esiste da .NET 2.0 l’attributo TypeConverter da dichiarare all’interno di MyCustomType:

[TypeConverter(typeof(MyCustomTypeConverter))]
 public class MyCustomType {
    private string Data { get; set; }
    public static MyCustomType Parse(string data) {
        // convert code from string to MyCustomType here...
        return new MyCustomType { Data = data };
    }
    public override ToString() {
        // convert code from MyCustomType to string here...
        return this.Data;
    }
 }

public class MyCustomTypeConverter : TypeConverter {
    public override bool CanConvertTo (ITypeDescriptorContext context, Type destinationType)
    {
        return destinationType == typeof(string) || base.CanConvertTo (context, destinationType);
    }

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is string)
            return MyCustomType.Parse ((string)value);  // YOUR CONVERT HERE

        return base.ConvertFrom(context, culture, value);
    }

    public override object ConvertTo (ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        var myCustomTypeToConvert = (MyCustomType)value;
        if (destinationType == typeof(string))
            return myCustomTypeToConvert.ToString ();   // YOUR CONVERT HERE

        return base.ConvertTo (context, culture, value, destinationType);
    }
}

Una volta costruito il converter si invoca nel seguente modo per convertire da/a un certo tipo:

MyCustomType myCustomType = new MyCustomType { Data = "MyData" };
TypeConverter myCustomTypeConverter = TypeDescriptor.GetConverter (typeof(MyCustomType));

string myCustomTypeAsText = (string) myCustomTypeConverter.ConvertTo(myCustomType, typeof(string));
MyCustomType myCustomTypeFromText = (MyCustomType) myCustomTypeConverter.ConvertFrom("MyData2");

Questo risolve il problema finquando sappiamo quale dei due tipi implementa il TypeConverter per quella particolare conversione, cosa che potremmo non sapere in una gestione completamente generica.

Per questo motivo ho implementato il seguente extension method che consente di convertire due tipi generici andando a inferire in automatico quale TypeConverter utilizzare:

/// <summary>
/// Converte l'istanza. Usa il TypeDescriptor di T
/// </summary>
public static TDestination ConvertSafe<TDestination>(this object value) {
    if (value == null)
        return default(TDestination);

    // se sono gia lo stesso tipo non fare nulla
    if (typeof(TDestination) == value.GetType ())
        return (TDestination)value;

    // prova a convertire usando il converter di T
    var targetConverter = TypeDescriptor.GetConverter (typeof(TDestination));
    if(targetConverter != null && targetConverter.CanConvertFrom(value.GetType())) 
        return (TDestination)targetConverter.ConvertFrom (value);

    // prova a convertire usando il converter di value
    var sourceConverter = TypeDescriptor.GetConverter (value);
    if(sourceConverter != null && sourceConverter.CanConvertTo(typeof(TDestination))) 
        return (TDestination)sourceConverter.ConvertTo (value, typeof(TDestination));

    throw new InvalidCastException (String.Format("Unable to convert {0} to {1}", value.GetType(), typeof(TDestination)));
}

Esempio di utilizzo:

MyCustomType myCustomType = "MyData".ConvertSafe<MyCustomType>();
string myCustomTypeAsText = myCustomType.ConvertSafe<string>();

Che abilita scenari come il seguente che converte un tipo string (in teoria non convertibile) in un generico tipo MetaData<T> sfruttando internamente il TypeConverter del tipo T determinato a tempo di compilazione:

public MetaData<T> GetMetaInfo<T>(string value) {
    var result = new MetaData<T>(value.ConvertSafe<T>());
    return result;
}

Posted in .net | No Comments »

Split using delimiter except when delimiter is escaped

Posted by Ricibald on 11th September 2014

Split using delimiter except when delimiter is escaped

A common problem is to split a string handling escape characters.

This extension method handle the case of split considering the escape.
It uses the negative lookbehind feature of regular expressions.

Posted in .net | 73 Comments »

Automapper: Ignore All Not Mapped Properties

Posted by Ricibald on 19th July 2013

Normally in automapper you’ll write something like this:

Mapper.CreateMap<MoveEntity, MoveEntityDto>()
       .ForMember(dest => dest.PrimaryOriginTransferee, opt => opt.Ignore())
       .ForMember(dest => dest.PrimaryDestinationTransferee, opt => opt.Ignore())
       .ForMember(dest => dest.Customer, opt => opt.Ignore())
       .ForMember(dest => dest.DestinationAddress, opt => opt.Ignore())
       .ForMember(dest => dest.OriginAddress, opt => opt.Ignore())
       .ForMember(dest => dest.Order, opt => opt.Ignore())
       .ForMember(dest => dest.Shipment, opt => opt.Ignore())
       .ForMember(dest => dest.SourceSystemName, opt => opt.Ignore());

To ignore all not-mapped properties just use this extension method:

Mapper.CreateMap<MoveEntity, MoveEntityDto>()
       .IgnoreAllNonExisting();

Here the source code:

    public static IMappingExpression<TSource, TDestination> IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
    {
        var sourceType = typeof(TSource);
        var destinationType = typeof(TDestination);
        var existingMaps = Mapper.GetAllTypeMaps().First(x => x.SourceType.Equals(sourceType) && x.DestinationType.Equals(destinationType));
        foreach (var property in existingMaps.GetUnmappedPropertyNames())
        {
            expression.ForMember(property, opt => opt.Ignore());
        }
        return expression;
    }

Posted in .net | 2 Comments »

Download Snapping / Sticky / Magnetic Windows for WPF

Posted by Ricibald on 19th October 2009

Starting from Sticky Windows on CodeProject (makes your windows snapping like winamp or google talk) I adapted the project developed for standard WinForm in Wpf Application. It works with multiple monitor and with windows vista/7.

DOWNLOAD LINK.

I adapted the following interface to get the app work with WPF App:

    public interface IFormAdapter
    {
        IntPtr Handle { get; }
        Rectangle Bounds { get; set; }
        Size MaximumSize { get; set; }
        Size MinimumSize { get; set; }
        bool Capture { get; set; }
        void Activate();
        Point PointToScreen(Point point);
    }

    public class WinFormAdapter : IFormAdapter 
    {
        // Original Code Implementation
    }

    public class WpfFormAdapter : IFormAdapter 
    {
        // My Implementation
    }

Enjoy and please give me feedback!

DOWNLOAD LINK.

Posted in .net, download | 62 Comments »

Reflection Ricorsiva di Oggetti Javascript

Posted by Ricibald on 5th March 2009

Spesso lavorando con javascript ci troviamo una variabile complessa di cui non sappiamo nulla. Sarebbe bello avere un autocompletamento che ci elenchi tutte le funzioni e le proprietà ma gli IDE per ora non ci vengono troppo di aiuto (se ne conoscete qualcuno ditelo!!).

Quindi risulta utile ispezionare la variabile per trovare tutte le proprietà e funzioni che questa variabile dichiara in modo ricorsivo. A questo scopo, riporto il codice che ho scritto che consente di fare questo “sporco lavoro”. Cosa ne pensate? Esiste modo di ottimizzarlo (a parte migliorie di output)?

function TraceMethodsAndProperties(obj) {
	var prefix = "";
	var result = TraceMethodsAndPropertiesRecursion(obj, prefix);
	copyToClipboard(result);
}

function TraceMethodsAndPropertiesRecursion(obj, prefix){
	//alert('gotta:' + prefix);
	var result = "";
	try {
		if(obj != null) {
			for (var s in obj)
			{
				var value = obj[s];
				var key = prefix + s;
				
				result += "---------" + key + '=' + value + ';\n\n'
				var newPrefix = key + '.';
				result += TraceMethodsAndPropertiesRecursion(value, newPrefix);
			}
		}
	} catch(e) {
		// eccezione affogata per il singolo elemento che non consente la scansione: vai al prossimo
	}
	return result;
}

function copyToClipboard(s)
{
	window.clipboardData.setData('Text', s); // solo IE
}

Esempio di utilizzo:

    var persona = getCarloRossi();
    TraceMethodsAndProperties(persona);
    // OUTPUT:
    // ---------Nome=Carlo
    // ---------Cognome=Rossi
    // ---------Indirizzo.Via=via roma
    // ---------Indirizzo.Civico=32
    // ---------Indirizzo.CheckValid=function checkValid(via) { return via != ""; }

Posted in javascript | 2 Comments »

Certificazione MCTS Web verso l’MCPD Enterprise Framework 2.0 – Parte 3/5: 70-528

Posted by Ricibald on 19th February 2009

Questa è la terza parte (vedi la seconda parte) di una serie di pdf che ho scritto per riassumere il contenuto delle certificazioni Microsoft che portano alla certificazione Microsoft MCPD di livello “enterprise” (Distributed).

Logicamente questi pdf li avevo creati per riassumere i concetti che io ritenevo importante riassumere. Potrebbero essere appunti che non vi interessano affatto o che reputate inutili. Viceversa potrebbe essere un’ottima integrazione e un’ottimo punto di partenza per ripassare quanto studiato sul libro ufficiale dell’esame.

TS: Microsoft .NET Framework 2.0 – Web-Based Client Development

Posted in .net | 3 Comments »

Certificazione MCTS Win verso l’MCPD Enterprise Framework 2.0 – Parte 2/5: 70-526

Posted by Ricibald on 18th February 2009

Questa è la seconda parte (vedi la prima parte) di una serie di pdf che ho scritto per riassumere il contenuto delle certificazioni Microsoft (vedi terza parte) che portano alla certificazione Microsoft MCPD di livello “enterprise” (Distributed).

Logicamente questi pdf li avevo creati per riassumere i concetti che io ritenevo importante riassumere. Potrebbero essere appunti che non vi interessano affatto o che reputate inutili. Viceversa potrebbe essere un’ottima integrazione e un’ottimo punto di partenza per ripassare quanto studiato sul libro ufficiale dell’esame.

TS: Microsoft .NET Framework 2.0 – Windows-Based Client Development

Posted in .net | 5 Comments »

Certificazione MCPD Enterprise Framework 2.0 – Parte 1/5: 70-536

Posted by Ricibald on 17th February 2009

Questa è la prima parte di una serie di pdf che ho scritto per riassumere il contenuto delle certificazioni Microsoft (vedi seconda parte) che portano alla certificazione Microsoft MCPD di livello “enterprise” (Distributed).

Logicamente questi pdf li avevo creati per riassumere i concetti che io ritenevo importante riassumere. Potrebbero essere appunti che non vi interessano affatto o che reputate inutili. Viceversa potrebbe essere un’ottima integrazione e un’ottimo punto di partenza per ripassare quanto studiato sul libro ufficiale dell’esame.

Esame Microsoft 70-536: TS: Microsoft .NET Framework – Application Development Foundation

Posted in .net | No Comments »

Troncare valori Decimali Assimilabili ad Interi: Automatizzare Modifiche di Proprietà in una Classe

Posted by Ricibald on 1st February 2008

Lo so, il titolo dice poco e dice troppo… Cerco ora di spiegarvi la cosa, e credo che possa interessare a tutti gli sviluppatori .NET.

Mi sono trovato con questo problema apparentemente banale:

Dal database mi venivano restituiti valori di tipo Money, che venivano memorizzati come Decimal in una classe. La conversione Money-Decimal si porta dietro 4 cifre decimali, a prescindere dal valore. Vorrei quindi troncare queste cifre quando non serve. Ad esempio, vorrei convertire 12000,0000 in 12000.

Problema semplice, ma come? Considerate che non avevo un solo decimal, ma circa 200 valori memorizzati così. La soluzione immediata è utilizzare (12000.0000m).ToString("F") o Decimal.Truncate(12000.0000m) per troncare le cifre decimali, ma questo dovrei scriverlo 200 volte, e odio fare copia e incolla “sintomo di cattiva programmazione”.

Allora quello che mi serviva era:

Creare un metodo di utilità che mi consentisse di modificare tutte le cifre decimali in tutto il grafo degli oggetti che conteneva il mio oggetto di partenza.

Vorrei dunque creare un metodo come questo:

Bilancio bilancio = ImportBilancio();
PropertyModifier.ApplyToAllOfType<decimal>(bilancio, delegate(decimal number)
{
    decimal numberTruncated = Decimal.Truncate(number);
    Debug.Write(String.Format(" [Troncato: {0} -> {1}]", number.ToString(), numberTruncated.ToString()));
    return numberTruncated;
});

Riporto quindi la classe che consente questa utilissima funzione, per chiunque ne avesse bisogno:

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Diagnostics;
using System.Collections;

namespace PropertyModifier
{
public class PropertyModifier
{
public delegate T MethodModifier(T t);

private static BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;

public static void ApplyToAllOfType(object obj, MethodModifier modifier)
{
ApplyToAllOfType(obj, modifier, 0, true);
}

private static void ApplyToAllOfType(object obj, MethodModifier modifier, int indent, bool printCurrent)
{
if (obj == null)
return;

Type objType = obj.GetType();

if (printCurrent)
{
DebugWriteNode(objType.Name, indent);
Debug.WriteLine(“”); // vai a capo
}

/* Scandisci proprieta’ */
foreach (PropertyInfo prop in objType.GetProperties(flags))
{
/* Se e’ leggibile e non e’ indexed, ottieni valore */
if (prop.CanRead && prop.CanWrite && prop.GetGetMethod().GetParameters().Length == 0)
{
object propValue = prop.GetValue(obj, null);
if (propValue != null && !propValue.Equals(obj)) // previene cicli
{
DebugWriteNode(String.Format(“p:{0}={1}”,prop.Name, propValue), indent);
if (propValue is T1)
{
object modifiedValue = modifier((T1)propValue);
prop.SetValue(obj, modifiedValue, null);
}
Debug.WriteLine(“”); // vai a capo
ApplyToAllOfType(propValue, modifier, indent + 1, false);
}
}
}

/* Scandisci campi */
foreach (FieldInfo field in objType.GetFields(flags))
{
if (!field.IsInitOnly && !field.IsLiteral)
{
object fieldValue = field.GetValue(obj);
if (fieldValue != null && !fieldValue.Equals(obj)) // previene cicli
{
DebugWriteNode(String.Format(“f:{0}={1}”, field.Name, fieldValue), indent);
if (fieldValue is T1)
{
object modifiedValue = modifier((T1)fieldValue);
field.SetValue(obj, modifiedValue);
}
Debug.WriteLine(“”); // vai a capo
ApplyToAllOfType(fieldValue, modifier, indent + 1, false);
}
}
}

/* Se ho un elemento enumerabile, prendi gli elementi */
if (obj is IEnumerable)
{
IEnumerable enumerableObj = (IEnumerable)obj;
int currElement = 1;
foreach (object childObj in enumerableObj)
{
DebugWriteNode(String.Format(“{0}:{1}={2}”, currElement++, objType.Name, childObj), indent);
Debug.WriteLine(“”); // vai a capo
ApplyToAllOfType(childObj, modifier, indent + 1, false);
}
}
}

private static void DebugWriteNode(string nameToPrint, int indent)
{
for (int i = 0; i < indent; i++) { Debug.Write("| "); } Debug.Write("+ " + nameToPrint); } } } [/sourcecode]

Posted in .net | 2 Comments »