Archive

Posts Tagged ‘Extensions’

How-to: get int value via ADO.net SqlDataReader using column name

Based on Sam Holder’s answer at https://stackoverflow.com/questions/7388475/reading-int-values-from-sqldatareader/54296026, just contributed an extension method for fetching Int32 values via ADO.net’s SqlDataReader, without jumping through hoops (aka first fetch column ordinal [number] by name, then fetching the int value passing the column ordinal).

Would be nice if Microsoft was providing such things out of the box.

namespace adonet.extensions
{
  public static class AdonetExt
  {
    public static int GetInt32(this SqlDataReader reader, string columnName)
    {
      return reader.GetInt32(reader.GetOrdinal(columnName));
    }
  }
}

and use it like this

using adonet.extensions;

//…

int farmsize = reader.GetInt32("farmsize");

assuming there is no GetInt32(string) already in SqlDataReader – if there is any, just use some other method name instead

OpenStreetMaps as an alternative to Google Maps in Joomla!

If you use Joomla! (CMS / Content Management System), you could switch to the free OpenStreetMaps instead of the recently-turned-much-more-expensive Google Maps, thanks to the OSModul extension for Joomla!:

https://extensions.joomla.org/profile/extension/maps-a-weather/maps-a-locations/osmodul/

At the bottom of this page there is an example that uses a pin icon similar to how a location would appear in Google Maps. And here is an example with multiple pins (shown as ships).

A shortcoming in comparison to Google Maps is that OpenStreetMaps doesn’t show by itself many Points of Interest (POI) on the map for one to get oriented easier. For example the maps for the location at (38.29399, 21.78592) shows up a little bare: https://www.openstreetmap.org/query?lat=38.29399&lon=21.78592 compared to the same location shown on Google Maps: https://www.google.com/maps/place/38°17’38.4"N+21°47’09.3"E/@38.29399,21.78592

So it is best to add some such characteristic locations apart from one’s location pin, as shown at: https://gitlab.com/schlumpf/osmodul/wikis/Additional%20Markers%20Pins

More information on the OSModul extension for Joomla! can be found at:

https://gitlab.com/schlumpf/osmodul

https://gitlab.com/schlumpf/osmodul/wikis/How%20to%20use

Suggestion: C# static extension methods invokable on class type too

it would be nice if C# supported syntax like:

public static DependencyProperty Register(static DependencyProperty x, string name, Type propertyType, Type ownerType, FrameworkPropertyMetadata typeMetadata)

that is static extension methods for classes, that can be invoked without a class instance (just with the class type), apart from normal extension methods that can be invoked on a class instance.

