Archive

Posts Tagged ‘Extensions’

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

Advertisements

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.

%d bloggers like this: