vendredi 29 mars 2013

FDLV va lancer son application Windows Phone 7 !

Edit : FDLV était une erreur de jeunesse ... A oublier :) FDLV S'apprète à lancer son application mobile pour le bien-être de ces utilisateurs. Il sera alors possible de trouver un restaurant, un bar lounge, un vendeur de cigare ou un détaillant en vin et spiritueux dans tout le Luxembourg, et ce, en géolocalisé bien sur ! Chaque utilisateur pourra alors noter ces établissements le plus simplement du monde et permettra de centraliser les notations de tous les utilisateurs ! Pour les détails techniques, cette application est développée sous Windows Phone 7, avec un petit coup de pouce de Galasoft pour MVVM coté client et Entity Framework (dont la sortie 4.1 RTW est très récente) pour le coté serveur :)

Original article available at http://www.alphablog.org

Développement Windows Phone 7

Map ElementZ Lancement officiel du site référençant mes développement windows phone 7. http://www.company.alphablog.org/ En préparation : un tower defense nommé ElementZ. Les vidéos sont disponible pour démontrer le path finding et le système de niveau des tours. N'hésitez pas à me poser des questions ou à demander des fonctionnalités !

Original article available at http://www.alphablog.org

Velocity, le cache distribué selon Microsoft

Velocity (nom de code du projet) est un principe de cache distribué qui peut être attaqué par des programmes .Net. Vous pouvez donc l'utiliser sur votre site Web, sur une application serveur distribué ou sur toute autre implémentation ... Il sera généralisé dans peu de temps afin de l'offrir aux développeurs mais se rendra aussi disponible sur Azure. Une fois l'installation effectuée (principe d'un maitre et de plusieurs esclaves), on peut alors manager le cache par un power shell. Selon les dire, il sera disponible une interface pour la sortie officielle. Pour le coté développement, on ajoute simplement les assemblies au projet pour utiliser le cache. C'est une cache de type "Key - Value" qui peut stocker n'importe quel type d'objet .Net. Il est bien sur disponible un procédé de duplication et de reprise sur erreur ainsi qu'un système de versionning basique pour gérer les "conflits" que l'on peut imaginer avec l'aspect distribué. Le plus intéressant dans ce projet est la vision future. Il sera bientôt possible de le requeter avec du LinQ. Il sera aussi possible de lui intégrer du code exécutif ce qui permettra de faire passer la couche d'accès aux données par ce cache... On peut alors imaginer que la persistance passera par cette cache qui se chargera automatiquement et "au besoin" de persister les données dans la base. La possibilité d'avoir un "cache client" qui déleste un peu le serveur et qui permet une application cliente plus rapide, plus réactive et avec moins d'accès au réseau. Pour l'instant c'est disponible par exécutable séparé mais la version assembly sera bientôt disponible. A cela s'ajoute la possibilité de brancher des évènements pour prévenir le client de modification sur le cache du serveur. Pour ce qui est du transport, le cache s'appuie sur la technologie WCF, il est donc possible d'y ajouter (par simple modification d'un fichier de configuration) toute les sécurités et protections proposés par WCF. (Article aussi posté sur www.homonerdicus.com)

Original article available at http://www.alphablog.org

Multiple jointures sur Oracle 10g avec NHibernate

Quelques posts parlent d'un bug survenant avec oracle 10g et NHibernate lors d'une jointure multiple.

Survient alors une erreur "ORA-00904". Une fois le code SQL généré lu, on se rend compte que les jointures suivant une virgule sont alors incapable d'utiliser des valeurs déclarées dans le Select.
left outer join "City" city2_ on address1_.City_id=city2_.Id, "Country" country6_  left outer join Provider_Specialities specialiti3_ on provider0_.Id=specialiti3_.Provider_id
donc l'utilisation de provider0_.Id dans le second join est invalidé par le "," du premier join. Le code incriminé se situe dans le fichier Oracle10gDialect.cs dans NHibernate.Dialect. En voici son code :
public class Oracle10gDialect : Oracle9iDialect  {      public override JoinFragment CreateOuterJoinFragment()      {          return new ANSIJoinFragment();      }  }
Le workaround le plus simple à mettre en place est de changer le dialect de votre SessionFactory de Oracle10 vers Oracle9.

Original article available at http://www.alphablog.org

Injecter des Mocks via IOC (NInject et Rhino Mocks)

Voici une de mes publications (code développé avec Lionel Molas) sur un site de programmation en collaboration avec des amis : http://www.homonerdicus.com/ Le lien vers l'article est celui ci : http://www.homonerdicus.com/?p=17 Attention, ce post s'adresse aux gens qui savent ce qu'est de l'IOC et du Mocking :) Bonne lecture !   En voici une version copiée : Bonjour à tous, Voici un petit post expliquant l'intégration quasi-parfaite de Rhino Mocks avec NInject. Pour rafraichir les esprits, NInject est un framework d'IOC et donc d'injection de dépendance. Il permet l'injection de classes et autorise donc un fort découplage dans votre application. Rhino Mocks est quand à lui un framework fortement lié au contexte du test. Il permet, lors d'un test unitaire, de "bouchonner" une brique en cours de test afin d'isoler celle ci et donc de garantir sa testabilité "unitaire". Le but de cet article est de concevoir une application à faible couplage, avec NInject, et facilement "Mockable" avec RhinoMock. Afin de comprendre cet article, il est fortement conseillé de connaitre le principe de Mock, d'injection et l'utilisation de Rhino Mocks.

Contexte

Dans notre projet de test, NInject est installé coté serveur. Il met en relation les différentes classes en garantissant un fort découplage. Arrive la partie des tests unitaires. Nous décidons de mettre Rhino Mocks afin de bien "unitariser" les tests. Seul problème, les dépendances sont injectées en cours d'exécution. Il faut donc demander à NInject d'injecter du Rhino Mocks. Les versions utilisés sont Rhino Mocks 3.6 et NInject 2.0 Compréhension par l'exemple : Exemple de classe métier injectée avec NInject :
public class FileDAO : IFileDAO
   {
       [Inject]
       private IFileDAL _fileDAL { get; set; }
         public virtual File AddFile(string name, FileType fileType, byte[] contentFile)
       {
           //Some stuff here that use _fileDAL
       }
         public virtual bool DeleteFile(long index)
       {
           //Some stuff here that use _fileDAL
       }
   }
Sur le code ci dessus nous remarquons que la variable _fileDAL est injecté par NInject (on le remarque par le tag [Inject]) lors de la création d'une instance de la classe.
public void AuthenticateTest()
  {
      //Creation of the mock
      IUserDAO = _userDAOMock = Repository.StrictMock()
        //Usefull data for test
      string login = "toto@toto.com";
      string password = "titi";
      Employee user = new Employee(login, password);
        //Record what will be called and what will be returned
      using (NInjectMockProvider.Repository.Record())
      {
          Expect.Call(_userDAOMock.GetEmployee(login, password)).Return(user);
      }
        //Start the "playback" feature.
      using (NInjectMockProvider.Repository.Playback())
      {
          bool authOK = loginService.Authenticate(login, password);
            //Verify that everithing has been properly called
          _userDAOMock.VerifyAllExpectations();
          //Check if the test is OK 
         Assert.IsTrue(authOK);
      }
  }
Sur le code ci dessus, nous voyons les quelques étapes essentielles de l'utilisation de Rhino Mocks :
  • Mise en place des données de test
  • Enregistrement du comportement du mock
  • Lancement de la séquence de test
  • Vérification que l'enregistrement correspond bien au comportement appelé et vérification des résultats.
Le but de cet article est donc de s'abstraire de cette ligne :
IUserDAO _userDAOMock = Repository.StrictMock<IUserDAO>();
Comme nous injectons aussi dans nos classes testées, il nous faudrait procéder à l'injection des mocks par NInject.

Don't fight NInject !

Pour paraméter l'injection, NInject s'appuie sur une classe dérivée de la classe abstraite NinjectModule ou il suffit de surcharger la fonction Load() afin de définir les bindings sous la forme :
Bind<IUserDAO>().To<UserDAO>().InSingletonScope();
Ninject nous donne la possibilité d'ajouter un "Provider" qui fournirait donc l'instance de la classe. L'utilisation parfaite dans notre cas serait :
Bind<IUserDAO>().ToProvider<NInjectMockProvider<IUserDAO>>();
Nous indiquerons alors à NInject d'injecter un Mock pour des IUserDAO. Nous unifions donc le provider NInject avec la factory Rhino Mocks ! Que fait ce provider ?
public class NInjectMockProvider<T> : IProvider where T : class  {      //References to the MockRepository      public static MockRepository Repository = new MockRepository();      //Static dictionnary that allow to create a Mock by kernel      private static Dictionary<int, object> allItems = new Dictionary<int, object>();        public object Create(IContext context)      {          return CreateInstance(context);      }        //Say Ninject what type we are injecting      public Type Type      {          get { return typeof(T); }      }        //Create the mock or return the mock already created      private T CreateInstance(IContext context)      {          int temp = context.Kernel.GetHashCode();          if (!allItems.Keys.Contains(temp))          {              allItems.Add(temp, Repository.StrictMock<T>());      }      return allItems[temp] as T;  }
Ce qu'il faut retenir de ce provider-factory :
  • Il est configuré en injection Singleton by-design. Nous n'avons pas creusés plus loin, cela couvrait nos besoins
  • Il simule auprès de NInject l'injection d'une classe abstraite
  • Il s'occupe de la création des mocks typés.
Nous pourrions améliorer son fonctionnement en gérant les types d'injections (singleton, par thread, "OnePerRequest") par exemple.

Références :

Ninject Dojo Rhino Mocks documentation

Spécial Thanks to :

Lionel Molas, pour le peer-programming qui nous a permit de trouver la solution ainsi que son idée de publier la solution !

Original article available at http://www.alphablog.org