Then for example I could use it in Silverlight to add to its DependencyProperty class some extra WPF syntax that it currently misses, in order to increase code portability. It would wrap Dr.WPF’s implementation of value coercion for Silverlight’s DependencyProperty. I have the related code at my Compatibility library (http://Compatibility.codeplex.com) and respective NuGet package (http://nuget.org/packages/Compatibility), but the syntactic sugar is missing to achieve source code portability (via WPF and Silverlight projects that include common files via file links) without changes.

Note the "static DependencyProperty" parameter instead of the "this DependencyProperty" one that is used in C# extension methods (or else instead of static maybe they could use other keyword like type or typeof there, but I feel static is more appropriate).

Related discussion:

http://stackoverflow.com/questions/866921/static-extension-methods

http://stackoverflow.com/questions/249222/can-i-add-extension-methods-to-an-existing-static-class

Also see https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/2060313-c-support-static-extension-methods-like-f where somebody mentions "static extension properties" apart from "extension properties". Indeed it is natural that if static extension methods are to be allowed in the future, static extension properties should be added too (to extend a type with [attached] static properties)

You can vote for a related suggestion here:

https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/2060313-c-support-static-extension-methods-like-f

Visual Studio 2015 Extensions I use

Fix: VSIX installer error – SignatureDescription could not be created

This is my answer at:

http://stackoverflow.com/questions/31552082/vsix-installer-signaturedescription-could-not-be-created-for-the-signature-algo/

to the question on why some extensions fail to install at RC (Release Candidate) versions of Visual Studio 2015, showing error “SignatureDescription could not be created for the signature algorithm supplied”.

Not sure if Microsoft fixed this on purpose or by accident, but this is very useful for people who don’t have the time (and courage) to uninstall the RC version and reinstall the final one and all extensions they were using.

Speaking of reinstalling everything by hand, it would be nice if you could export an XML document containing a list of installed Visual Studio extensions and then be able to reimport it to install them all at an other Visual Studio installation (should also be able to edit that XML document to remove some if you wish, or at export see a checkbox list to deselect ones you don’t want exported in the resulting list).

To keep it short, the answer is:

Try installing http://go.microsoft.com/fwlink/?LinkID=619615 (found from http://blogs.msdn.com/b/somasegar/archive/2015/07/29/building-apps-for-windows-10-with-visual-studio-2015.aspx)

I used Custom installation option and selected everything. It upgraded Visual Studio 2015 Enterprise RC to Visual Studio 2015 Enterprise automatically and now those extensions that had started recently to not install, are installing fine. That way you’ll avoid the trouble of reinstalling everything.

Note that after installation finishes it shows a button to Launch Visual Studio, which will launch the Enterprise edition (or Professional in the case I guess one had Professional RC installed). However your Windows taskbar shortcuts for Visual Studio 2015 and Blend 2015 will be now broken and you have to fix them by right-clicking them and selecting Properties, then setting them to C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe and C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\blend.exe respectively, assuming you use an 64-bit OS – else remove the “ (x86)” part – and had installed Visual Studio on C: disk. You may wish to also add those links to the Start menu, under the respective folder (named Visual Studio 2015) if you also miss them from there.

HowTo: Use MEF to implement import/export etc. plugin architecture

Copying here my comment at a discussion on the GraphX project:

https://github.com/panthernet/GraphX/pull/15

in case it helps somebody in using MEF (Managed Extensibility Framework) in their software’s architecture

——–

Using static classes instead of interfaces can mean though that you need to use reflection to call them (e.g. if you wan to have a list of export plugins).

Instead can keep interfaces and make use of MEF to locate import/export and other plugins (you can have some class attribute there that mark the class as a GraphXExporter and MEF can be asked then to give you interface instances from classes that have that attribute.)

see usage at
http://clipflair.codeplex.com/SourceControl/latest#Client/ClipFlair.Windows/ClipFlair.Windows.Map/MapWindowFactory.cs

//Project: ClipFlair (http://ClipFlair.codeplex.com)
//Filename: MapWindowFactory.cs
//Version: 20140318

using System.ComponentModel.Composition;

namespace ClipFlair.Windows.Map
{

  //Supported views
  [Export("ClipFlair.Windows.Views.MapView", typeof(IWindowFactory))]
  //MEF creation policy
  [PartCreationPolicy(CreationPolicy.Shared)]
  public class MapWindowFactory : IWindowFactory
  {
    public BaseWindow CreateWindow()
    {
      return new MapWindow();
    }
  }

}

and at
http://clipflair.codeplex.com/SourceControl/latest#Client/ClipFlair.Windows/ClipFlair.Windows.Image/ImageWindowFactory.cs

//Project: ClipFlair (http://ClipFlair.codeplex.com)
//Filename: ImageWindowFactory.cs
//Version: 20140616

using System.ComponentModel.Composition;
using System.IO;

namespace ClipFlair.Windows.Image
{

  //Supported file extensions
  [Export(".PNG", typeof(IFileWindowFactory))]
  [Export(".JPG", typeof(IFileWindowFactory))]
  //Supported views
  [Export("ClipFlair.Windows.Views.ImageView", typeof(IWindowFactory))]
  //MEF creation Policy
  [PartCreationPolicy(CreationPolicy.Shared)]
  public class ImageWindowFactory : IFileWindowFactory
  {

    public const string LOAD_FILTER = "Image files (*.png, *.jpg)|*.png;*.jpg";

    public static string[] SUPPORTED_FILE_EXTENSIONS = new string[] { ".PNG", ".JPG" };

    public string[] SupportedFileExtensions()
    {
      return SUPPORTED_FILE_EXTENSIONS;
    }

    public BaseWindow CreateWindow()
    {
      return new ImageWindow();
    }

  }

}

then at
http://clipflair.codeplex.com/SourceControl/latest#Client/ClipFlair.Windows/ClipFlair.Windows.Base/Source/View/BaseWindow.xaml.cs

to get the first plugin that supports some contract (I get that contract name from the serialization file [using DataContracts]) for a loaded view, or that supports some file extension for a file dropped inside a component, I do:

    protected static IWindowFactory GetWindowFactory(string contract)
    {
      Lazy<IWindowFactory> win = mefContainer.GetExports<IWindowFactory>(contract).FirstOrDefault();
      if (win == null)
        throw new Exception(BaseWindowStrings.msgUnknownViewType + contract);
      else
        return win.Value;
    }

    protected static IFileWindowFactory GetFileWindowFactory(string contract)
    {
      Lazy<IFileWindowFactory> win = mefContainer.GetExports<IFileWindowFactory>(contract).FirstOrDefault();
      if (win != null)
        return win.Value;
      else
        return null;
    }

.NET String extension methods to check for array of prefixes or suffixes

Seems StartsWith and EndsWith methods of String class in .NET are missing a version that accepts multiple (as an array) prefixes or suffixes respectively when testing the string. To achieve this I just added the following extension methods to StringExtensions class (of Utils.Extensions namespace) under Utils.Silverlight project at the ClipFlair source code.

public static bool StartsWith(
this string s,
string[] suffixes,
StringComparison comparisonType = StringComparison.CurrentCulture) { foreach (string suffix in suffixes) if (s.StartsWith(suffix, comparisonType)) return true; return false; } public static bool EndsWith(
this string s,
string[] suffixes,
StringComparison comparisonType = StringComparison.CurrentCulture) { foreach (string suffix in suffixes) if (s.EndsWith(suffix, comparisonType)) return true; return false; }

 

To use them, you add a reference to Utils.Silverlight project to your own one and then add a using clause for the namespace that hosts a static class with these extension methods (e.g. “using Utils.Extensions;”) and then you can use them on any String at the respective source file. Can even use them on literal strings, since most .NET compilers support Boxing of literals into respective types.

I’m using a default value for the comparisonType method argument to make it optional. I use StringComparison.CurrentCulture as the default value for it (performing a word case-sensitive and culture-sensitive comparison using the current culture), as Microsoft is doing at “String.StartsWith(String)” method. However, do note the following text from that method’s documentation:

Notes to Callers

As explained in Best Practices for Using Strings in the .NET Framework, we recommend that you avoid calling string comparison methods that substitute default values and instead call methods that require parameters to be explicitly specified. To determine whether a string begins with a particular substring by using the string comparison rules of the current culture, call the StartsWith(String, StringComparison) method overload with a value of StringComparison.CurrentCulture for its comparisonType parameter.

.NET String class extensions to replace prefix or suffix

Just added the following extension methods to StringExtensions class (of Utils.Extensions namespace) under Utils.Silverlight project at the ClipFlair source code.

public static string ReplacePrefix(
this string s,
string fromPrefix,
string toPrefix,
StringComparison comparisonType = StringComparison.CurrentCulture) { return (s.StartsWith(fromPrefix, comparisonType)) ?
toPrefix + s.Substring(fromPrefix.Length) : s; } public static string ReplacePrefix(
this string s,
string[] fromPrefix,
string toPrefix,
StringComparison comparisonType = StringComparison.CurrentCulture) { foreach (string prefix in fromPrefix) if (s.StartsWith(prefix, comparisonType)) return toPrefix + s.Substring(prefix.Length); return s; } public static string ReplaceSuffix(
this string s,
string fromSuffix,
string toSuffix,
StringComparison comparisonType = StringComparison.CurrentCulture) { return (s.EndsWith(fromSuffix, comparisonType)) ?
s.Substring(0, s.Length - fromSuffix.Length) + toSuffix : s; } public static string ReplaceSuffix(
this string s,
string[] fromSuffix,
string toSuffix,
StringComparison comparisonType = StringComparison.CurrentCulture) { foreach (string suffix in fromSuffix) if (s.EndsWith(suffix, comparisonType)) return s.Substring(0, s.Length - suffix.Length) + toSuffix; return s; }

 

To use them, you add a reference to Utils.Silverlight project to your own one and then add a using clause for the namespace that hosts a static class with these extension methods (e.g. “using Utils.Extensions;”) and then you can use them on any String at the respective source file. Can even use them on literal strings, since most .NET compilers support Boxing of literals into respective types.

e.g.

s = s.ReplacePrefix("https://&quot;, "http://&quot;, StringComparison.OrdinalIgnoreCase);

//– converts https:// prefix to http:// ignoring character case

or

s = s.ReplacePrefix(new String[]{"https://&quot;, "http://&quot;}, "", StringComparison.OrdinalIgnoreCase);

//– removes https:// or http:// prefix ignoring character case

 

Update:

I added a default value for the comparisonType method argument to make it optional. I use StringComparison.CurrentCulture as the default value for it (performing a word case-sensitive and culture-sensitive comparison using the current culture), as Microsoft is doing at “String.StartsWith(String)” method. However, do note the following text from that method’s documentation:

Notes to Callers

As explained in Best Practices for Using Strings in the .NET Framework, we recommend that you avoid calling string comparison methods that substitute default values and instead call methods that require parameters to be explicitly specified. To determine whether a string begins with a particular substring by using the string comparison rules of the current culture, call the StartsWith(String, StringComparison) method overload with a value of StringComparison.CurrentCulture for its comparisonType parameter.

HowTo: Make Project Linker extension’s VSIX install at Visual Studio 2012

Project Linker is a Visual Studio Extension that “helps to automatically create and maintain links from a source project to a target project to share code that is common to Silverlight and WPF”.

In ClipFlair, where I have shared code between a Silverlight and a WPF project (I guess same would be for XNA projects for Xbox360 and for PC), a practice I use is to put shared files in a “Source” project and add them to both projects as links (using “Open as link” action available from Add file dialog if you press the dropdown arrow next to the “Open” button).

An alternative is to put such files in say the WPF project and use the Project Linker tool from Microsoft Patterns & Practices group to link to those files from the Silverlight project easily.

However, that tool seems to be only available for Visual Studio 2010, not for the newer 2012 version. Luckily, some users have posted a workarround at the discussion there (Reviews and Q&A tabs):

  1. Download the .vsix
  2. Extract contents with 7-Zip (since .vsix is a .zip file which you can see by renaming to .zip or .vsix.zip)
  3. Modify file with extension .vsixmanifest to add <visualstudio version="11.0"> to the <supportedproducts> node
  4. Change MaxVersion to <supportedframeworkruntimeedition minversion="3.5" maxversion="4.5" /> (this may not be necessary)
  5. Zip up contents again
  6. Rename extension back to .vsix
  7. Install extension

According to comments there, this works but not for all project types. It works if one links the Silverlight project to the WPF one, but not the other way around. It throws a NullReferenceException somewhere in the extension.

Single statement ScaleTransform initialization in both WPF and SL

With Silverlight using a cut-down .NET API, some decisions have been at least ackward, causing Silverlight code to be sometimes unnecesserily more complex than its WPF counterpart and WPF code needing several changes to get ported for Silverlight. In ClipFlair I’ve implemented a WPFCompatibility layer to ease compiling WPF code for Silverlight (and vice-versa too) without source code changes.

One of the missing things from Silverlight is at ScaleTransform class, where only a parameterless constructor is available. That way, whereas in WPF you can construct a ScaleTransform and initialize it in one statement, in Silverlight you need to first construct the transform and then set its X scale and Y scale in two separate (property setter) statements. Obviously this also has a small cost in performance since you end up with 3 method calls instead of a single one.

That is the WPF statement

ScaleTransform t = new ScaleTransform(someXscale, someYscale);

has to be translated in Silverlight to:

ScaleTransform t = new ScaleTransform();
t.ScaleX = someXscale;
t.ScaleY = someYscale;

 

In WPF_ScaleTransform.cs file at WPF_Compatibility project, I provide two different approaches to aid in more portable code that uses ScaleTransform:

 

1) The first approach is to create a method named “new_ScaleTransform” that takes X & Y scale parameters and returns a new ScaleTransform object and use it instead of calls to ScaleTransform’s constructor that takes X and Y scale.

    public static ScaleTransform new_ScaleTransform(double scaleX, double scaleY) //unfortunately there are is no extension method mechanism for contructors in C# yet (and the ScaleTransform class is sealed so we can’t create descendent class)
    {
      ScaleTransform result = new ScaleTransform();
      result.ScaleX = scaleX;
      result.ScaleY = scaleY;
      return result;
    }

Since WPF_Compatibility uses two separate projects WPF_Compatibility.WPF and WPF_Compatibility.Silverlight that share the same source files (added as file links from a common Source subfolder instead of copied into the projects), there is an extra optimization that I decided to do, using a conditional compilation statement so that in WPF we use more optimal code:

public static ScaleTransform new_ScaleTransform(double scaleX, double scaleY) //unfortunately there are is no extension method mechanism for contructors in C# yet (and the ScaleTransform class is sealed so we can’t create descendent class)
{
#if SILVERLIGHT
  ScaleTransform result = new ScaleTransform();

  result.ScaleX = scaleX;
  result.ScaleY = scaleY;
#else
  ScaleTransform result = new ScaleTransform(scaleX, scaleY);
#endif 
  return result;
}

So, with the above approach one will be able to write in both WPF and Silverlight (assuming they add a “Using WPF_Compatibility;” to the top of their C# source file):

ScaleTransform t = new_ScaleTransform(someXscale, someYscale);

 

2) The second approach is to create a (static) extension method (called SetScale) for the ScaleTransform class and have that method accept X and Y scale params (apart from the implicit ScaleTransform object), which, after setting X and Y scale, should return the ScaleTransform object so that one can construct a ScaleTransform with the parameterless constructor and daisy chain a call to the SetScale method in the same statement. Since that method returns the ScaleTransform object that was passed to it (after setting X and Y scale to it), the combination behaves like a parametric constructor.

public static ScaleTransform SetScale(this ScaleTransform transform, double scaleX, double scaleY)
//can use this in both WPF and Silveright (the last one misses a parametric
//constructor) to initialize on the same statement on which we construct the
//ScaleTransform
{
  transform.ScaleX = scaleX;
  transform.ScaleY = scaleY;
  return transform; //return the transform so that it can be used in the form
  ScaleTransform t = new ScaleTransform().SetScale(scaleX, scaleY)
}

After you import the namespace WPFCompatibility (via the using statement mentioned above), where the WPF_ScaleTransform static class belongs, you can make use of this static extension method like below:

ScaleTransform t = new ScaleTransform().SetValue(someXscale, someYscale);

As an added bonus, an extra extension method is provided to set both the X and Y scale from a single parameter:

public static ScaleTransform SetScale(this ScaleTransform transform, double scale)
{
  return transform.SetScale(scale, scale);
}

Update:

In recent versions of C# (not sure if VB.net has such a feature) you can initialize multiple properties for a  new instance  in a single statement at the time of construction, so I have updated the “new_ScaleTransform” method like below. It still works at both WPF and Silverlight, while both get a single-line statement (the WPF version should still be the fastest, even though both are now one-liners).

public static ScaleTransform new_ScaleTransform(double scaleX, double scaleY)
//unfortunately there are is no extension method mechanism for contructors
//in C# yet (and the ScaleTransform class is sealed so we can't create
//descendent class)
{ #if SSILVERLIGHT
ScaleTransform result =
new ScaleTransform() { ScaleX = scaleX, ScaleY = scaleY }; #else ScaleTransform result = new ScaleTransform(scaleX, scaleY); #endif return result; }
%d bloggers like this: