Skip to content

Linking to Resources

simonthorogood edited this page Feb 24, 2011 · 8 revisions

Once you have registered resource types in OpenRasta, you will need to link to specific resources.

While you could write all the URIs manually, this doesn’t fit well with refactoring of your URIs and of your resources during development. It’s also a very error-prone process.

To help solve the issue, OpenRasta defines a number of extension methods you can invoke on any object, provided that object type has been registered in OpenRasta.

Consider that your declarations contain the following snippet.

ResourceSpace.Has.ResourcesOfType<Customer>().AtUri("/customers/{firstname}");
ResourceSpace.Has.ResourcesOfType<ContactUs>()
                 .AtUri("/contact")
                 .And.AtUri("contactez").Named("french");
...
public class Customer
{
    public string FirstName { get; set; }
}

Linking to an instance

var customer = new Customer { FirstName "John" }
var uri = customer.CreateUri();

The uri that will get generated will be http://localhost/customers/John. All the uri templates

If multiple URIs are defined for a resource type, OpenRasta will select the URI for which the maximum number of uri templates have been filled. The most specific URI always wins.

Linking to a type

To create a link to a type rather than an instance, you call the CreateUri method on the type.

var uri = typeof(ContactUs).CreateUri();

Linking to a specific Uri Name

An overload of the CreateUri methods is available to let you choose a URI for a specific URI name.

var uri = typeof(ContactUs).CreateUri("french");

Base URIs

By default, OpenRasta will automatically detect which URI the request comes from, and always generate absolute URIs based on this.

All of the CreateUri methods have an overload accepting a baseUri parameter that will be used instead of the ambiant URI when generating a URI.

Making generating URIs testable

There are two ways to make the generation of URIs testable.

Firstly, you can define an IoC container within your setup, and register your own mocked version of the IUriResolver interface, and mock it. Due to the current implementation of .CreateUri you’ll also need to register a communication context mock.

public Mock<IUriResolver> UriResolver;
public void setup()
{
  var resolver = new InternalDependencyResolver(); // or for castle windsor, new WindsorDependencyResolver(new WindsorContainer());
  UriResolver = new Mock<IUriResolver>();
  CommunicationContext = new Mock<ICommunicationContext>();
  resolver.AddDependencyInstance(typeof(IUriResolver),UriResolver.Object);
  resolver.AddDependencyInstance(typeof(ICommunicationContext), CommunicationContext.Object);
  DependencyManager.SetResolver(resolver);
}
public void teardown()
{
  DependencyManager.UnsetResolver();
}

And in your test:

public void the_uri_is_set()
{
  var myHandler = new CustomerHandler();
  UriResolver.Expects(x=>x.CreateUriFor(/*set your expectations */)).Returns(new Uri("http://localhost");
  var myResult = myHandler.Get();
  // assert the uri is set
}

Note: the following may have worked at some point; it doesn’t at changeset 430 on the 2.0.3 branch – use the form above
Optionally, you can simply take a dependency on IUriResolver in the constructor, and use the CreateUriFor method.

public class MyHandler
{
  public MyHandler(IUriResovler uriResolver) { /*...*/ }
  public Customer Get()
  {
    var address = new Address { PostCode "XX1 WW8" };
    return new Customer { Address = uriResolver.CreateUriFor(address) };
  }
}

You can then simply create your test double in your test and pass it to the constructor.

Clone this wiki locally