In the previous post I described an overview of an architecture that could be used when developing silverlight modular apps. In this post I’ll start with a simple business domain model and create a domain layer around that model.

In this example our app will be a web application for a company that sells products and that can be used by its customers to fulfill orders and its employees to process them. These orders have details which consist of products and quantities. Each product can have a product category. When a customer submits an order fulfillment, an employee of the company may process that order to prepare the items for shipping.

The company has a few departments, and each employee belongs to a department. This means that employees from the Sales department will be to process orders; employees from the Human Resources department will be able to recruit new employees; and employees from the Financial Department will be able to watch some charts and print reports with statistics of how sales are evolving as time goes by, sales reports, etc.

Authentication and authorization will be added in the future.

For the sake of simplicity, I’ve create the following data model.

This model will be both our data model and domain model. It is very simple and as I said in the previous post, creating a separate domain model is optional because you can still do fine with your data entities. Since we’re using Entity Framework we’ll take advantage of LinqToEntitiesDomainService, a specific Domain Service that deals with EF’s objects.

Since we’re starting with our Domain layer, we’ll define a Domain Service that can be used from our Silverlight app (or other clients as well) and create the CRUD operations. I’m sure you have noticed how much (duplicated) code is generated when you use the Domain Service template from Visual Studio. Well.. suffer no more! Just create a base class for your domain services and add the following methods:

The Container property is an IUnityContainer instance, that I keep on the base Domain Service. I usually have a common singleton class where the IoC container is available but I also create a child container for each Domain Service. That allows me to register specific instances in the child container and use it only within the scope of my Domain Service. This is useful for resolving repositories because my repositories depend on the ObjectContext which gets injected via dependency injection. This is how it’s done:

For simplicity I’ve included the AttachAsModified method in the IRepository. This method is important because RIA requires that the current entity being updated be attached in the ObjectContext. Another option would be to create a separate interface that derives from IRepository and add the method there. That’s because the IRepository interface is a generic concept that can be used with many data access technologies.

Note that from the moment you create your Domain Service and expose your entities, imediately another person/team can start building the app using the exposed entities, while another team keeps working on the server layer adding metadata and/or validation logic which will also be available to the client application.

In the next post I’ll cover the metadata specification for our entities and that should be enough for our server-side layer, so far.

I’ve been working on a generic repository implementation as well. I took the abstraction a step further in that my repository itself doesn’t depend on the data layer. Instead it delegates its work to a UnitOfWork implementation. That is the only class that has to be implemented specifically for a given data layer. Check out my post demonstrating it here http://azurecoding.net/blogs/brownie/archive/2010/09/22/irepository-lt-t-gt-and-iunitofwork.aspx I’d like to know your thoughts.

1 It’s not from theory it’s from practice. I use this technique in production. And I’m not the first to leverage this approach

2. If I want to expose custom methods on the repository, I just place them on the derived interface and implementation (e.g. IFooRepository:IRepository) other than Sprocs (which I have not needed) everything else is handled.

3. Yes the findby takes a Func but by the time it gets to the DAL itself (for example entity framework) it’s implicitly cast to Expression<Func>.

4. I don’t put attach on the repository because that’s a function of the Unit of Work. The thing about my design is that it allows the client to determine when to execute a batch of operations by being responsible for calling commit on the UOW. So I can perform operations on multiple repositories and commit them in one transaction.

I understand if you didn’t quite understand what was going on, like I said it took a while for me to appreciate the utility of the Unit of Work pattern and even longer to realize that I could make the repository fully independent of the persistence layer.

I recognize the UOW pattern is used and accepted, but I see it as just a variant of IRepository, or a complement of it. That doesn’t make it more or less useful, it exists to solve a specific problem which is the unit of work.

I think (I’m sure) the same can be accomplished by sharing the ObjectContext (or ISession in case of NHibernate) among the IRepository instances, that is doing operations on multiple repositories and then submit the changes in one transaction. All we need is an IDbContext interface or something, that wraps the object that can do unit of works. If you’re using EF or NHibernate you can also do unit of works by using TransactionScopes.

Apart from that, I don’t think that a Func can be implicitly (or even explicitly) converted to an Expression. The opposite can be made by compiling the expression, but if you pass a lambda expression (of type Func) to your FindBy method an execute it against an IQueryable, it will call the LINQ method that receives a Func and not the expression one and so the results are retrieved and filtered in memory. I’m pretty sure about that, unless I’m missing some nasty .NET feature, which I’d like to know🙂.

I must have had a brain lapse or had been sleeping during the class on Expressions. You’re right there is no conversion from Func to Expression<Func> (or any other delegate for that matter). I *Think* it still runs server side but could be mistaken as I am wont to do on ocassion.

I agree with you that there is no universally “right” or “wrong” way to handle data persistence. The benefit from my approach is that the only variant is the UnitOfWork implementation allowing me in many cases to avoid having to implement a custom repository for the simple scenario…and in the other scenarios only having to implement custom named queries when necessary.

Thanks for identifying the gotcha in my design. Truth be told, I was just too lazy to type the extra few characters to make it an Expression<Func>

All said and done, I like your approach to the async querying on the client side for RIA services. Keep up the great work.

This is a great serie about Architecting Silverlight LOB applications.
I hope you ‘ll continue with the serie soon🙂

I have a question about the Server framework and maybe you can help.
I’m trying to create a domain layer which can be used by silverlight and for example the good old WinForms!
I Understand that WCF RIA does the work by handling the client changeset and make the calls to the insert, update and delete methods on the domainservice.
This is great, because this way you can handle your autorisation / validation in one place.
However when using for example winforms changes to the context will not go through the same insert, update and delete methods.
I can use metadata for the simple matters, however what about autorisation and for example complex validation

I thought i could maybe use your DomainRepositoryService but this is not yet possible this way?
For now I’m thinking about 3 possible solutions:

1. Iterate through the changeset myself and call the appropriate methods.
Then i have to work with two context’s one for the “client” changeset and one for the server.

2. Make the Domain entities flat, so it’s not possible to add associated entities.
However then you loose the use of the context?

3. Create a service reference to the WCF RIA service in your WinForms application.
But then you also have to create the changeset in winforms yourself.