Showing posts with label c#. Show all posts
Showing posts with label c#. Show all posts

30 August 2013

Allowing .Net unit tests to access internal members

Good code encapsulation requires that various members be marked as private, or at least internal. However this can make it difficult for unit test frameworks such as NUnit to access them.

You can grant an external (e.g. unit test) assembly access to internal members by doing the following:

  1. Give your test assembly a strong name (via Project Properties, Signing, Sign the assembly)
  2. Compile the assembly (eg. My.Test.dll)
  3. Open the Visual Studio command prompt
  4. Navigate to the folder where My.Test.dll got built
  5. Run:  sn -Tp My.Test.dll
  6. This will display the full public key for the signed assembly. Copy it. (it'll be about 320 chars)
  7. Open the AssemblyInfo.cs file for the assembly containing the code with internals to be tested.
  8. Enter a line such as: [assembly: InternalsVisibleTo("My.Test, PublicKey=1234")] where 1234 is the full key generated in step 6.
Note: this only works if the full key is used, not the shorter summary key.

3 May 2012

MSBuild Task to generate hash of files

Here's a handy inline MSBuild task to take a bunch of files and generate a hash. I used it to generate a hash of source files in order to determine if an exe has really been changed (given that exe's compile to distinct files each time even if the source hasn't changed).

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<UsingTask TaskName="GenerateHash" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<InputFiles ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
<OutputFile ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Using Namespace="System.IO" />
<Using Namespace="System.Linq" />
<Using Namespace="System.Security.Cryptography" />
<Code Type="Fragment" Language="cs"><![CDATA[
using (var ms = new MemoryStream())
using (var md5 = MD5.Create())
{
foreach (var item in InputFiles)
{
string path = item.ItemSpec;
using (FileStream stream = new FileStream(path, FileMode.Open))
{
var fileHash = md5.ComputeHash(stream);
ms.Write(fileHash, 0, fileHash.Length);
}
}
ms.Flush();
ms.Position = 0;
var dirHash = md5.ComputeHash(ms);
using (TextWriter w = new StreamWriter(OutputFile, false))
{
w.WriteLine(string.Join("", dirHash.Select(b => b.ToString("x2"))));
}
}
]]></Code>
</Task>
</UsingTask>

<Target Name="Demo">
<GenerateHash InputFiles="@(SomeFiles)" OutputFile="res.txt" />
</Target>
</Project>

9 February 2012

ShouldSerialize

Sometimes features are staring at you in the face, all you need to do is read the docs. Other times it really feels like things are hidden. Thanks Con for pointing me to ShouldSerializePropertyName - I did a careful look through the MSDN serialization docs in hope of finding this very feature, but didn't have any luck.

What does it do? For any given property, create a bool ShouldSerializePropertyName() method to decide if it should be included in serialization. A bit magical, but does the trick.

Why do I want this? I want to serialize an object graph to XML. But I don't want to render a container element for any empty collections. I think I'm becoming a bit of a pedent when it comes to XML.

Docs (in as much as I could be find any) are over here under Windows Form Controls.

15 January 2012

XmlSerializer inheritance woes

OK, this just drove me crazy for about an hour. I'm using the XmlSerializer, and my object graph has derived types.

I was using the XmlInclude attribute in the correct manner, but I still kept getting:

The type Child was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.

It didn't work when I passed the extraTypes parameter to the XmlSerializer constructor either.

In the end it turns out that the 'Namespace' declaration was the problem. Adding an identical namepsace to the Child class fixed the problem. Strange because up until using inheritance things have worked fine only specifying it on the root class.

[XmlRoot(Namespace = "somenamespace")]
public class Root
{
public Parent Field { get; set; }
}

[XmlInclude(typeof(Child))]
public class Parent
{
public string Data { get; set; }
}

public class Child : Parent
{
}

...
Root r = new Root();
r.Field = new Child();

20 December 2011

Treating most warnings as errors

A common scenario in C# I find is that I would like to:

  1. Treat most warnings as errors by default
  2. But, treat a few specific warnings as just warnings.

I still want them to show up as warnings, which is to say that I don't want them to disappear altogether. 'CS0618 Obsolete' is a good example of this.

This cannot be achieved through the C# Project Properties editor, but it can be done by manually editing the .csproj file to add these two MSBuild properties:

<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsNotAsErrors>618</WarningsNotAsErrors>

This is vaguely referred to in the docs here, and the list of error codes can be found here.

30 November 2011

Binding, and Templates, and ContentControls, oh my!

I'm working in Silverlight 4, and have been trying to get a particular binding scenario to work right. It seems to be the case that try to satisfy any one or two requirements is easy enough, but when things start piling up, Silverlight can get a bit tricky.

My requirements:

  1. I'm creating a UserControl
  2. The UserControl itself needs to work inside a template.
  3. I want to define properties on the UserControl.
  4. I want a ContentControl in the UserControl
  5. I want to define a ContentTemplate on the content control
  6. And lastly, I want this inner template to bind to properties of the UserControl

The problems:

  • I can't name the UserControl and use ElementName inside the template, because the UserControl itself is also going to be used in a template, and ElementName doesn't always behave well in that situation.
  • I can't programatically set the DataContext or Bindings within the template, because Silverlight doesn't give programatic access to a template.
  • Setting the DataContext of the UserControl or the ContentControl to the UserControl itself doesn't help, because the DataContext of a template is actually the Content property of the ContentControl.
  • I can't set the Content of the ContentControl to the UserControl itself, because this makes Silverlight hang (presumably due to an infinite recursive loop).

So here's what I've got working. It's disgusting, but seems to work.

<UserControl>
...
<ContentControl x:Name="content"/>
<ContentControl.ContentTemplate>
<DataTemplate>
<TextBox Text="{Binding Self.SomeValue}" />
</DataTemplate>
<ContentControl.ContentTemplate>
</ContentControl>
...
</UserControl>

And the code...

public partial class MyControl : UserControl
{
public class Indirection
{
public ValueEditor Self { get; set; }
}

public MyControl()
{
InitializeComponent();
this.content.Content = new Indirection() { Self = this };
}

public static readonly DependencyProperty SomeValueProperty = ...
public string SomeValue { ... }

}

So the idea is to set the ContentControl.Content to a proxy object that is not the control itself, but with a reference to the control, which can then be accessed in the path of the binding.

If you know a nicer way to do this, please leave a comment!

29 November 2011

Default parameters

How disappointing! I've just started to dip a toe into C# default parameters. And they have to be compile-time constants. Sure, it makes a lot of sense, but how about allowing static readonly properties as well?

All I want is this:

// Not too much to ask for?
void MyMethod(Guid someId = Guid.Empty)
{
...
}

24 November 2011

INotifyPropertyChanged code snippet

I've never really worried about getting into Visual Studio code snippets. But I've been using INotifyPropertyChanged a lot recently, so it got me looking at them again.

Found this cool snippet by Brian Schroer for filling out properties. Here's my slightly customized version of it to suit personal taste. Thanks Brian!

Steps to intall:

  1. Save the following to NotifyProperty.snippet on your desktop1
  2. In Visual Studio go to Tools / Code Snippets Manager
  3. Press Import and locate the file
  4. Import the file into My Code Snippets

Steps to use:

  1. In the code editor, type propn then press TAB twice.
  2. Immediately type the name of the property. Press tab.
  3. Then type the .Net Type name of the property.

The code:



<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>propn</Title>
<Shortcut>propn</Shortcut>
<Description>Code snippet for property and backing field in class implementing INotifyPropertyChanged</Description>
<Author>Brian Schroer</Author>
<!-- http://geekswithblogs.net/brians/archive/2010/07/27/inotifypropertychanged-with-less-typing-using-a-code-snippet.aspx -->
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>type</ID>
<ToolTip>Property type</ToolTip>
<Default>string</Default>
</Literal>
<Literal>
<ID>property</ID>
<ToolTip>Property name</ToolTip>
<Default>MyProperty</Default>
</Literal>
</Declarations>
<Code Language="csharp">
<![CDATA[/// <summary>
/// Gets or sets the $property$
/// </summary>
public $type$ $property$
{
get { return _$property$;}
set
{
if (value != _$property$)
{
_$property$ = value;
OnPropertyChanged("$property$");
}
}
}
private $type$ _$property$;
$end$]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

Some VS macros I can't live without

Here's a few Visual Studio Macros that I can't live without at the moment. They're somewhat pieced together from bits I found online and customized for my needs. Thanks to whoever you are!

In order:

  • Locates the currently open file in the Solution Explorer panel.
  • Attaches debugger to a service.
  • Attaches debugger to an open Silverlight window.

(Ugh! VB - Whoever thought it was a good idea to write whole applications in this stuff?)


Imports System
Imports EnvDTE100
Imports System.Diagnostics

Public Module AttachDebugger

Public Sub LocateCurrentFileInSolutionExplorer()
' Suggest binding to: Alt+L Alt+L
DTE.ExecuteCommand("View.TrackActivityinSolutionExplorer")
DTE.ExecuteCommand("View.TrackActivityinSolutionExplorer")
DTE.ExecuteCommand("View.SolutionExplorer")
End Sub

Public Sub DebugMyService()
Dim p As EnvDTE.Process

For Each p In DTE.Debugger.LocalProcesses
If p.Name.ToLower().EndsWith("myservice.exe") Then
p.Attach()
Exit Sub
End If
Next
MsgBox("Could not find ReadinowSvc.exe")
End Sub

Sub DebugSilverlight()
'Thanks to http://www.dllshepherd.net/2011/05/silverlight-attach-to-process-shortcut.html
Try
Dim dbg2 As EnvDTE80.Debugger2 = DTE.Debugger
Dim trans As EnvDTE80.Transport = dbg2.Transports.Item("Default")
Dim dbgeng(1) As EnvDTE80.Engine
dbgeng(0) = trans.Engines.Item("Silverlight")

For Each process As EnvDTE80.Process2 In dbg2.GetProcesses(trans, Environment.MachineName)
If process.Name.Contains("iexplore.exe") Then
For Each program As EnvDTE.Program In process.Programs
If program.Name.Contains("Silverlight") Then
process.Attach2(dbgeng)
End If
Next
End If
Next
Catch ex As System.Exception
MsgBox(ex.Message)
End Try
End Sub

End Module

15 November 2011

Binding UserControl properties in Silverlight

It seems to me that the logical thing to do in Silverlight when building some sort of composite control is to create a UserControl, expose some properties, add some controls to the user control, and bind them to those properties.

For example, a custom CoffeeMug control might want to expose MugColor and PercentFull properties. However, it's taken me quite a while to figure out how to get this to work properly.

The problem is in selecting the binding source. WCF offers the FindAncestors binding helper, which can be used to locate the user control relative to the control being bound, but Silverlight offers no counterpart.

So initially I had been using ElementName:

<UserControl x:Name="thisControl" ... >
...
<Rectangle x:Name="mugShape"
Background="{Binding MugColor, ElementName=thisControl}" />
...
</UserControl>

This works pretty well in simple circumstances, but it wasn't working for me in DataTemplate scenarios, such as in the DataGrid. I was having similar problems with using custom controls in custom ComboBox and ListBox data templates.

Well, apparently its a known shortcoming of Silverlight. When the data template is asked to make a concrete instance, it no longer carries the necessary context information to resolve element names directly. It can however be overcome by manually specifying the binding in code.


public CoffeeMug()
(
this.Loaded += new new RoutedEventHandler(Control_Loaded);
}
void Control_Loaded(object sender, RoutedEventArgs e)
{
Binding binding = new Binding("MugColor");
binding.Source = this;
// remember to set binding.Mode = TwoWay if applicable
this.mugShape.SetBinding(Shape.BackgroundProperty, binding);
}

This guy has also hacked together a behavior to make everything much nicer in an MVVM environment as well, but I don't think I'd go to that much effort personally.

10 November 2011

Debugging immediate variables

Here's a neat Visual Studio debugging trick I just stumbled on today by accident. Sometimes, it can be very handy to be able to refer back to information from another frame in the stack, or from a previous call to the same function.



Step 1

When you're at a location of interest, use the intermediate window to declare a new variable and assign a value to it. (Remember to give it a type declaration or 'var').


// Type this into the 'Immediate' window
var tmp = data;



Step 2

Now, when you're at a completely different location, either in a different method, or even at a different calling of the same method, you can still inspect your immediate variable in the watch window.




Obviously the temp variable is not going to automatically update if the source it came from gets updated, but it can still be pretty handy sometime, for example to compare two values to see if they're the same.


Presumably we're also holding onto a reference now that would prevent it from being garbage collected, so in a large environment it might be a good idea to set the temp variable back to null when you're done with it.


What happens if you set it to a variable name that is then used at a subsequent break point? Answer: it gets blown away and replaced with the new value (and type).

9 November 2011

Interface implementation and covariance


I was a bit disappointed to discover that the following code doesn't compile in C# 4. In particular, it seems that as the 'Thing' property is only a getter on the interface, any concrete implementation should be able to return a derived type, since it can be guaranteed that anyone getting the parent type from the interface will also be able to operate on the child type.




class Thing { }

class SpecificThing : Thing { }

interface IThingContainer
{
Thing Thing { get; }
}

class SpecificThingContainer : IThingContainer
{
public SpecificThing Thing { get; set; }
}

26 October 2011

Enum.GetValues in Silverlight

It seems Enum.GetValues is not defined in the Silverlight client profile.
The owl says it best.
Oh well, a hacking we shall go.

14 September 2011

Covariance contravariance inconvenience

I love the covariance/contavariance support in C#4. That is the mechanism that lets you implicitly convert from an IEnumerable<Child> to an IEnumerable<Parent> was expected (covariance), and an IComparable<Parent> can be converted to IComparable<Child> (contravariance). Here Child obviously inherits from Parent.

One of the biggest problems though is that this only works for classes and interfaces where the type parameters are either all outbound or all inbound for covariance and contravariance respectively. E.g. no methods on IEnumerable<T> accept T, which is covariance. And no methods on IComparable<T> return T. Eric Lippert wrote a bunch of posts worth reading about while the compiler team were considering variance.

This is somewhat inconvenient. For example it means that IList<Child> cannot be assigned to IList<Parent>, or vice-versa, because IList<T> methods both accept and return T. And often one may wish to write a method using IList<T> rather than IEnumerable<T> as it allows for direct element access. It is particularly frustrating because I may well only need to use the methods that read from the list, and so if IReadonlyList<T> existed then all might be sweet.

Now I was wrestling with this kind of thing the other day when I read Lippert's post on What is this thing called a Type, which got me thinking about it all again. Here he's again talking about how various operations tranform one Type into another.

OK, to the point. Here's the idea I was thinking. What if it were possible to create modified types based on existing interfaces and classes that only present the input or output methods.

For example (and to use Lippert's Giraffe inherits from Mammal inherits from Animal example):
IList<out Mammal> and IList<in Mammal> becomes types that are declarable in code.

IList<out Mammal> exposes only the subset of IList<Mammal> that is covariant. I.e. the methods for reading from the list, but none of the methods that accept T parameters. IList<out Giraffe> could be assigned to IList<out Mammal>. As a type, IList<out Mammal> itself would be smaller than IList<Mammal>, so it is always possible to convert from IList<Mammal> to IList<out Mammal>. So, finally IList<Giraffe> could be assigned to IList<out Mammal>.

Likewise, IList<in Mammal> exposes only the subset of IList<Mammal> that is contravarient, exposing only the methods for modifying a list. By the same (but contravariant) argument, IList<Giraffe> would be assignable to IList<in Mammal>.

Some code we could then write:

static void FeedMammals(IList<out Mammal> mammals)
{
// mammals.Count is available as it doesn't use the type parameter.
// Using an old-style for-loop to illustrate we don't want to use IEnumerable<T>
for (int i=0; i<mammals.Count; i++) parameter
{
// only the getter is available, as it is outbound
mammals[i].FeedMammalFood();
}

// But these are illegal:
mammals[0] = new Mammal(); // setter
mammals.Insert(0, new Mammal()); // method that accepts T
}


And call with:

List<Giraffe> giraffes = ...;
FeedMammals(giraffes); // yay, cast from List<Giraffe> to IList<out Mammal>


Similarly we could have:

static void AddBabyMammals(IList<in Mammal> mammals)
{
// New baby born
Mammal baby = GetNewBabyMammal();
mammals.Insert(0, baby);

//Setter is also OK to replace a value
mammals[0] = baby;

// But these would be illegal
Mammal m1 = mammals[0]; // getter
foreach (var m2 in mammals) // call to enumarator, because its 'out'
}


And call with:

List<Animal> animals = ...;
AddBabyMammals(animals); // yay, cast from List<Giraffe> to IList<out Mammal>


This would be a wonderful feature. Anyway, that's my two cents.