public IEnumerator<T> GetEnumerator() { var pos = 0; while (pos < _data.Count()) { yield return _data.ElementAt(pos++); } }
mercredi 15 mai 2013
La meilleure perle de code...
samedi 28 juillet 2012
jnode : jquery et nodejs
une api nodejs avec la simplicité de jquery.
jnode utilise le fichier jquery-core à cette adresse https://github.com/jquery/jquery/blob/master/src/core.js.
jnode a pour but d’être utilisé avec un serveur http. Vous pouvez faire sans, mais vous vous retrouverez avec des fonctionnalités inutiles.
Ce qu’apporte jnode :
- Une configuration simple d’un serveur http
- un serveur de fichiers statiques
- un serveur d’api (avecla possibilité d’encapsuler automatiquement le résultat en fonction du type de contenu attendu par le client)
- la fonction $ de jquery : vous pouvez charger un module avec la fonction $ ou l’utiliser pour exporter un handler
- les isFunction, isArray, ... de jquery sont bien sûr de la partie.
- vous trouverez aussi les inmanquables extend, each, inArray, merge, grep, map, function de jquery
mardi 18 octobre 2011
La façon de construire des UI évolue
Depuis quelques temps, je travaille sur un framework d’UI en .NET. Ce framework est potentiellement capable de générer une UI en n’importe quoi. Pour l’instant un rendu WPF et HTML sont implémentés. Ce dont je me suis aperçu en faisant de framework c’est que nos besoins d’UI ont évolués.
Les contrôles d’UI que nous voulons ne sont plus des contrôles bas niveau tels qu’un bouton ou un TextBox, mais des contrôles haut niveau : un contrôle Master-Detail, une toolbar. Je ne vais certainement pas m’attirer les bonnes grâces des designers et autres infographistes en disant cela, mais le design importe peu au final. Ce qui compte, c’est d’avoir un rendu fonctionnel.
Une application se décrit de manière fonctionnelle : un menu, une vue maître/détail, une fonction d’export de la vue maître… Le fait que le bouton se situe au-dessus de la grille ou dans un onglet contextuel d’un ruban, qui s’en soucie ? Ce qui importe, c’est d’avoir un comportement cohérent au sein d’une application, et si ce comportement peut être généralisé à toutes les applications existantes sur un OS, c’est encore mieux. C’est ce que commence à propose Microsoft avec son API WinRT. Une UI commune pour toutes les applications Metro.
Ce qu’il manque à .NET, c’est une uniformisation des interfaces. Avec le XAML, on tend effectivement vers cette uniformisation, mais le soucis, c’est qu’il ne s’agit pas d’une bibliothèque de contrôles identiques : Silverlight a la sienne, WPF aussi, WinRT, qui arrive, aussi. C’est là où intervient mon framework en cours de développement : 1 langage, des cibles différentes. J’ai tenté de pousser le concept à son maximum en proposant de n’avoir qu’une dll contenant l’UI, et c’est ensuite le projet que vous faites qui doit spécifier qu’il s’agit d’une application Web, Win, … Et voilà. Bien sûr, il ne s’agit là que d’une humble contribution, pleine de bugs à souhaits, manquant cruellement de fonctionnalité. Le but est principalement de démontrer le concept.
A mon avis, le développement d’application va prendre un nouveau tournant après la sortie de Windows 8, et je pense que la tendance sera à 1 langage => n plateformes, 1 plateforme => 1 UI uniforme. La seconde tendance a déjà émergé avec iOS ou WindowsPhone. Dans les best practices de développement d’UI (web principalement), on nous recommande toujours tester les fonctionnalités plutôt que de tester le moteur de rendu. N’est-ce pas une première étape vers un langage universel de création d’UI ? Est-il possible d’uniformiser toutes les UI sous un seul et même langage universel ?
jeudi 7 juillet 2011
Evaluant est Happly
Depuis le premier juillet 2011, Evaluant devient Happly. A partir de là, nous pouvons nous poser la question suivante : Qu’est ce que cela change ? La réponse pourrait se résumer à plein de choses et pas grand chose. Alors, un complément de précision est nécessaire :
- Ce qui change : un nouveau nom, de nouvelles ambitions et plus de moyens.
- Ce qui ne change pas : les mêmes équipes, les mêmes valeurs d’entreprise. En résumé, Happly restera le même acteur régional.
Repris de l’article de Philippe.
vendredi 1 juillet 2011
Marshalling en .NET, quelle galère !
Bonjour à tous,
Je n’ai pas consacré beaucoup de temps ces temps-ci au mon blog. Cela ne m’a pas empêché de travailler sur un projet perso. J’en avais déjà parlé à quelques collègues, mon but est de me faire un media center basé sur VLC en WPF. J’avais 3 idées en têtes :
- Intégrer sans WindowsFormsControlHost la vidéo de VLC pour pouvoir avec la puissance de WPF au niveau des transformations
- Avoir une interface Metro
- Avoir une interface Web/REST me permettant de contrôler mon Media Center (de la même façon que l’API sur la FreeboxHD)
C’est maintenant chose faite pour deux de ces trois tâches : une interface métro est assez simple à réaliser en WPF. Par contre, l’intégration de VLC l’est beaucoup moins. Avec l’aide d’un collègue qui a pas mal navigué dans le monde de la 3D, j’ai pu décortiquer le module direct3D de VLC et le reproduire en C#. VLC étant codé en C, il a fallu créer des délégués. J’ai voulu utiliser un wrapper tout fait comme vlcdotnet. Mais là encore, le wrapper bas niveau n’était encore pas réalisé comme il le fallait. Mais il m’a fallu vraiment beaucoup de temps avant de comprendre que mon problème venait du marshalling de .NET. un int* ne peut pas être marshallé en int[] parce que la taille n’est pas connue. Du coup j’avais un tableau de taille 1 alors que c’était un tableau de taille 5 sur VLC. Bref, cumuler des erreurs de marshalling sur 3 callbacks différents, ca fait beaucoup d’erreurs pour comprendre pourquoi ca marche pas…
vendredi 4 février 2011
EUSS en asynchrone !
Euss avance ! Désormais, les requêtes en asynchrones sont réalisable. En tout cas le moteur le plus basique d’euss (le moteur mémoire) les gère. C’est bientôt la fin de DataService
mardi 9 février 2010
Comment activer l’intellisense sur les fichiers javascript
Salut à tous,
Je viens juste de lire un post que j’ai pensé qu’il serait intéressant de partager. Vous avez tous certainement déjà entendu parler de jquery et du fait qu’avec la version 1.3, il y avait un fichier vsdoc que vous pouviez télécharger pour avoir l’intellisense lors de l’écriture de javascript avec jquery. Maintenant, un patch a été publié pour visual studio qui active le support des fichiers vsdoc. Pas seulement pour jQuery, mais pour n’importe quel fichier javascript.
Voici le lien vers le post original : http://blogs.msdn.com/webdevtools/archive/2008/11/07/hotfix-to-enable-vsdoc-js-intellisense-doc-files-is-now-available.aspx
Voici le lien vers le site de jquery où vous pouvez télécharger le fichier vsdoc : jQuery web-site (Cherchez “Documentation: Visual Studio”)
Bien-sur, il ne faut pas déployer le fichier vsdoc. Celui-ci est présent simplement pour une aide au développement…
jeudi 7 janvier 2010
Comment améliorer les performances de votre application intranet ASP.NET ?
Avez-vous déjà regardé le nombre de requêtes effectuées par une application web intranet ?J’insiste sur Intranet, parce que je parle des application utilisation l’authentification windows. Généralement, pour ce type d’applications, on les configure pour rejeter les utilisateurs anonymes. Cependant, cela implique que chaque fichier aura besoin d’une authentification, ce qui totalement faux : les fichiers javascript, css, images, … Tout ces fichiers ne devrait pas nécessiter d’authentification. C’est pourquoi, il faudrait autoriser les utilisateurs anonymes à y accéder.
Pourquoi désactiver l’authentification pour ces fichiers améliorerait les performances ? Tout simplement parce que l’authentification windows fonctionne sur le principe suivant : le navigateur envoie une requête en anonyme, le serveur réponds 401 (non autorisé), alors, et seulement à partir de ce moment, le navigateur envoie une nouvelle requête authentifiée, et vous pouvez maintenant récupérer le fichier. Cela veut dire qu’il y a 2 aller/retour pour récupérer un fichier. Cela fait sens pour les pages, mais pas pour les styles, les scripts ou les images. A mon avis, la “best-practice” serait de mettre les fichiers non sensible dans un dossier. Typiquement, le but serait d’utiliser la fonctionnalité de thèmes (même si vous n’avez qu’un seul thème).
Maintenant, nous arrivons à la partie pratique.
Pour chaque dossier contenant uniquement des données non sensible, vous devriez ajouter un fichier web.config contenant les lignes suivantes :
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<allow users="?"/>
</authorization>
</system.web>
</configuration>
C’est mieux maintenant, mais ce n’est pas suffisant. En effet, il y a aussi les resources script qui sont chargées par le ScriptManager. Puisqu’on ne peux pas rediriger simplement le chemin vers ScriptResource.axd et WebResource.axd, il faut appliquer les changement directement dans le web.config racine de l’application en ajoutant les lignes suivantes dans l’élément configuration racine :
<location path="WebResource.axd">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
<location path="ScriptResource.axd">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
J’espère que vous avez apprécié l’astuce. A bientôt
samedi 24 octobre 2009
Comment faire un proxy HTTP
Comme vous l’avez vu, j’ai récemment mis à jour mon projet codeplex zeroconf. Ce projet ne contient pas seulement l’implémentation du protocol DNS et du protocol Bonjour. Il contient aussi l’implémentation du protocol HTTP qui me permet d’envoyer des requêtes HTTP en UDP, chose qui n’est pas faisable avec l’implémentation du framework .NET. Au boulot, j’ai besoin de vérifier qu’une application que j’ai développé fonctionne correctement avec IE6( oui, ca existe encore… malheureusement). Puisque je suis sur Windows 7, je me suis dit que ca pourrait être super d’utiliser IE6 en application virtuelle. Je pense que vous voyer où je veux en venir. Sur une machine virtuel, on n’a pas accès au serveur de développement web démarré par visual studio. Ce que j’aurais pu faire, c’est déployer sur la machine virtuelle, ce qui veut dire, installer IIS, le configurer, passer du temps à vérifier le fichier web.config… Bref, pas une solution des plus simple à mettre en place. Alors, je me suis dit : Ce qu’il me faut, c’est un proxy, et j’ai déjà l’implémentation du protocole HTTP !
Voici le code du fameux proxy :
public class Proxy
{
RestServer proxy;
string hostToRedirectTo;
static void Main(string[] args)
{
Proxy p = new Proxy(ushort.Parse(args[0]), args[1]);
p.Start();
Console.ReadLine();
p.Stop();
}
private void Stop()
{
proxy.Stop();
}
private void Start()
{
proxy.StartTcp();
}
public Proxy(ushort portToListenOn, string hostToRedirectTo)
{
proxy = new RestServer(portToListenOn);
this.hostToRedirectTo = hostToRedirectTo;
proxy.HttpRequestReceived += proxy_HttpRequestReceived;
}
void proxy_HttpRequestReceived(object sender, HttpRequestEventArgs e)
{
e.Request.Host = this.hostToRedirectTo;
e.Response = e.Request.GetResponse(true);
e.Response.Body.Position = 0;
}
}
Comme vous pouvez le voir, la solution est très simple, et ne nécessite qu’une dizaine de lignes de code !!!
vendredi 23 octobre 2009
Bonjour mis à jour
Bonjour à tous,
J’ai mis à jour mon projet codeplex zeroconf. Le principal but de cette release est du refactoring. Ce project n’est pas seulement une implémentation de bonjour, mais contient aussi une implémentation de serveur. Avec cette implémentation de serveur, vous pouvez faire presque tout ce que vous voulez. Le seul désavantage, c’est que je ne gère pas les sessions. Pour comprendre de quoi je parle, je vous conseille de télécharger la dernière release de bonjour et de jeter un oeil à l’assembly Network.dll. Je vous promets que je fournirai un peu plus de documentation à ce sujet.
Vous pouvez déjà regarder la documentation sur le site du projet.
Amusez-vous bien !
mercredi 5 août 2009
Singleton réutilisable dépendant d'un context Http
Après avoir lu le post d'Ayende Rahien, je me suis dit qu'il fallait que je partage l'implémentation de mon module de singleton http que j'utilise depuis un certain temps maintenant. Ce module me permet avec très peu de lignes de codd d'avoir une seule instance de ce que je veux. Si comme Ayende, vous utilisez NHibernate, vous avez seulement d'hériter du code que je vais vous donner pour faire votre propre HttpSessionModule, et ainsi avoir une session créée HttpContext. Je l'utilise pour avoir non pas un ObjectContext (j'utilise euss), mais un service qui cache cette couche de persistence.
Voici l'implémentation abstraite de mon module de singleton Http :
public abstract class HttpSingletonModule<T> : IHttpModule
{
#region IHttpModule Members
public void Dispose()
{
}
public void Init(HttpApplication application)
{
application.PostAuthorizeRequest += new EventHandler(application_AuthorizeRequest);
application.EndRequest += new EventHandler(application_EndRequest);
}
void application_EndRequest(object sender, EventArgs e)
{
HttpApplication application = sender as HttpApplication;
HttpContext context = application.Context;
if (context != null)
{
T instance = (T)context.Items[typeof(T).AssemblyQualifiedName];
if (instance is IDisposable)
((IDisposable)instance).Dispose();
}
}
public static T Instance
{
get { return (T)HttpContext.Current.Items[typeof(T).AssemblyQualifiedName]; }
set { HttpContext.Current.Items[typeof(T).AssemblyQualifiedName] = value; }
}
void application_AuthorizeRequest(object sender, EventArgs e)
{
HttpApplication application = sender as HttpApplication;
HttpContext context = application.Context;
if (context != null)
context.Items.Add(typeof(T).AssemblyQualifiedName, CreateInstance(context));
}
protected abstract T CreateInstance(HttpContext context);
#endregion
}
Comme vous devez l'avoir compris maintenant, pour implémenter un module, c'est assez simple. Voici l'implémentation que j'utilise dans un projet :
public class PortalServiceModule : HttpSingletonModule<PortalService>
{
protected override PortalService CreateInstance(HttpContext context)
{
if (context.User.Identity.IsAuthenticated)
return new PortalService(context.User.Identity.Name);
return new PortalService();
}
}
Vous voyez ? Si peu de lignes de code pour une telle simplicité d'utilisation : pour récupérer l'instance de mon PortalService, j'ai juste à appeler la propriété static Instance de mon PortalServiceModule. Comment pourrait-on faire plus simple ?
vendredi 10 juillet 2009
ModalPopup paramétrée
Certains d'entres vous ont peut-être déjà eu le problème : ouvrir une fenêtre modale (en l'occurence avec AjaxControlToolkit), et pouvoir lui passer un paramètre, l'id du contrôle ayant ouvert la popup par exemple. Sachez que c'est entièrement possible, cela nécessite juste un peu de code. La première chose à savoir c'est qu'avec le framework AjaxControlToolkit, il existe une propriété BehaviorID sur tous les extenders. Cette propriété vous permet ensuite de manipuler cet extender côté client (en javascript, donc). Je vous propose de jeter un coup d'oeil sur le code avant les explications.
<asp:ModalPopupExtender runat="server" BehaviorID="myPopupBehavior"
PopupControlId="myPopup" TargetControlId="dummyLB" />
<asp:Panel ID="myPopup" runat="server">
<asp:HiddenField runat="server" ID="myParameter" />
</asp:Panel>
<asp:LinkButton ID="dummyLB" runat="server" style="display:none" />
<style type="text/javascript">
function openPopup(parameter)
{
$find("myPopupBehavior").show();
$get("<%= myParameter.ClientID %>").value=parameter;
}
</style>
Après avoir vu le code, je pense que vous avez besoin d'explications, et c'est tout à fait normal. Tout d'abord, la première chose à savoir, c'est qu'un extender AjaxControlToolkit a toujours besoin d'un TargetControlID. J'ai donc fait un LinkButton invisible pour l'utilisateur, mais qui est bien là pour ne pas faire planter l'application. La seconde chose à remarquer, c'est que dans le panel qui sera affiché, j'ai un champ caché (Hidden field). C'est ce dernier qui contiendra la valeur de mon paramètre. Pour affecter mon paramètre, j'ai donc fait une fonction javascript qui encapsule ce fonctionnement d'affectation de la valeur du champ caché. Ainsi, j'ai donc une fonction réutilisable à tout moment. Voici un exemple d'utilisation :
<a onclick="openPopup('http://www.google.fr')>lien vers google</a>
L'avantage de ce code est donc de pouvoir récupérer la valeur de votre paramètre côté serveur, puisque le champ caché est un contrôle serveur !
Voilà, j'espère que cet article vous aura plut.
samedi 6 juin 2009
jQuery Control Toolkit
Cela fait longtemps que je n'avais pas posté quelque chose sur mon blog, J'ai été légèrement occupé par mon travail. Mais ce travail me permet aujourd'hui de vous présenter un nouveau projet codeplex : jQuery Control Toolkit. Le but de ce projet est de permettre d'utiliser jQuery au travers d'extenders en ASP.NET, mais plus généralement de fournir des nouvelles fonctionnalités en tant que plugins jQuery. Ce projet n'est pas encore beaucoup détaillé, mais si vous ne pouvez pas attendre la description de chaque fonctionnalité, vous pouvez jetter un oeil dans le code source, il y a une application web qui utilise chaque fonctionnalité (principale). Il y a aussi plus de fonctionnalités dans le fichier source javascript jQuery.ACT.js, mais il n'est pas (encore) documenté.
Amusez-vous bien.
lundi 23 mars 2009
Powershell pour Visual Studio
Voilà mon nouveau projet : Powershell for Visual Studio. Vous pourrez déjà y trouver la coloration syntaxique, ainsi qu'un intellisense basique (cmdlets disponibles, avec leur aide). Actuellement, il semble que le SDK VS2008 soit requis pour le faire marcher. Ce sera résolu dans la prochaine version...
Amusez-vous !
Powershell for Visual Studio
mardi 24 février 2009
XNA Designer 0.1
J'ai mis à jour mon projet XNA sur codeplex. Maintenant, le concepteur fonctionne, il est (plus ou moins) beau. De plus, vous pouvez aussi télécharger une librarie de composants contenant : des caméras, un model viewer, un cube, un escalier, un mur, ...
Vous pouvez avoir un aperçu du concepteur sur la page d'accueil du projet.
Vous voulez l'essaeyer par vous même, allez télécharger la release.
vendredi 6 février 2009
Bonjour MEF
Vous connaissez MEF (Managed Extensibility Framework) ? C'est un framework permettant une meilleure réutilisation d'application et de composants. En utilisant MEF, les applications .NET peuvent être compilées statiquement et composée dynamiquement. Je vous laisser allez vois le site sur codeplex pour plus d'informations.
MEF est basé sur un principe de catalogue, il y a un DirectoryCatalog, un AssemblyCatalog, ... Eh bien, je suis fier de vous présenter un BonjourCatalog.
Pour cela, toujours la même adresse : http://www.codeplex.com/zeroconf. A quoi ça sert ? eh bien tout simplement à détecter les services bonjour en utilisant MEF.
Je n'ai pas encore fais de release concernant ce BonjourCatalog, mais ca ne saurait tarder.
mercredi 14 janvier 2009
Implémentation concrète du pattern Singleton en .NET
Un pattern que l'on retrouve assez régulièrement est le pattern singleton, je vous propose ici une implémentation .NET. Celle ci gère le fait que l'on veuille un singleton dépendant d'un contexte ou non (singleton par contexte ASP.NET, singleton par contexte WCF, singleton par Thread, singleton pour une application ASP.NET) :
public class Singleton<T>
{
private Singleton()
{
if (CreatingInstance != null)
CreatingInstance(this, EventArgs.Empty);
}
private static T instance;
[ThreadStatic]
private static T threadInstance;
private static object instanceLock = new object();
public static T Instance
{
get
{
//ASP.NET case
T instance;
if (HttpContext.Current != null)
{
if (UseContextInstance)
instance = (T)HttpContext.Current.Items[typeof(T).AssemblyQualifiedName];
else
instance = (T)HttpContext.Current.Application[typeof(T).AssemblyQualifiedName];
if (instance == null)
{
instance = new Singleton<T>().SingletonInstance;
if (UseContextInstance)
HttpContext.Current.Items[typeof(T).AssemblyQualifiedName] = instance;
else
HttpContext.Current.Application[typeof(T).AssemblyQualifiedName] = instance;
}
return instance;
}
if (OperationContext.Current != null)
{
throw new NotImplementedException();
if (instance == null)
{
HttpContext.Current.Items[typeof(T).AssemblyQualifiedName] = new Singleton<T>().SingletonInstance;
}
return instance;
}
//In case of no HttpContext nor OperationContext
if (UseContextInstance)
{
if (Singleton<T>.threadInstance == null)
Singleton<T>.threadInstance = new Singleton<T>().SingletonInstance;
}
else
{
if (Singleton<T>.instance == null)
{
lock (instanceLock)
{
if (Singleton<T>.instance == null)
Singleton<T>.instance = new Singleton<T>().SingletonInstance;
if (Singleton<T>.instance == null)
TryActivate(out Singleton<T>.instance);
}
}
}
return Singleton<T>.instance;
}
}
private static void TryActivate(out T p)
{
try
{
p = Activator.CreateInstance<T>();
}
catch (MissingMethodException) { p = default(T); }
}
public T SingletonInstance { get; set; }
public static event EventHandler CreatingInstance;
/// <summary>
/// Set this property to <see cref="true" /> to have your singleton dependant on your context :
/// - one per thread in Windows Forms/WPF
/// - one per Context in ASP.NET
/// </summary>
public static bool UseContextInstance { get; set; }
}