Friday, October 30, 2009

Silverlight 3 Page Not Found error

I was working on a project when all of the sudden I started getting a “Page Not Found” error. Of course the page is there and it had been working fine. Turns out it was the templates infrastructure hiding the error from me.

When you create a new SL Navigation Application, you’ll find the following in your MainPage.xml.cs.

// If an error occurs during navigation, show an error window
private void ContentFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
    e.Handled = true;
    ChildWindow errorWin = new ErrorWindow(e.Uri);
    errorWin.Show();
}

This nice little piece of code hides the real cause of the error so that all you see is Page Not Found.

Bryant Likes has some code that will give you a better idea of the error.

// If an error occurs during navigation, show an error window
private void ContentFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
    Exception ex = e.Exception;

    while (ex.InnerException != null)
    {
        ex = ex.InnerException;
    }

    e.Handled = true;
    ChildWindow errorWin = new ErrorWindow(ex);
    errorWin.Show();
}

This should save a few hours of looking.

Friday, October 16, 2009

Nice Drop Shadow Border in XAML

I was working with Silverlight 3 and created this drop shadow border. Enjoy.

<Style x:Key="DropShadow" TargetType="Border">
    <Setter Property="Background" Value="WhiteSmoke" />
    <Setter Property="CornerRadius" Value="5" />
    <Setter Property="BorderThickness" Value="1,1,4,4" />
    <Setter Property="Margin" Value="10" />
    <Setter Property="Padding" Value="6" />
    <Setter Property="BorderBrush">
        <Setter.Value>
            <LinearGradientBrush>
                <GradientStop Color="#ccc" Offset="0" />
                <GradientStop Color="#ddd" Offset="1" />
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
</Style>

Thursday, October 1, 2009

Using Interfaces, Generics and the Repository Pattern

I’ve been using the repository pattern to insulate my apps from the LINQ to SQL so that I can easily change when (or if) MS kills L2S. The nice thing about this is that I can write a generic repository the encompasses some of the tasks so that the code is consistent for all repositories.

A little background first. We name all our tables the plural of the objects contained and the first column is an integer primary key named in the singular followed by a “Key” suffix. For example, the Customers table has a first column of CustomerKey. This key name is then used in all related tables as the foreign key column. This makes it very easy to come in behind someone and figure out the data structure.

This convention gets in the way of making life easier for me because all items have a different name for the primary key. To fix this, created an interface called IPrimaryKey, shown below.

public interface IPrimaryKey
{
    int PrimaryKey { get; set; }
}

In my database model, I change the name from CustomerKey to PrimaryKey.

image  image

I then create an interface for Customer and a partial class implementing the ICustomer interface. Note that ICustomer adds IPrimaryKey, so any class implementing ICustomer will also have a PrimaryKey.

public interface ICustomer
     :IPrimaryKey
{
     string FirstName { get; set; }
     string LastName { get; set; }
     string Address { get; set; }
     string City { get; set; }
}

partial class Customer
     : ICustomer
{
}

I can now create an interface for my repository and a generic base class that can be inherited by all my other repositories. Creating an interface allows me to use InversionOfConrol to keep my classes flexible, especially for testing.

public interface IRepository<T> where T : IPrimaryKey
{    
    T GetByKey(int key);    

    void Save(T entity);
}

public abstract class RepositoryBase<T>
    : IRepository<T> where T : IPrimaryKey
{    
    protected BogusDbDataContext dc;
    protected IQueryable<T> SourceTable;    

    public T GetByKey(int key)
    {
        return (from x in SourceTable
                where x.PrimaryKey == key                
                select x).SingleOrDefault();    
    }    

    public IQueryable<T> List()    
    {        
        return from x in SourceTable select x;    
    }    

    public abstract void Save(T entity);
}

And finally here is my customers repository.

public class CustomersRepository
    : RepositoryBase<ICustomer>, ICustomersRepository
{
    public CustomersRepository()
    {
        dc = new BogusDbDataContext();
        SourceTable = dc.Customers;
    }

    public override void Save(ICustomer entity)
    {
        dc.Customers.InsertOnSubmit((Customer)entity);
    }
}

Notice that customers has no code to retrieve an entity by it’s primary key. That code exists in RepositoryBase. All my other repositories can use the same code.

Here is a mock repository and some tests to see how it all fits together.

public class CustomersRepositoryMock
    : RepositoryBase<ICustomer>, ICustomersRepository
{
    private List<ICustomer> customers;

    public CustomersRepositoryMock()
    {
        customers = new List<ICustomer>();

        customers.Add(new Customer() { PrimaryKey = 1, FirstName = "John", LastName = "Public", Address = "123 Main", City = "Somewhereville" });
        customers.Add(new Customer() { PrimaryKey = 2, FirstName = "Larry", LastName = "Jones", Address = "456 Oak", City = "Somewhereville" });
        customers.Add(new Customer() { PrimaryKey = 3, FirstName = "Fred", LastName = "Smith", Address = "789 Grand", City = "Somewhereville" });
        customers.Add(new Customer() { PrimaryKey = 4, FirstName = "Barb", LastName = "Johnson", Address = "1234 Cedar", City = "Somewhereville" });

        this.SourceTable = customers.AsQueryable();
    }

    public override void Save(ICustomer entity)
    {

    }
}
[TestMethod()]
public void GetByKeyTest()
{
    CustomersRepositoryMock repository = new CustomersRepositoryMock();
    int key = 3;
    ICustomer target = repository.GetByKey(key);

    Assert.AreEqual(key, target.PrimaryKey);
}

[TestMethod()]
public void ListTest()
{
    CustomersRepositoryMock repository = new CustomersRepositoryMock();
    IQueryable<ICustomer> target = 
        from x in repository.List()
            where x.LastName.StartsWith("J")
            orderby x.LastName
            select x;

    Assert.AreEqual(2, target.Count());
    Assert.AreEqual("Johnson", target.First().LastName);
    Assert.AreEqual("Jones", target.Last().LastName);
}
The L2S data context needs to be handled appropriately. I treat the repositories as a unit of work in that I dispose of them almost immediately after use. In this way, I don’t get in trouble with load options. I also try to make sure that I return concrete objects except where I use IQueryable methods. This prevents unwanted problems with a data context that no longer exists.

There are other interfaces that can be used such as one for Beginning / Ending dates and IsActive. Again, write the code in RepositoryBase and all the derived repositories can use the same code.