-
Notifications
You must be signed in to change notification settings - Fork 1
Linking to Resources
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; }
}
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.
To create a link to a type rather than an instance, you call the CreateUri method on the type.
var uri = typeof(ContactUs).CreateUri();
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");
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.
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.