Sunday, 27 May 2012

Silverlight Async Rest Wcf

Here is a simple example application that shows off:

  • “Aync” and “await” within Silverlight 5 in Visual Studio 11
  • Calling a simple RESTful WCF interface hosted with no config or svc file

image

image

image

MainPage.xaml.cs (code behind)

private async void LoadDataButton_Click(object sender, RoutedEventArgs e)
{
var request = new WebClient();
var uri = new Uri("http://localhost:5349/services/cars");
var jsonString = await request.DownloadStringTaskAsync(uri);

using (var stream = new MemoryStream(Encoding.Unicode.GetBytes(jsonString.ToCharArray())))
{
var serializer = new DataContractJsonSerializer(typeof (Car[]));
var cars = (Car[]) serializer.ReadObject(stream);
CarsListBox.ItemsSource = cars;
}
}

Service Interface

[ServiceContract]
interface IService<T>
{
[OperationContract]
IList<T> GetAll();

[OperationContract]
T Get(string id);

[OperationContract]
void Insert(T entity);

[OperationContract]
void Update(string id, T entity);

[OperationContract]
void Delete(string id);
}

Service Implementation

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class CarService : IService<Car>
{
private readonly IRepository<Car> _repo;

public CarService()
{
_repo = new FakeCarRepository();
}

public CarService(IRepository<Car> repo)
{
_repo = repo;
}

[WebGet(UriTemplate = "Cars", ResponseFormat = WebMessageFormat.Json)]
public IList<Car> GetAll()
{
var cars = _repo.GetAll();
return cars;
}

[WebGet(UriTemplate = "Car/{id}", ResponseFormat = WebMessageFormat.Json)]
public Car Get(string id)
{
var car = _repo.GetById(id);
return car;
}

[WebInvoke(UriTemplate = "Car", Method = "POST")]
public void Insert(Car car)
{
_repo.Insert(car);
}

[WebInvoke(UriTemplate = "Car/{id}", Method = "PUT")]
public void Update(string id, Car car)
{
_repo.Update(car);
}

[WebInvoke(UriTemplate = "Car/{id}", Method = "DELETE")]
public void Delete(string id)
{
_repo.Delete(id);
}
}

DTO

[DataContract]
public class Car
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Make { get; set; }
[DataMember]
public string Model { get; set; }
[DataMember]
public int Year { get; set; }
}

How come no config or svc file?


Global.asax

public class Global : HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add(new ServiceRoute("services", new WebServiceHostFactory(), typeof(CarService)));
}
}

Web.config

<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
</configuration>

Source


http://stevenhollidge.com/blog-source-code/SilverlightAsyncRestWcf.zip

Code Contracts

I started writing a blog post about Code Contracts that I believe will end up working its way into all future .NET software, particularly APIs.  Then I came across this excellent write up that I highly recommend:

http://devjourney.com/blog/code-contracts-part-1-introduction/

Code Contracts in action

using System;
using System.Diagnostics.Contracts;

namespace CodeContracts
{
public interface IRandomGenerator
{
int Next(int min, int max);
}

public class RandomGenerator : IRandomGenerator
{
private readonly Random _random = new Random();

public int Next(int min, int max)
{
return _random.Next(min, max);
}
}

public class Randomizer
{
private readonly IRandomGenerator _generator;

public Randomizer(IRandomGenerator generator)
{
_generator = generator;
}

public int GetRandomFromRangeContracted(int min, int max)
{
Contract.Requires<ArgumentOutOfRangeException>(
min < max,
"Min must be less than max"
);

Contract.Ensures(
Contract.Result<int>() >= min &&
Contract.Result<int>() <= max,
"Return value is out of range"
);

return _generator.Next(min, max);
}
}
}

The above code Post build

public class Randomizer
{
// Fields
private readonly IRandomGenerator _generator;

// Methods
public Randomizer(IRandomGenerator generator)
{
this._generator = generator;
}

public int GetRandomFromRangeContracted(int min, int max)
{
int Contract.Old(min);
int Contract.Old(max);
__ContractsRuntime.Requires<ArgumentOutOfRangeException>(min < max, "Min must be less than max", "min < max");
try
{
Contract.Old(min) = min;
}
catch (Exception exception1)
{
if (exception1 == null)
{
throw;
}
}
try
{
Contract.Old(max) = max;
}
catch (Exception exception2)
{
if (exception2 == null)
{
throw;
}
}
int CS$1$0000 = this._generator.Next(min, max);
int Contract.Result() = CS$1$0000;
__ContractsRuntime.Ensures((Contract.Result() >= Contract.Old(min)) && (Contract.Result() <= Contract.Old(max)), "Return value is out of range", "Contract.Result<int>() >= min && Contract.Result<int>() <= max");
return Contract.Result();
}
}


