Using a DomainService in ASP.NET and Dynamic Data

Update (8/26/2010): I updated some of the content to reflect the new way to get the bits.

 

One of the big things that I discussed in my MIX 2009 talk is the new DomainDataSource control.  It is available as part of the WCF RIA Services Toolkit.  To install it, you’ll first need to install the core RIA Services.  In addition to the runtime, this will give you some useful tooling to get started.

So basically, there is this thing called a DomainService, which is essentially a Business Layer class that exposes CRUD methods.  Once you have a DomainService, you can use it in various scenarios, including ASP.NET apps and Silverlight apps.  Here, we will focus on its use from ASP.NET. 

Important: the DomainDataSource discussed here is the server side ASP.NET WebForms control.  There is also a Silverlight client control by the same name (also used in RIA services).  And to add to the confusion, Nikhil has a blog post which discusses a sample ASP.NET control also named DomainDataSource.  But it is not the same as we are discussing here.  Yes, I realize that this is pretty confusing.  Just trying my best to clear it up!

The rest of this blog was written for earlier preview bits, and some of the details have changed.  For a walk through based on more recent bits, check out this post by Pranav Rastogi.

 

 

Creating a DomainService

DefaultDomainServiceProject comes with a default DomainService, but to make things more interesting you should just delete it and recreate one from scratch.  Just delete DomainServices\NorthwindEntitiesDomainService.cs.

Now right click on DomainServices, choose Add New Item, and pick Domain Service Class.  Name it for instance Catalog.

image

You’ll see a New Domain Service dialog.  In here, do the following:

  • Uncheck Enable Client Access. That’s only useful for the Silverlight scenario.
  • Check Categories and Products.  For Products, also click the right check box to enable editing.
  • Check ‘Generate associated classes’ at the bottom. This will be useful for Dynamic Data.

image

You should end up with a class that looks like this:

 public class Catalog : LinqToEntitiesDomainService<NorthwindEntities> {

    public IQueryable<Categories> GetCategories() {
        return this.Context.Categories;
    }

    public IQueryable<Products> GetProducts() {
        return this.Context.Products;
    }

    public void InsertProducts(Products products) {
        this.Context.AddToProducts(products);
    }

    public void UpdateProducts(Products currentProducts, Products originalProducts) {
        this.Context.AttachAsModified(currentProducts, originalProducts);
    }

    public void DeleteProducts(Products products) {
        if ((products.EntityState == EntityState.Detached)) {
            this.Context.Attach(products);
        }
        this.Context.DeleteObject(products);
    }

Basically, it’s just a class for a few CRUD methods that you want to expose.  In this case, it’s working over an Entity Framework model (hence the base class), but it would look similar with Linq to SQL or other ORM technologies.

The important part is that all data access goes through those methods, so you have full control over it.  This is quite different from using LinqDataSource/EntityDataSource, where they talk directly to the DAL without going through your code.  You have to write a little code, but the extra control you get makes it well worth it!

 

Registering your DomainService with Dynamic Data

Before we get into writing ‘standard’ ASP.NET pages by hand (in future posts), we’ll use Dynamic Data to get started quickly.  To do this, simply add this line to global.asax (replacing the similar line that’s already there):

 DefaultModel.RegisterContext(
    new DomainModelProvider(typeof(Catalog)),
    new ContextConfiguration() { ScaffoldAllTables = true });

 

Running it

Now you can just Ctrl-F5 and you should get a working Dynamic Data app.  Note how it only lets you do things for which you have CRUD methods.  e.g.  you can edit Products but not Categories.

To make things more interesting, try various things:

  • Debug the app and set break points in your CRUD methods to see them getting called.
  • Change GetProduct() to only return a subset of the products, and watch it affect the UI
  • Change UpdateProduct() to modify the product before saving it,
  • Add some Dynamic Data style metadata in DomainServices\Catalog.metadata.cs.  e.g. add a [Range(0, 100)] attribute to some integer field, and try an edit that violates the range

 

Conclusion

This was really just a quick intro to using DomainService in ASP.NET and Dynamic Data.  I’ll try to follow up with some posts that go into more details on how to use DomainDataSource directly in a page without involving any Dynamic Data.  To reiterate, though Dynamic Data works great with DomainDataSource, DomainDataSource completely stands on its own without Dynamic Data (as was shown in my MIX talk).