InternetException

About coding and whatnot.

Visual Studio code snippets

clock February 25, 2014 12:39 by author n.podbielski

What I really like in Visual Studio as development environment is code snippets. Well actually probably other IDE have something very similar but I do not have much of a choice in that matter as C# developer :)
Anyway this feature is really useful. For example while refactoring I very often use if surround snippet.

Unfortunately there are no easy way to edit/add new snippets since VS do not have built in snippets editor. But their syntax is almost XML and quite simple. I will cover few simple examples in this short article.

Ok. Let's start with what we have in VS. There is Code Snippets Manager available Tool menu.

 

There is not much we can do in that window: add or remove snippets directory or import single snippets. In my opinion only real useful feature is possibility to check where we can find existing snippets. Also I do not recommend to add new folders because of extra need to specify search directory when we search for desired snippet after using insert snippet Visual Studio shortcut (Ctrl K, X by default for Visual C# environment setting). For example when selecting for surround statement in Java Script; after adding new folder we have to choose folder before we choose snippet, which is waste of time for me.

 Ok. Let's try a simple example. While developing in Java Script it is good idea to use Require JS or other AMD library.
 It would be really painful to write every time same formula for new JS module. Instead it is better to create code snippet. Using Code Snippets Manager we can obtain directory in which JS snippets resides. By default this is: C:\Program Files (x86)\Microsoft Visual Studio 11.0\JavaScript\Snippets\1033\JavaScript for VS 2012.

Desired code for starting a new module for me was:

define([''],
    function (dep) {	
        return new function () {
			//private variables
			//private functions
			//public functions
			$selected$$end$
			//globals
			//onload
		};
    });

To define code snippet with above template we have to create new file {name}.snippet in above directory.

File contents should be similar to following:

  
<CodeSnippet Format="1.1.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <Header>
    <Title>module</Title>
    <Author>Natan Podbielski</Author>
    <Shortcut>mdl</Shortcut>
    <Description>Code snippet Require JS module</Description>
    <SnippetTypes>
      <SnippetType>Expansion</SnippetType>
      <SnippetType>SurroundsWith</SnippetType>
    </SnippetTypes>
  </Header>
  <Snippet>
    <Code Language="JavaScript"><![CDATA[
define([''],
    function (dep) {	
        return new function () {
			//private variables
			//private functions
			//public functions
			$selected$$end$
			//globals
			//onload
		};
    });
]]></Code>
  </Snippet>
</CodeSnippet>

Keep in mind that white space in <Code> tag are very meaningful and should look exactly like it should look in destination code in VS. With file like this you can use it in VS. Press insert snippet shortcut in JS file. You should see something like this (sometimes it is necessary to open Code Snippets Manager or restart VS to force to reread all snippets):

 

 

 

Quick explanation about tags:

<Title> is a title that is shown in Code Snippet Manager and 'select snippet menu'.

<Author> is an author of the snipper. Visible in Code Snippet Manager.

<Shortcut> is a string of characters you have to type which make available to you Tab shortcut which will expand typed characters into desired code from snippet. Like ctor is a shortcut for built in VS constructor snippet.

<Description> is a description visible from Code Snippet Manager and from 'select snippet menu'.

<SnippetTypes> is an enumeration of snippet type. There is only two types of snippets: Expansion and SurroundsWith. With <SnippetType> tag you can decide which is it and from what menu or shortcut it will be available.

<Code> is an actual code for snippet. Should be 1 to 1 to desired code. Besides snippets variables which I will describe bellow.

 

You should be very specific about white space, indentation of code of snippet (about syntax too of course but it is obvious) etc. It is better to write it right once in snippet than correct it every time you use it :)

There are available plenty of variables inside of snippet. They are defined like $name$ inside actual code.

Most important for example for surround type of snippets is variable $selected$, which describe where VS should put text that you selected before inserting desired template. $end$ specifies when cursor should be after inserting snippet. It is useful for snippets that you should populate with specific code, method for example: you should write method body so this is useful to put $end$ inside method body. There are some variables defined by snippet engine, like $classname$, which is current class name. You can also defines your own variables, which then can be easily changed while using snippet. Consider built in snippet for property with backing field: propfull.

