Skip to main content

Le singleton le plus court au monde s’écrit en C#

Depuis des années, j’écris des singletons avec le code suivant :


private static readonly MyClass Instance;

/// <summary>
/// Constructeur static
/// </summary>
static MyClass()
{
    // Instantiation du singelton
    Instance = new MyClass();
}

/// <summary>
/// Instance courante unique
/// </summary>
public static MyClass Current { get { return Instance; } }

/// <summary>
/// Constructeur privé
/// </summary>
private MyClass()
{
}

Mon singleton n’étant jamais supprimé, il n’est donc pas besoin d’être vérifié et instancié lors du Get. Je n’utilise pas de lock pour l’instanciation, car mon instance est créée via le constructeur statique (celui-ci ne peut être appelé qu’une fois).

Avec les dernières optimisations et simplifications de C# (propriétés privées en lecture seule), mon Singleton est devenu toujours plus court (2 lignes spécifiques):


/// <summary>
/// Constructeur statique
/// </summary>
static MyClass()
{
    // Instantiation du singelton
    Current = new MyClass();
}

/// <summary>
/// Instance courante unique
/// </summary>
public static MyClass Current { get; }


/// <summary>
/// Constructeur privé
/// </summary>
private MyClass()
{
}

À quand le Singleton en une ligne ?

Jérémy Jeanson

ALINK et x64 : L'assembly référencé 'mscorlib.dll' cible un processeur différent

Peut-être avez-vous déjà rencontré le warning suivant :

L'assembly référencé 'mscorlib.dll' cible un processeur différent


Celui-ci se produit sur des projets exploitant des fichiers .resx quand on veut les compiler en 64 bits.

Un très vieux problème à l’époque de Visual Studio 2010 provoquait le même warning. En furetant ici et là sur le web on peut trouver diverses solutions plus ou moins compliquées pour résoudre ou contourner ce warning. Mais l’ensemble de ces solutions mixées ou mises bout à bout ne fonctionne pas sur Visual Studio 2017 (ou alors elles incluent des manipulations inutiles).

Pour résoudre le problème, il faut que le projet concerné indique à Visual Studio où se trouve le SDK en version 64 bits (c’est là que se trouve l’utilitaire dont Visual Studio 2017 a besoin lors de la compilation). Il se trouve que la seule différence entre la version 32, et la version 64 est qu’il faut ajouter x64 au nom du dossier en version 64 bits.

L’information doit être ajoutée en toute fin du fichier .csporoj (juste avant la balise fermante </Project> ).


<Target Name="Resx" BeforeTargets="BeforeBuild" >
  <PropertyGroup Condition="'$(Platform)'=='x64'">
    <TargetFrameworkSDKToolsDirectory>$(TargetFrameworkSDKToolsDirectory)$(Platform)\</TargetFrameworkSDKToolsDirectory>
  </PropertyGroup>
</Target>

Description de la modification :

  • Target a une propriété Name donnée en rapport avec le problème à résoudre. Mais on peut très bien lui donner un autre nom (du moment qu’il n’est pas déjà utilisé ou qu’il ne s’agit pas de BeforeBuild ou AfterBuild)
  • Target a un attribut BeforeTargets égale à BeforeBuild, car l’information doit être disponible avant la build.
  • PropertyGroup a une Condition pour n’utiliser les porpiétés qui suivant qu’avec la compilation en 64 bits.
  • TargetFrameworkSDKToolsDirectory est le chemin que l’on veut définir.


Je n’ai pas fourni de liens vers des solutions similaires, car comme évoqué plus haut, elles ne concernent pas de cas, ou incluent plus de modifications que nécessaire.

Jérémy Jeanson

Problèmes de compatibilité entre Entity Framework et le Multilingual App Toolkit ?

Entity Framework et le le Multilingual App Toolkit  (MAT) utilisent tous deux les fichiers de ressources :.

  • EF les utilise pour garder des traces des migrations.
  • MAT les utilise pour trouver les informations à localiser.

EF et MAT sont compatibles?

Si les deux sont utilisées dans un même projet, il est utile de prendre une précaution simple :

  • Pour chaque fichier .xlf manipuler par MAT, il faut marquer les informations de EF comme n’étant pas à traduire.
  • Un fichier de rexs est produit par MAT pour chaque migration. Il est vide, mais ne faut pas le supprimer.