Unit tests with Moq and NUnit test cases

using System;
using Moq;
using NUnit.Framework;

namespace CodeContracts.Tests
{
[TestFixture]
public class Given_mocked_RandomGenerator
{
private Mock<IRandomGenerator> _randomMock;
private Randomizer _randomizer;

[SetUp]
public void Setup()
{
_randomMock = new Mock<IRandomGenerator>();
_randomizer = new Randomizer(_randomMock.Object);
}

[TestCase(1, 0)]
[TestCase(2, 1)]
[TestCase(100, 10)]
[TestCase(0, -1)]
[TestCase(-1, -2)]
[TestCase(-10, -100)]
public void When_min_is_greater_than_max_Then_should_throw_exception(int min, int max)
{
Assert.Catch<Exception>(() => _randomizer.GetRandomFromRangeContracted(min, max));
}

[TestCase(0, 0)]
[TestCase(1, 1)]
[TestCase(10000, 10000)]
[TestCase(-1, -1)]
[TestCase(-10000, -10000)]
public void When_min_is_equal_to_max_Then_should_throw_exception(int min, int max)
{
Assert.Catch<Exception>(() => _randomizer.GetRandomFromRangeContracted(min, max));
}

[TestCase(1, 2, 0)]
[TestCase(10, 100, 7)]
[TestCase(-100, -10, -107)]
public void When_return_value_is_less_than_min_Then_should_throw_exception(int min, int max, int expected)
{
_randomMock
.Setup(r => r.Next(min, max))
.Returns(expected);

Assert.Catch<Exception>(() => _randomizer.GetRandomFromRangeContracted(min, max));
}

[TestCase(10, 100, 102)]
public void When_return_value_is_more_than_max_Then_should_throw_exception(int min, int max, int expected)
{
_randomMock
.Setup(r => r.Next(min, max))
.Returns(expected);

Assert.Catch<Exception>(() => _randomizer.GetRandomFromRangeContracted(min, max));
}

[TestCase(0, 2, 1)]
[TestCase(10, 100, 50)]
[TestCase(-100, 10, 5)]
[TestCase(int.MinValue, int.MaxValue, 1)]
[TestCase(int.MinValue, int.MaxValue, 0)]
[TestCase(int.MinValue, int.MaxValue, -1)]
public void When_min_is_less_than_max_Then_should_equal_expected_result(int min, int max, int expected)
{
_randomMock
.Setup(r => r.Next(min, max))
.Returns(expected);

var actual = _randomizer.GetRandomFromRangeContracted(min, max);

Assert.AreEqual(expected, actual);
}

[TestCase(0, 2, 0)]
[TestCase(10, 100, 10)]
[TestCase(-100, 10, -100)]
[TestCase(int.MinValue, int.MaxValue, int.MinValue)]
public void When_min_is_less_than_max_and_result_equals_min_Then_should_equal_expected_result(int min, int max, int expected)
{
_randomMock
.Setup(r => r.Next(min, max))
.Returns(expected);

var actualResult = _randomizer.GetRandomFromRangeContracted(min, max);

Assert.AreEqual(expected, actualResult);
}

[TestCase(0, 2, 2)]
[TestCase(10, 100, 100)]
[TestCase(-100, 10, 10)]
[TestCase(int.MinValue, int.MaxValue, int.MaxValue)]
public void When_min_is_less_than_max_and_result_equals_max_Then_should_equal_expected_result(int min, int max, int expected)
{
_randomMock
.Setup(r => r.Next(min, max))
.Returns(expected);

var actualResult = _randomizer.GetRandomFromRangeContracted(min, max);

Assert.AreEqual(expected, actualResult);
}
}
}

Source


http://stevenhollidge.com/blog-source-code/CodeContracts.zip

Saturday, 26 May 2012

Silverlight Fluid Move Behavior

Check out this excellent tutorial on http://xaml.tv where Victor Guadioso shows how to use the Fluid Move Behavior in Expression Blend:

What you will learn:

  1. How to create sample data (text and images);
  2. How to create a ListBox and bind the ItemsSource to the sample data;
  3. How to create a Details Grid that reflects the selected item of the ListBox;
  4. How to use the Fluid Move and Fluid Set Tag Behaviors to make the selected item animate from the ListBox to the Master Details Grid;

For more Xaml tips check out http://xaml.tv and follow Victor on twitter:  https://twitter.com/victorgaudioso