It has declaration as follows:

		<Snippet>
			<Declarations>
				<Literal>
					<ID>type</ID>
					<ToolTip>Property type</ToolTip>
					<Default>int</Default>
				</Literal>
				<Literal>
					<ID>property</ID>
					<ToolTip>Property name</ToolTip>
					<Default>MyProperty</Default>
				</Literal>
				<Literal>
					<ID>field</ID>
					<ToolTip>The variable backing this property</ToolTip>
					<Default>myVar</Default>
				</Literal>
			</Declarations>
			<Code Language="csharp"><![CDATA[private $type$ $field$;

	public $type$ $property$
	{
		get { return $field$;}
		set { $field$ = value;}
	}
	$end$]]>
			</Code>
		</Snippet>

Declaration of variables $type$ and $field$ allow us to write name of field and type of field and property one time in one place:

 

Changing myVar for something more meaningful and submitting a snippet will change highlighted places with myVar value inside snippet code too. Pretty useful!

As you can see in actual declaration of snippet variables there is possibility of setting default value and tool tip so and end user could know what we meant for variable while creating a template. There is a really world of possibilities from such snippets. If we using some kind of elaborate code structures inside of our project (custom data contracts for example, or ASP.NET custom controls etc.) it is best to create snippets for them. Or for other broadly used code samples.

For example I created snippet for jQuery ready function:

 <CodeSnippet Format="1.1.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <Header>
    <Title>jQuery ready</Title>
    <Author>Natan Podbielski</Author>
    <Shortcut>docrd</Shortcut>
    <Description>Code snippet for jQuery document ready event</Description>
    <SnippetTypes>
      <SnippetType>Expansion</SnippetType>
      <SnippetType>SurroundsWith</SnippetType>
    </SnippetTypes>
  </Header>
  <Snippet>
    <Code Language="JavaScript"><![CDATA[$$(function(){
	$selected$$end$
});]]></Code>
  </Snippet>
</CodeSnippet>

Important: as you can see above to achieve $ inside destination code (after using a snippet inside VS) you have to escape it with $, so jQuery $ becomes $$ inside snippet code declaration!

Or for console.log(); JS function, which is very similar but with <Code> tag like this:

 <Code Language="JavaScript"><![CDATA[console.log($end$);]]></Code>

I hope this will help in your journey into VS code snippets world. :)



Entity Framework Patterns extension and Unit Test in Visual Studio 2012

clock April 23, 2013 02:18 by author n.podbielski

Yesterday I was trying to make work simple test class in VS2012. I did not know what was wrong exactly. It was first project when I tried to glue together Entity Framework with repository pattern and Ninject as IoC container. Because of the fact that this was first time for solution like that I was sure that it is me, or rather source of my problem was indeed my code. But let's not skip ahead.

So when I manage to translate adding EF classes to Unity from here: IoC : using EntityFramework.Patterns with Unity 2.1 into Ninject language. I got error like this from VS (when tried to running test case):