MAT et EF sont alors compatibles.

Où est le problème?

Malgré cela, il peut arriver que le MAT fasse remonter des warnings du type :

Warnings liés à MAT


Côté migration, il manque effectivement des fichiers .fr-FR.resx (2 sur 4).

Liste de fichier produits pour la migration Entity Framework

Dans ce cas, le MAT indique que des ressources ne sont plus présentes. Un développeur les a peut être supprimées par erreur.

Comment s’en sortir?

Pour s’en sortir, il faut créer un fichier fr-FR.rex pour chaque fichier manquant (si cela est possible, aller les chercher dans TFS).

Le fichier peut être créé en faisant une copie du fichier d’origine.

Ensuite, il faut bien vérifier que le fichier fr-FR.xlf indiqué, les ressources sont bien indiquées comme n’étant pas à traduire.

Liste de données marquées comme n'étant pas à traduire


Peut-on avoir une approche plus propre?

Il existe une solution qui n'est pas documentée, mais qui est expliquée sur le Uservoice de MAT. Elle consiste à marquer les fichiers que MAT doit ignorer.

Pour cela il faut ouvrir son fichier .csproj et modifier à la main les noeuds EmbeddedResource qui concernent un fichier à exclure. Pour chaque noeud, on ajoute <SuppressAutomaticLocalization>true</SuppressAutomaticLocalization>.

Noeuds xml à modifier

Moralité

Toujours être vigilant et méthodique quand on utilise des technologies qui exploitent le même type de solutions pour des usages bien différents.

Bien évidemment, l'approche la plus simple consiste à isoler les ressources à localiser dans une autre assembly. Ainsi MAT ne cherchera pas à interagir avec un fichier qui n'est pas à localiser.

Jérémy Jeanson

Erreur de redirection de version de System.Net.Http

Peut-être avez-vous un souci récurant avec System.Net.Http qui fait qu’à chaque mise à jour de vos packages nuget, votre configuration n’est plus bonne.

Votre librairie System.Net.Http en version 4.3.3 devrait inclure une redirection vers l’assembly 4.2.2.0, mais celui-ci change pour une autre valeur.

Dans l’idéal votre configuration contiendrait ceci :


<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
   <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0"/>
</dependentAssembly>

Mais devient régulièrement :


<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
   <bindingRedirect oldVersion="0.0.0.0-4.1.1.2" newVersion="4.1.1.2"/>
</dependentAssembly>

Le numéro 4.x.x.x peut varier

Pas terrible comme situation. Plutôt que de pester après Visual studio, il serait bon de jeter un œil aux warnings de votre solution.

Il est fort probable que vous ayez un message de la sorte :

Liste de warnings liés à la configuration

Pour s’en sortir, il suffit de suivre la consigne indiquée. On sélectionne la ligne de warning et on valide la correction via la touche Enter de son clavier (le double click fonctionne aussi). Ce qui affichera la boite de dialogue suivante :

Question préléminaire à la correction du fichier de configuration

Après validation, votre fichier de configuration contiendra les redirections manquantes et vous ne rencontrerez plus de problèmes avec System.Net.Http.

Moralité

Toujours laisser visibles les warnings, et prendre le temps de les lire pour les résoudre. Les cacher, c’est mal !

Un projet qui est stable et qui s’inscrit dans le temps n’a pas de warnings.

Jérémy Jeanson

Alertes invisibles avec bootstrap 4 ?

Si vous utilisez un code tel que celui-ci avec bootstrap 3, vos alertes seront invisibles quand vous migrerez vers bootstrap 4.


<div class="alert alert-info fade in">
...
</div>

Voici un petit problème tout simple qui m’a déjà été remonté une paire de fois. Je présume que la documentation de la migration de bootstrap 3 à 4 n’est pas suffisamment explicite.

Il y a en fait une classe qui a changé de la version 3 à la version 4. On ne doit plus utiliser in, mais show.

Ce qui donne :


<div class="alert alert-info fade show">
...
</div>

On peut voire son usage dans la documentions des alertes (section Dismissing).

Jérémy Jeanson

Cookies Cookie Policy

This website uses cookies and similar technologies to allow us to promote our services and enhance your browsing experience. If you continue to use this website you agree to our use of cookies.