Macs, Parallels and Keyboard Layouts
I am currently developing on a Mac, running Visual Studio on a Windows 7 VM courtesy of Parallels. There are a number of issues to resolve the first of which is the key mappings.
I am using the Mac bluetooth keyboard and a few keys are mapped incorrectly:
| Pressing this key | Results in this output |
| § | ` |
| ± | ¬ |
| @ | “ |
| “ | @ |
| \ | # |
| | | ~ |
When using OS X alt + 3 produces a # and alt + 2 produces a €. Unfortunately in Windows alt key combinations are normally used to launch menu items.
The answer to this is a free program from Microsoft called Keyboard Layout Creator.
Download and install this (on your Windows VM) then you can use it to create a correct layout. Once you have the layout you can create an installer to install your keyboard layout on however many VMs you like.
You can download the layout I created and open the file in the layout creator to build your own installer. I have also uploaded the installer I created (mostly for my own reference, I make no guarantees it will not fry your system, please use a good virus scanner etc.).
Once you have installed the layout open Keyboards and languages:
Then change the default input language and keyboard:
Any applications that are open need to be restarted, but then you should have all keys working correctly.
I have mapped # to Ctrl + alt + 3 and € to ctrl + alt + 2 which should work as long as the application you are in is not using them as shortcut keys.
DI with Ninject for an MVC project
This seems to be a somewhat moving target with ASP.Net MVC moving up the versions as well as Ninject. This particular target will be ASP.Net MVC 2.0 and Ninject 2.0.
First set up the references:
- Download Ninject.Web.Mvc (If not using git, there is a download source link on the page).
- Open the mvc2/Ninject.Web.Mvc.sln and compile with release settings.
- Copy the files Ninject.dll and Ninject.Web.Mvc.dll from the mvc2/build/debug/release folder to the lib folder of your MVC project.
- Add references to these two files to your MVC project.
The DI Container (called a Kernel with Ninject) needs initializing on app startup which, with MVC, is in the Global.asax. Add the following using statements to the Global.asax:
using Ninject; using Ninject.Modules; using Ninject.Web.Mvc;
Change the MvcApplication so it inherits from NinjectHttpApplication:
public class MvcApplication : NinjectHttpApplication {
Let Visual Studio implement the CreateKernel method.
override the OnApplicationStarted method copying in the lines from the Application_Start method:
protected override void OnApplicationStarted() {
AreaRegistration.RegisterAllAreas();
RouteRegistrar.RegisterRoutes(RouteTable.Routes);
}
Then delete the Application_Start method.
Ninject stores the rules it uses to return class instances in Modules which are derived from NinjectModule. Add the following class to the MVC project:
using Ninject.Modules;
namespace MvcApp.Web {
public class WebModule : NinjectModule {
#region Instance Methods
public override void Load() {
}
#endregion
}
}
The Load method is where we specify how each request for a concrete class is fulfilled.
Lastly, modify the CreateKernel method so that the module is passed into the Kernel’s ctor:
protected override IKernel CreateKernel() {
var modules = new INinjectModule[]
{
new WebModule()
};
var kernel = new StandardKernel(modules);
return kernel;
}
Fakes, Mocks, and Stubs, What’s the Difference?
It doesn’t take much unit testing before you come across a dependency in the class you are testing for another object. Hopefully your classes are loosely coupled and you are able to make a substitution for this other object. It seems most people call these substitute objects mocks but a mock is a specific thing. According to Martin Fowler there are 4 types of substitution:
- Dummy – An object that is never actually used, just required to fill out the parameter list.
- Fake – An object with just enough of a working implementation to substitute.
- Stub – An object that can provide canned answers to member calls and, optionally, record the calls for later interrogation.
- Mock – An object that is programmed with a set of expectations of which calls will be made, in what order with what parameters. It is the expectation that is tested after the code has been exercised.
Entity Classes, IDs and Equality
I want my entity classes to rely on their ID when checking equality, the ID is populated from the repository when I retrieve an object and automatically generated when I save a new entity.
This poses the problem of how I compare two entities before they have been saved while working with them in my domain, or, when I have ‘newed’ them up myself for unit testing. The answer is to use a transient ID.
Normally an Entity Base class might look like this:
public abstract class EntityBase : IEquatable<EntityBase> {
public virtual int Id { get; protected set; }
public override bool Equals(object other) {
return Equals(other as EntityBase);
}
public override int GetHashCode() {
return Id;
}
public virtual bool Equals(EntityBase other) {
if (other == null) return false;
return other.Id == Id && other.GetType() == GetType();
}
}
If two new objects are created from a derived class then object1.Equals(object2) will be true as Id will be 0 for both objects. To avoid this I need to check if an object has not yet been saved:
private bool IsTransient {
get { return Id == 0; }
}
And just check for referential equality if this is the case:
public virtual bool Equals(EntityBase other) {
if (other == null) return false;
if (IsTransient) return ReferenceEquals(this, other);
return other.Id == Id && other.GetType() == GetType();
}
GetHashCode() needs to be overridden to reflect this:
public override int GetHashCode() {
if (IsTransient) return base.GetHashCode();
return Id;
}
The full code for EntityBase is:
public abstract class EntityBase : IEquatable<EntityBase> {
public virtual int Id { get; protected set; }
private bool IsTransient {
get { return Id == 0; }
}
public override bool Equals(object other) {
return Equals(other as EntityBase);
}
public override int GetHashCode() {
if (IsTransient) return base.GetHashCode();
return Id;
}
public virtual bool Equals(EntityBase other) {
if (other == null) return false;
if (IsTransient) return ReferenceEquals(this, other);
return other.Id == Id && other.GetType() == GetType();
}
}
Solution Layout for an MVC App
While it may seem easier to throw all code into one project, it is good practise to separate areas of code into different projects within a solution. This helps promote good design with principles like loose coupling and high cohesion. A solution layout I like is:
- Domain – contains the domain layer and data interfaces (in their own sub folder) and, if necessary can reference the Infrastructure project.
- DataInterfaces *
- Infrastructure – contains plumbing code for functions such as logging and reporting, should not reference any other projects.
- Logging
- Reporting
- Infrastructure.Data – contains data access code and references the Core and Infrastructure projects. Whilst some may put this in the infrastructure project, I prefer Domain to be able to reference Infrastructure which causes a circular reference if data access code is kept there.
- Tests – self explanatory – references any projects that need tests. Each project has a subfolder to contain it’s tests
- Core
- Data
- Web.Controllers
- Web – contains the core of the MVC project including the views and Global.asax, some files and folders have been moved around and models and controllers have been moved into different projects. The web project references all other projects except Test.
- Public
- css
- images
- javascript
- Views
- Public
- Web.Controllers – contains the controllers and also the RouteRegistrar class. Splitting the controllers into their own project does cause some extra initial work but a good argument for doing this can be found here.
*Indented items represent folders and sub folders within the projects.
The Solution Explorer should look similar to this when done:
All projects are class libraries except for the Web project which is MVC2. Web Content folder has been renamed to public and sub folders added and script and css files moved into it. HomeController has been moved to the Controllers project and the Controllers and Models folders have been deleted.
To get this solution to run:
- Set Web as Start Up Project
- Add a reference to Web.Controllers from Web.
- Add a references to System.Web, System.Web.MVC (2.0.0.0) and System.Web.Routing from Web.Controllers.
- Add the RouteRegistrar class to Web.Controllers.
- Amend Global.asax.cs Application_Start to use RouteRegistrar.RegisterRoutes.
using System.Web.Mvc;
using System.Web.Routing;
namespace Furld.Web.Controllers {
public class RouteRegistrar {
#region Class Methods
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new {controller = "Home", action = "Index", id = UrlParameter.Optional} // Parameter defaults
);
}
#endregion
}
}
I also have a preferred folder structure which looks like this:
- Main project folder – this is what gets committed to source control
- Docs
- Lib – contains all libraries I reference (e.g. nunit.framework.dll, ninject.dll etc).
- Src – contains the solution file and the projects, each in it’s subfolder (Core, Data …).
- Tools – contains tools used in the project, both those that require installation and those where I am just using libraries (e.g. NUnit-2.5.4.10098.zip).
This layout has a few changes from my normal layout partly prompted by Rob Conery’s http://mvcstarter.codeplex.com/ and some investigation of http://www.sharparchitecture.net/.
Azure Development Fabric and Visual Studio 2010
Posted by John in Visual Studio on April 13, 2010
Just installed Visual Studio 2010. The first thing I tried was creating an new Cloud project.
The whole process was surprisingly painless. After creating the solution, I was prompted to download and install the Azure tools. Once they were installed, I deleted and recreated the solution and was prompted for which Roles I wanted:
After creating the solution just hit F5 to see the project running in the Azure Development Fabric.
The debugger is already connected and all works just as you would expect.
Simple WCF Service Host
app.config
The configuration for a simple http WCF host is:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
</appSettings>
<system.serviceModel>
<services>
<service name="AssemblyNamespace.ServiceImplementation"
behaviorConfiguration="ServiceBehavior">
<endpoint address="ServiceName"
binding="basicHttpBinding"
contract="AssemblyNamespace.ServiceContractInterface" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://HostName:Port/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
An example:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
</appSettings>
<system.serviceModel>
<services>
<service name="TestService.CalculatorService"
behaviorConfiguration="CalculatorServiceBehavior">
<endpoint address="CalculatorService"
binding="basicHttpBinding"
contract="TestService.ICalculator" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
The Service
Define the service in an interface
using System.ServiceModel;
namespace TestService
{
[ServiceContract]
public interface ICalculator
{
#region Instance Methods
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
#endregion
}
}
Then implement the interface
using System;
namespace TestService
{
public class CalculatorService : ICalculator
{
#region ICalculator Members
public double Add(double n1, double n2) {
double result = n1 + n2;
Console.WriteLine("Received Add({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}
public double Divide(double n1, double n2) {
double result = n1/n2;
Console.WriteLine("Received Divide({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}
public double Multiply(double n1, double n2) {
double result = n1*n2;
Console.WriteLine("Received Multiply({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}
public double Subtract(double n1, double n2) {
double result = n1 - n2;
Console.WriteLine("Received Subtract({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}
#endregion
}
}
The Host
Lastly create a host for the service
using System;
using System.ServiceModel;
namespace TestService
{
internal class Program
{
#region Class Methods
private static void Main() {
using (ServiceHost serviceHost = new ServiceHost(typeof (CalculatorService))) {
serviceHost.Open();
Console.WriteLine("The calculator service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
}
}
#endregion
}
}
Installing Subversion on Windows
My requirements are to host the repository on a windows machine, mostly for access from the LAN but also to be accessible over the Internet. The server is running Vista but the install and set up process should be similar on other versions of windows.
Currently there are two relevant builds of Subversion, one based on apache 2.0 and one based on 2.2. I am going to install Apache 2.2 and the corresponding Subversion build.
Install the Apache HTTP server.
Download and run the latest subversion build (currently svn-1.4.6-setup.exe) from http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=8100&expandFolder=8100&folderID=91
Copy the file mod_dav_svn.so from C:\Program Files\Subversion\bin to C:\Program Files\Apache Software Foundation\Apache2.2\modules.
Open the Apache configuration file (‘Start > All Programs > Apache HTTP Server 2.2 > Configure Apache Server > Edit the Apache httpd.conf Configuration File’) and find the line ‘#LoadModule dav_module modules/mod_dav.so’.
Remove the ‘#’ from the front of that line then add the line ‘LoadModule dav_svn_module modules/mod_dav_svn.so’ below it. Save the file and restart the service to confirm everything is working as it should.
Create the directory where you want to store the repositories (e.g. D:\Svn).
Go back to the Apache configuration file and at the end of the file add:
<Location /Svn>
DAV svn
SVNListParentPath on
SVNParentPath D:\Svn
</Location>
Save the changes then restart the Apache service for them to take effect.
You should now be able to browse to http://localhost:81/Svn/ and see a page with zero repositories.
Installing Apache HTTP Server on Windows
I am setting up a machine to host Subversion. My preference is to use Apache as the HTTP server. The server is running Vista but the install and set up process should be similar on other versions of windows.
Download
The latest Apache build (currently apache_2.2.9-win32-x86-no_ssl-r2.msi) from http://httpd.apache.org/download.cgi
Install Apache
Run the installer and follow the instructions. Enter the server name under ‘Network Domain’ and ‘Server Name’, enter an email address and leave ‘for All Users’ selected.
Navigate to http://localhost/ and you should see the text ‘It works!’.
I prefer to run IIS on port 80 and Apache on 81. If you already have IIS installed and running you may not have got the ‘It works!’ page but rather an IIS page when running the test above.
Change to Port 81
‘Start > All Programs > Apache HTTP Server 2.2 > Configure Apache Server > Edit the Apache httpd.conf Configuration File’
Search for ‘Listen 80′ and replace with ‘Listen 81′
Save the conf file and restart the service from the services console then browse to http://localhost:81/ to confirm it works.
Create a Password File
Open a command prompt at C:\Program Files\Apache Software Foundation\Apache2.2.
Create a password file by entering ‘bin\htpasswd -c passwd username‘ and enter and confirm the password when prompted.
Add any further users with ‘bin\htpasswd passwd username‘.
Edit the Apache httpd.conf configuration file and change:
<Directory />
Options FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
</Directory>
To:
<Directory />
Options FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
AuthType Basic
AuthName “Subversion Repositories”
AuthUserFile passwd
Require valid-user
</Directory>
Restart the Apache 2.2 service and confirm you are asked for a username and password when you navigate to http://localhost:81/.
You may need to amend your firewall to allow connections from port 81.
Vista “Windows Complete PC Restore” fails with “No valid backup locations could be found”
There is an issue with Vista complete PC back up and restore if you are restoring to a clean system from more than one DVD or CD. It appears that the catalogue is stored on the last disc in the back up set but this appears to be undocumented.
This means when you run your Windows Complete PC Restore, either from Vista or by choosing repair your computer during an installation, and insert the first disk of the back up when asked to insert the backup media you get the message “No valid backup locations could be found” which initially is just a bit worrying.
If you insert the last disk of the backup set, the catalogue is found and you can choose the backup and the backup options you want. When the backup starts you will be asked to insert the first disk.