Result Message:    Unable to create instance of class UnitTest. Error: System.IO.FileLoadException: Could not load file or assembly 'EntityFramework, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040).
Result StackTrace:   
at System.Signature.GetSignature(Void* pCorSig, Int32 cCorSig, RuntimeFieldHandleInternal fieldHandle, IRuntimeMethodInfo methodHandle, RuntimeType declaringType)
   at System.Signature..ctor(IRuntimeMethodInfo methodHandle, RuntimeType declaringType)
   at System.Reflection.RuntimeConstructorInfo.GetParametersNoCopy()
   at System.Reflection.RuntimeConstructorInfo.GetParameters()
   at Ninject.Injection.DynamicMethodInjectorFactory.EmitLoadMethodArguments(ILGenerator il, MethodBase targetMethod) in c:\Projects\Ninject\ninject\src\Ninject\Injection\DynamicMethodInjectorFactory.cs:line 115
   at Ninject.Injection.DynamicMethodInjectorFactory.Create(ConstructorInfo constructor) in c:\Projects\Ninject\ninject\src\Ninject\Injection\DynamicMethodInjectorFactory.cs:line 40
   at Ninject.Planning.Strategies.ConstructorReflectionStrategy.Execute(IPlan plan) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Strategies\ConstructorReflectionStrategy.cs:line 67
   at Ninject.Planning.Planner.<>c__DisplayClass1.<CreateNewPlan>b__0(IPlanningStrategy s) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Planner.cs:line 109
   at Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map[T](IEnumerable`1 series, Action`1 action) in c:\Projects\Ninject\ninject\src\Ninject\Infrastructure\Language\ExtensionsForIEnumerableOfT.cs:line 32
   at Ninject.Planning.Planner.CreateNewPlan(Type type) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Planner.cs:line 109
   at Ninject.Planning.Planner.GetPlan(Type type) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Planner.cs:line 71
   at Ninject.Activation.Providers.StandardProvider.Create(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 77
   at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157
   at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
   at Ninject.Planning.Targets.Target`1.GetValue(Type service, IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 197
   at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 165
   at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 114
   at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.<Create>b__2(ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96
   at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Ninject.Activation.Providers.StandardProvider.Create(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96
   at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157
   at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.<CastIterator>d__b1`1.MoveNext()
   at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
   at Ninject.ResolutionExtensions.Get[T](IResolutionRoot root, IParameter[] parameters) in c:\Projects\Ninject\ninject\src\Ninject\Syntax\ResolutionExtensions.cs:line 37
   at UnitTest..ctor()

So my first thought was: heck, I probably did something wrong and it not so easy (Ninject registrations of components is really easy, you should try yourself). But I cannot find any references to that version of EF anywhere in my project. In fact I did not added them myself, everything was done by NuGet, so it should work, right? Yes. It should and it was working because:

1. Registration of classes from EntityFramework.dll was working perfectly.

2. Registration of classes from EntityFramework.Pattersn.dll was not working at all.

3. When I added console project registration of both types from both assemblies was working without problems.

So the problem was with EntityFramework.Patterns.dll, its internal reference to older version of EF (I was using 5.0 version). Another problem was with assembly redirecting from older version of EF to newer 5.0. In console project section in app.config:

 <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
      </dependentAssembly>
   </assemblyBinding>
  </runtime>

was doing what it suppose to, forcing application to use 5.0 version despite internal reference to version 4.3.1 inside EntityFramework.Patterns.dll. So maybe in test it is not present. Nope it was. Maybe configuration is not copied into Debug dir? Nope. Maybe it is named wrong? Nope. In this moment I had to take a few minutes off.

I was thinking: everything is as it suppose to. Assemblies, references, redirecting, configuration. So... maybe test environment is not starting correctly? Maybe it is ignoring that part of app.config. When I was adding NuGet packages same day I noticed update for VS. Why not tried that? Few clicks, about 1 hour and restart of VS after I tried again. Guess what? It worked!

So it was bug with VisualStudio. I was glad that it was over and little disappointed for few hours that I have lost. But it was at least one step closer in the right direction. Smile

 

So if you encounter problem like that tried update VS 2012 with Update 2. It should work!



Curious Case of Visual Studio project compatibility.

clock February 12, 2013 08:06 by author n.podbielski

Recently I was asked at work for quick review of small project. It was created (or updated) in newest version of Visual Studio - 2012. I don't have installed VS 2012.

I could install it, yes, but it would be just waste of time since browsing through code in that project took me only few hours.

So I decided to try to open that in VS 2010.

It was not surprised that didn't work entirely. I was expected that I won't have possibility of building it - .NET 4.5 was not even installed on my machine. But to see "incompatible" next to project name was surprise to me indeed. It was strange I was suspecting that lack of .NET 4.5 binaries could cause that. But installation of framework did not help. I still was seeing this:

 

That is strange. I would thought that Microsoft at least would allow me to browse through files and see contents of project. I guess they would try every little thing they can to sell they newest software Smile.

So I thought to try to open this project in version 2008. Just for fun and this was surprised it worked Cool. I even get message 'build succeeded' when I tried it, but I have to mention that was only once and after opening files with errors (non existent namespaces and classes) it no longer worked Smile. But it was ok since I was only required to look at the code inside.

After 'build succeeded' info I tried to open project properties of project and get this:

 

 

So if project had no framework at all it could skip building entirely and since there was not errors It succeeded Smile

Nevertheless I done my work using VS2008.

Why Microsoft would block something in VS2010 and no in 2008. Maybe users of second are considerably less numerous so it was just to expensive to do such thing.