Contents tagged with RIA

  • RIA – Should a service return the IQueryable<T>?

    Note: The examples in this blog post uses WCF RIA Services PDC Beta, and changes can be made in the future to the framework.

    In several of my blog posts about WCF RIA Services I have used the Repository pattern to return an IEnumerable<T>, for example:

    public class CustomerRepository : ICustomerRepository
    {
         public IEnumerable<Customer> GetCustomers()
         {
               //...
         }
    }


    And in the DomainService:


    [EnableClientAccess()] public class CustomerService : DomainService { private ICustomerRepository _customerRepository; public CustomerService(ICustomerRepository customerRepository) { _customerRepository = customerRepository; } public IEnumerable<Customer> GetCustomers() { //Use _customerRepository } }
     
    Here is the client-side code which Loads the DTO/”Presentation Model” into the DomainContext:

     var customerContext = new CustomerContext();
    
     customerContext.Load<Customer>(customerContext.GetCustomers());


    The Load method takes a Query object as an argument, by doing so, it knows which method in the DomainService it should call to load the objects. We can on the client-side specify our own query and pass it down to the server, and WCF RIA Services will make sure the execution of the Query will take place on the server side, this will reduce the data passed over the wire to the client. BUT! There is a problem of using IEnumerable<T>. The query will take place on top of the IEnumerable<T>, which means that our Repository will return ALL customers from the database, and this can affect performance (I talked to a well known SQL Server MVP about retrieving too much data from the database, he told me that he never notice a problem of retrieving to much data from a database, there are other issues that can affect performance badly.). So in that case, we don’t need to be worry?! I still think we should try to avoid retrieving data we don’t need from the database.

    How can we solve the above issue with IEnumerable<T>?

    We can for example get the query passed down to our DomainService and pass it to our Repositories, in that case we can use it as a Query Object. We can get the Query information by overriding the Query method of the DomainService class. Another solution is to create our own Query Object and pass it to the server as an argument to the GetCustomers method or just simply use the IQueryable<T> interface.

    How can IQueryable<T> be used?

    When using Entity Framework or Linq To SQL etc, we can create a query, this query will only be executed when we tell it to, for example calling the ToList method, Single etc of the query object:

    var customersQuery = from customer in myContext.Customers
                         where customter.Country == "Sweden"
                         orderby customer.CompanyName
    select customer; var results = customersQuery.ToList(); //Execute the query here


    As long as we don’t execute the customerQuery, we can extend the query, when we are done we execute it. When WCF RIA Services uses the EF or L2S Domain Service classes, it will only return the query (in this case use the IQueryable<T>) and not a list of objects, so when we use the Load method and pass down a query, the query will extend the returned query, and then WCF RIA Services will invoke the query and  EF and L2S will turn the query into T-SQL and execute it against the database. In that way we can reduce the data returned from our database to the DomainSerivce.

    This sounds great, let us always return IQueryable<T>!

    But! and a big one, we can’t use this solution in a RIA where business logic should be on the server-side. In some cases we may need to perform some business logic based on the data retrieved from the database, in this case we need to execute the query before returning our data to the client. So in this case we need to use IEnumerable<T>. But (a lot of but here), if we don’t need to perform any business logic on the server-side before we return our objects to the client, we can use the IQueryable<T>, I think it’s a nice solution for small client/server apps. It requires that the objects we want to send to the client are well designed and with the View in consideration. If we use the IQueryable<T>, we can’t use the Repository pattern, instead we can use a Query provider. So the Repository turns into a query provider:

    public class CustomerQueryProvider : ICustomerQueryProvider
    {
         public IQueryable<Customer> GetCustomers()
         {
               //...
         }
    }

     

    The CustomerQueryProvider can for example use EF or L2S to return an IQueryable<T> of customers:

    public IQueryable<Customer> GetCustomers()
    {
        _myObjectContext.Customers;
    }
    

     

    The DomainService will look like this:

     

    [EnableClientAccess()]
    public class CustomerService : DomainService
    {
         private ICustomerQueryProvider _customerQueryProvider;
    
         public CustomerService(ICustomerQueryProvider customerQueryProvider)
         {
             _customerQueryPrivider = customerQueryProvider;
         }
    
         public IQueryable<Customer> GetCustomers()
         {
             //Use _customerQueryProvider.GetCustomers()
          }
    }


    The reason why a Query Provider is used here, is to remove dependencies to a specific detail. Now we can have different Query Providers as long as they implements the ICustomerQueryProvider interface and the infrastructure used in the Query Provider supports the IQueryable<T> interface.

    Summary

    For small database driven RIA where almost not business logic is needed, we can get a lot of benefits of using the IQueryable<T> interface instead of the IEnumerable<T>. But in a enterprise RIA where business logic should take place on the server-side, the IEnumerable<T> can be a better choice. But it depends! There are so many factors that must be known before we can know which design will fit best.

    If you want to know when I publish new blog posts, you can follow me on twitter: http://www.twitter.com/fredrikn

    Read more...

  • Is WCF RIA Services ready for the Enterprise?

    Today Microsoft released the WCF RIA Services Beta, it’s now on top of WCF and by default uses binary data end points and data contract serialization. By using binary data end points we will get better performance and make the data sent over the wire smaller (The other preview versions uses pure JSON). WCF RIA Services is a great framework for Rapid Application Development (RAD) of 2-tier applications. Based on the new changes to the WCF RIA Services it’s defiantly ready for the Intranet and small applications, but how about the Enterprise. First of all if you uses the Entity Framework or Linq to SQL Domain Services, it’s not ready for the Enterprise and will never be, IMO, because when we use it it distribute DAL types to the client. They are useful for small data driven applications. BUT! WCF RIA Services with the DTO (Data Transfer Object) support will make it closer to be ready for the Enterprise, but is that enough?

    It’s complex to build RIA (Rich Internet Application) and require a lot of plumbing. This is something WCF RIA Services is trying to solve. Just remember there is a reason why things are complex, and what every framework developers are trying to do, is to hide the complexity by adding a new level of abstraction. The thing is, the complexity is still there. At first I was skeptic about WCF RIA Services, but it was because the very early previous wasn’t that good, it was ok, good ideas but works had to be done. Now after almost 2 years it starts to look like something promising.

    I have notice several of developers using .WCF RIA Services and because it’s so easy to use, they seems to forgot about the network. What the WCF RIA Services Team have struggle with, is to make sure developers should be aware of the network. I know that even how much they try, some developers will use it in a wrong way. That is nothing they can do anything about. But is that so bad? NO! It gives the people that use it in the right way job opportunists ;)

    I wrote that WCF RIA Services with its DTO support will make it closer to be ready for the Enterprise and the uses of EF and L2S Domain Services are not a good choose when it comes to build Enterprise RIA. There are actually one advantage of using the EF and L2S DomainServices, and that is the way of passing a query from the client to the server. The query will be used when EF and L2S are querying the database (as far as I know, I hope it does at least ;)). It will results in less data sent from the data source. When using DTO the query will take place after we retrieve all the data from our DomainService query methods. But still on the server. But the good thing is that there is a solution to make sure the query also takes place when we query our data source and that is by overriding the DomainService Query method, it has the description of the query passed from the Client. But we had to interpret it and transform it to a query which can query our domain model.

    It looks like developers loves the data annotations added to WCF RIA Services. The validation part is great when it comes to the uses of EF and L2S Domain Services, because the DAL types are generated from the tools (hmm, thinking of the Devils is in the tools ;)), and it’s “hard” to add validation to it. In that case with WCF RIA Services we can use annotation to add validations, which will be available both on the client and the server. Isn’t that great? DTO also support validations buy adding annotations. You have to have in mind, that this validation can’t be tested with Unit Test, it’s the Framework which will execute it. But you also have to remember that DTO is just what is says an object which transfers data. On the client-side we may use a ViewModel which will handle the validation instead.

    Back to the main question, is WCF RIA Services ready for the Enterprise? If I say Yes, it may be a lie, if I say No, it’s definitely a lie. I think it’s ready, or at least I would give it a try. I think the team have made a great framework, I will with no doubt recommand it to others.

    Read more...

  • Distributing domain entities over the wire

    When we design our domain entities we don’t have a presentation layer or database in mind. The domain entities are core business objects located on the server or client side based of what kind of application we are building. Domain entities aren’t designed for distribution. When we realize that we need a distribution, we shouldn’t distribute the entities, instead collect the data we need to distribute and create a data transfer object (DTO) instead. Have the network in mind, a domain entity aren’t designed with a network in mind and of that reason not suitable for distribution. When we create our domain entities, they aren’t designed for presentation purpose, they are designed to fulfill business needs. You should be careful when you start thinking about returning a domain entity to the View when using a patterns like MVC, instead use DTO or a ViewModel, because once again the domain entities aren’t designed with presentation in mind, and aren’t often suitable for presentation purpose. It’s often better to map them to a DTO or ViewModel, objects that are suitable for presentation purpose or passed over the wire.

    Read more...

  • .NET RIA Services Exception handling

    Note: This post is based on the July preview of the .NET RIA Services, so changes may happen in a future release of the framework

    At the moment I’m updating a code example for my Silverlight 3.0 course and have added some exception handling to the code. I also got a question about how to handle exception while calling the Load operation of the DomainService class. So I decided to write a blog post about it, maybe someone more have the same question.

    By default if you make a call to a DomainService query method, you will not get an exception on the client-side, if you don’t adding some extra code. Lets pretend that the following code is your DomainService and Query method:

    public class MyDomainService : DomainService
    {
          public IEnumerable<Customer> GetCustomers()
          {
               //Code that can throw an exception;
           }
    }

    The method above will throw an exception. If you on the client-side want to “call/use” the GetCustomers method, you will use the generated DomainContext class’s Load method:


    var d = new MyDomainContext(); var loadOperation = d.Load<Customer>(d.GetCustomersQuery(), MyCallBack, null); LayoutRoot.DataContext = d.Customers;



    When this code is executed, you will not get any exception, so the user or you may think that no exception have occurred. But that isn’t the case. So what I’m going to write about now, is different way you can check if an exception occurred (Wouldn’t it be nice if we only could get an exception instead of adding extra code to check if an exception is thrown ;)).

    The LoadOperation class has two properties we can use, HasError and Error. To check if we got an exception we can use the HasError property, if we want to get information about an exception, we can use the Error property. The first example I’m going to use, will only display an exception for the client.

    On the client-side I have a StackPanel called myErrorPanel, it also have a TextBlock where the Text property is bound to a property path “Error.Message”.


    <
    StackPanel x:Name="myErrorPanel"> <TextBlock Text="{Binding Path=Error.Message}"></TextBlock> </StackPanel>


    In the code-behind we can now write the following code which will bound the LoadOperation to the myErrorPanel:


    var d = new MyDomainContext(); var loadOperation = d.Load<Customer>(d.GetCustomersQuery()); LayoutRoot.DataContext = d.Customers; myErrorPanel.DataContext = loadOperation;


    If the Load method of our DominContext has an error, the Error Message will be displayed for the User. By using this solution, we will not have any idea if an error has occurred during the Load operation, if it does it will only be shown for the User. The StackPanel will also take up some space on the user interface, so to solve it we can for example add a Converter, and bound the HasError to the StackPanel’s Visibility property. The following two other solution will instead show us, how we can use a callback method and the LoadOperation’s Complteted event to have a better control if an exception is thrown during the Load operation.

    The DomainContext’s Load method can take a callback as an parameter, by using a callback, we will get a notification when the Load operation is completed, and we can also see if there was any error during the Load operation. The following code will use a callback and check if an error has occurred:


    var d = new MyDomainContext(); var loadOperation = d.Load<Customer>(d.GetCustomersQuery(), MyCallBack, null); ... void MyCallBack(LoadOperation<Customer> loadOperation) { if (loadOperation.HasError) //Handle the error }


    The following solution will use the LoadOptions’s Completed event to check if an error has occurred:


    var d = new MyDomainContext(); var loadOperation = d.Load<Customer>(d.GetCustomersQuery()); loadOption.Completed += new EventHandler(loadOption_Completed); ... void loadOption_Completed(object sender, EventArgs e) { if (((LoadOperation)sender).HasError) //handle the error }


    If you wonder what solution I prefer, it would be the one that uses a callback. I do want to see some changes to the .NET RIA Services Load operations, like specifying a callback just for handling exceptions, and a default generated callback added to the DominaContext, which will be called if no callback is used, by doing so, we could get an exception when the Load fails without adding some extra code.

    Read more...

  • How SubmitChanges works in .NET RIA Servies

    Now I’m back from my 4 week long vacation. I have spend a lot of time with my new apartment, took about 2 month to get most of it ready, I still have a lot of things to do, but all the painting and stuff are done :) I got a question on my e-mail regarding .NET RIA Services and the Business Application project’s UserRegistartionService. It was about the AddUser method in the Service and when and where it’s called. I thought it would be great to write a post about it.

    Read more...

  • Will .NET RIA Services be the Silver Bullet!

    I have spend some time on the Silverligth.net forum and in the .NET RIA Services thread.. and just created a replay on a post about RIA Architecture and design.. I have some concerns regarding to how developers are using .NET RIA Services etc.. maybe it’s not a big deal.. but I will try to share my concerns and made a copy of my replay and created it as a blog post. I look forward to your comments. To get basic understanding about about my view of a RIA Architecture and also .NET RIA Servers, I prefer you read my two other blog post before you read this blog post.

    RIA Architecture with Silverlight in mind

    A different view of the .Net RIA Services

    Developers are so desire to use a perfect and great domain model to work with. It will help us a lot..(I will claim that a domain model is not a silver bullet, it's a way we prefer to work these days, and I prefer it too). We are used to work that way, we like to work that way.. so why not do it and why not in a distributed system? There are some technologies that tried to make sure we could work with object in a distributed system, like DCOM, CORBA and RMI etc. Now we have .NET RIA Services..

    When I have read threads in Silverlight.Net forum, I notice that developers tries to create complex models and want a server side model to also be used on the client side. Nothing strange, it’s how we will work, right? So what is the main problem? Well, developers creates complex models, and do it in one place (on the server side), and the .NET RIA Services can "copy" by using code-gen this model to the client-side. Developers can still work with the entities as it was locally, because it is what we want to do, it make it a lot easier for use to build our apps.. we are used to it! But one of the problems with systems like DCOM, RMI, CORBA and sort of .NET RIA Services is that they tend to try and hide the fact that we are actually talking across a network. Everyone that uses these technologies knows that we are talking across a network, but it’s so easy to forget about it, because of the possibility to use object in a way we want to. The way they hide it, is that we don’t need to care about knowing about it. It’s the plumbing that is removed from us. So we can create our model, and suddenly we have it on the client side and can work with it as it was “locally”. We have one place where we create our shared domain model and we can forget about the network (not saying that everyone does, but regarding to some post in this forum, I think they are).

    By adding inheritance, lazy-loading (which we want to use, to solve some problems) etc, will only make sure we try more and more to work in a way we are used to, even with a distributed system, and we will get blinded and don’t see the network. We don’t want to see it, because it will affect how we wants to work, and it make sure we can’t do what we wants to do.. so we just remove it from our mind, we hide it, we don’t see it, we pretend it wasn’t there. I love the sounds of it, it would be perfect if we don’t need to think about it. Because if it was never there, we can work in the way we want to work, right?

    As long as developers know and have the network in mind and create a model based on it, I will be satisfied, but it will probably not happen. The same mistakes have done before, and we are only repeating our self. Designing a system that uses both network capabilities and object oriented design techniques to their fullest advantage is still possible and desirable, and engineers will try to solve this. Some day they may succeed, maybe the final version of .NET RIA Services will be the ONE! But as long as there isn’t a Silver bullet yet! I will try to remind people about the network and the distribution.

    EDIT: Only to not get comments regarding the hidden stuff:

    I know that .NET RIA Services team is not trying to “hide” the distributin, but the way people wants to use it, to solve a common problem, and what they are requested and tries to do, concerns me.. and what most developers wants (if it will be available), will make sure the distribution will become “hidden”.

    Read more...

  • RIA Architecture with Silverlight in mind

    Rich Internet Application (RIA) is an interesting topic. More and more business apps are moving into to the cloud, and more and more will have better User Experience (Ux). According to Gartner Research, nearly 60 percent of all new application development will include RIA technology by 2010. Today we can use different technologies to build a RIA, for example, AJAX, Flash and Silverlight etc. When it comes to AJAX we will soon reach the top of what we can do with it, because of the limitation of HTML, Client-side scripts and the browsers etc. That makes Silverlight and Flash more interesting regarding to me. But what is RIA? RIA It’s an internet applications that looks and feels like desktop applications, it also provide most of the maintainability and deployment benefits of Web applications. A RIA client can have state, so to increase User Experience, the user can work with data for a while until it will be passed down to the server for processing. Because the client side of a RIA can have state and work with data for a while, it’s extra important to have concurrency in mind. Some other users can have changed the data during the time we have worked with our copy. When developing RIA Clients we need to have several things in mind, for example a RIA is often running within an execution container in the Browser, so people can hit the refresh button or use the back and forward buttons, which can be reload the whole app and the current state can be gone. When we creates a large RIA, we can’t let users wait for hours until the application is loaded and started, so we need to load views etc on demand, and split them into small “modules”. Developing a RIA is not like developing a stateless ASP.NET app.

    In this post I will write about the architecture and design I use when building a RIA with Silverlight.

    The following is a figure of an Architecture of a typical RIA implementation:


    RIA_arch

    The Presentation Layers purpose is to make sure users gets the best possible User Experience. The Presentation Layer of a RIA should not include too much business logic, instead it will communicate with a Web Server to perform business operations. This is done by accessing a Application Service Layer which in turn will communicate with the Domain Model [Evans DDD]. In this post I will focus more on the Application Service Layer and the Presentation layer, rather then the other layers or tiers.

    Business Logic, where to place it?

    Because a RIA often look and feel like a desktop application, and can have state, it can be appealing to add a lot of business logic to the Presentation Layer. But try to not do that. The only kind of business logic that should be in the Presentation Layer is user input validations, and business logic that can increase user experience and increases performance overall, for example by avoiding communications to the Web Server or some expensive business operations, which can for example improve the UI responsiveness. Start with your business logic implementation on  the server and expose them through services. It will make sure you don’t start adding a lot of business logic to the client at the first place. One problem with the business logic is that same business logic can exists on both the client and server side. For example validations. To address this issue you can for example use the Microsoft .NET RIA Services. If you don’t want to use the .NET RIA Services, make sure you group the business logic into a separate assembly, which you can share both with the Server and client, or at least make sure you reuse the same kind of code and language, so you can easily replace the code when changes is made to the business logic on the server and should also be changed on the client side. Some logic should never be on the client side, such as highly sensitive business logic. Add it to the server for security reasons. If the client side are going to need a lot of business logic that can be changed often, make sure to add it to a downloadable module. It will make it easy to replace the logic without re-downloading the entire RIA application.

    How to share Business logic between tier with .Net RIA Services

    The .NET RIA Services lets us create a DomainService where we can add our CRUD operations and custom queries. We can also use metadata to add shared validation logic and also add code that should be shared between the client and the server. .NET RIA Services will locate our DomainServices, metadata and shared code, and generate client-side classes for us. The following code is a simple DomainService which will return a list of an “Entity” (You can find more about design considerations etc when creating entities later in this post):

    [EnableClientAccess()]
    public class UserService : DomainService
    {
        private UserDataService _userDataService = new UserDataService();
    
        [Query(PreserveName=true)]
        public IEnumerable<User> Followers()
        {
            return this._userDataService.Users;
        }
    }


    Here is en implementation of the User Entity:


    public partial class User
    {
       [Key]
       public string ID { get; set; }
    
       public string Name { get; set; }
    
       public string Description { get; set; }
    }


    To add validations that are applied on both tiers we can create a metadata class:

    [MetadataType(typeof(UserMetaData))]
    public partial class User
    {
        internal sealed class UserMetaData
        {
            [Required]
            public string Name;
    
            [Required]
            [StringLength(255, MinimumLength = 0)]
            public string Description;
        }
    }


    The above metadata class will make sure that the generated Entity for the client-side will have the validations specified by using attributes. When it comes to validation, make sure to validate both on the client side to improve user experience, and server side validation for security. The magic to share business logic between the client and server is by using code generation. There is only one place the business logic is added, and it’s on the server side, but can be shared with the client side without adding duplications.


    Communication

    To increase the user experience and performance, the communication from the client side to the server must be made asynchronous. If not we can block the UI thread. If long running code is needed, it’s worth to consider if a background thread should be used or not. Here is an example how the Silverlight’s BackgroudWorker can be used to run a thread in the background:


    public MainPage()
    {
        InitializeComponent();
    
        var bw = new BackgroundWorker();
        bw.RunWorkerCompleted += bw_RunWorkerCompleted;
        bw.DoWork += bw_DoWork;
        bw.RunWorkerAsync();
    }
    
    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        //perform the work
        e.Result = result of the operation if any
    }
    
    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Error != null)
           //handle exception
    
        //get the result from e.Result and do for example update UI
    }

    Note: When performing operations in a background thread, it can be advisable to show the user the progress of the operation (if the user should see any result after the operation is completed). The BackgroundWorker class has a ProgressChanged support.

    To communicate to the Server, WCF, APS.NET WebServices, .NET RIA Services, ADO.NET Data Service, WebClient etc can be used. When passing data from server to the client or back, try to remember that there can be some bandwidth limitations. When creating a distributed system, objects shouldn’t be distributed. So don’t distribute your domain model’s entity. Instead create new kind of “resources”. For example by using formats like JSON, XML or DataContracts, and only pass the data that is needed by the presentation layer. Try to focus on what data a specific View needs. If you need to save data on the client-side for offline support, make sure to use the Isolated Storage or the new SaveFileDialog added to Silverlight 3.0. Don’t use a local databases, instead make sure you make a call to a Service. If it would be catastrophic to lose state data on the client, make sure to store it on the server. Try to minimize the number of round-trips to the server. Make sure to filter all data at server rather than at the client to reduce the amount of data that must be sent over the network. By using .NET RIA Services, we can without adding new methods to the DomainService, make sure a Query is passed as an argument to the server and the server will do the filtering. Try to avoid creating too much queries on the client side, if you have common quires witch is located on several Views on the client side, make sure you add a common query as a method to a DomainService instead. It will make it much easier for you to maintain  the application.

    The following is an example of how WebClient together with XDocument can be used to retrieve data from the server, with a REST like way:

    public MainPage()
    {
         InitializeComponent();
    
         var wc = new WebClient();
    
         wc.OpenReadCompleted += wc_OpenReadCompleted;
         wc.OpenReadAsync(new Uri("/User/Followers", UriKind.Relative));
    }
    
    void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
        XDocument xmlUsers = XDocument.Load(e.Result);
    
        var users = from user in xmlUsers.Descendants("user")
                    select new
                           {
                             ID = (string)user.Element("ID").Value,
                             Name = (string)user.Element("Name").Value,
                             Description = (string)user.Element("Description").Value
                           }; 
    
    }



    The “/User/Followers” URI used by the WebClient, can for example be a REST API created by using ASP.NET MVC:


    public class UserController : Controller
    {
        public ActionResult Followers()
        {
            var userDataService = new UserDataService();
    
            return View(userDataService.Users);
        }
    }
    
    Followers.aspx 
    
    <%@ Page Language="C#" 
             Inherits="System.Web.Mvc.ViewPage<List<Models.User>>" %> 
    <users type="array"> 
        <% foreach (var user in ViewData.Model) { %>
            <user> 
                <id><%= Html.Encode(user.ID)%></id> 
                <name><%= Html.Encode(user.Name)%></name> 
                <description><%= Html.Encode(user.Description)%></description> 
            </user>
        <% } %> 
        </user> 
    </users>


    The following is how we can use a WCF Service to retrieve data from the server. The WCF Service is part of the Application Service Layer:


    [DataContract]
    public class User
    {
        [DataMember]
        public string ID { get; set; }
    
        [DataMember]
        public string Name { get; set; }
    
        [DataMember]
        public string Description { get; set; }
    }

     

    public class UserService { private UserDataService _userDataService = new UserDataService(); [OperationContract] public IEnumerable<User> GetFollowers() { return _userDataService.Users; } }

     

    MainPage.xaml.cs

    public MainPage()
         {
             InitializeComponent();
    
             var us = new UserServiceClient();
             us.GetFollowersCompleted += us_GetFollowersCompleted;
             us.GetFollowersAsync();
             
             
             myGrid.ItemsSource = _uc.Users;
             _uc.Followers(_uc.Users.AsQueryable<User>().Where( c => c.ID == "1") , null);
    
         }
    
         void us_GetFollowersCompleted(object sender, GetFollowersCompletedEventArgs e)
         {
             myGird.ItemSource = e.Result;
         }


    As you can see in the above code, a DataContract is created, this contract should only return the information that the client needs. To minimize the data sent to the client over the network, it can be good to create data contracts for each View (Client side “forms”), but be pragmatic. If we will have more than one View that need the same data, we can reuse the same contracts if the different is only one or two properties, it may be unnecessarily to create two data contracts to reduce the data sent over the wire. But still have bandwidth in mind. I often create one Service per View, and if there are some other Views that should reuse the exact same kind of operations I reuse the Service, or create a new Service which in turn will access the other Service. It depends on the app and the Views etc.

    To make a call to a WCF Service, a Service Reference is needed to locate the Service and to create a client-side proxy class to make it easy to communicate with the Service.

    In the first example in this post I showed some .NET RIA Services code, where I created a DomainService. When the solution is build a generated proxy class will be created and added to the Silverlight project. This class is called a DomainContext. Here is an example where .NET RIA Services DomainContext is used to communicate to the DomainService:


    public partial class MainPage : UserControl
    {
        UserContext _uc = new UserContext();
    
        public MainPage()
        {
            InitializeComponent();
    
            var us = new UserServiceClient();
            us.GetFollowersCompleted += us_GetFollowersCompleted;
            us.GetFollowersAsync();
            
            myGrid.ItemsSource = _uc.Users;
            _uc.Followers();
    
        }
    
        void us_GetFollowersCompleted(object sender, GetFollowersCompletedEventArgs e)
        {
            myGird.ItemSource = e.Result;
        }
    }


    Now when you have seen some different ways to communicate with a Service form the Client, we can focus more on the data passed to the client from the server and back..

    Data

    When creating a distributed system we should never distribute an object. So don’t try to pass entities from the Domain Model to the client side. Instead create a new model only for presentation purpose. For example with DataContracts or if you are using REST a resource, or a thin object only used for presentation purpose if you are using .NET RIA Services. Here is a figure over how I often build my applications:

    ria_arch2

    Note: The View Model is not the Pattern ViewModel. It’s a model created for presentation purpose only, for example a DataContract, or at .NET RIA Services Entity etc.

    One of the important part when creating a RIA, is to focus on the “model” that the View should use. If we for example should list all Customers, and we only need display three properties, we creates a class/resource or DataContract for that purpose, for example:

    public partial class Customer
    {
       [Key]
       public string ID { get; set; }
    
       public string Name { get; set; }
    
       public string Country { get; set; }
    }


    If we need more detail about a Customer, we create a new class with the properties needed:


    public partial class CustomerDetail { [Key] public string ID { get; set; } public string Name { get; set; } public string Country { get; set; } public string Description { get; set; } public string Email { get; set; }

    ... }


    When building RIA, performance and bandwidth is something we should have in consideration, so it’s not sure a user will show detailed information about a Customer, so in this case we make sure we have two methods in our Application Service Layer, GetCustomer and GetCustomers. The GetCustomer will return the CustomerDetail class and the GetCustomers the Customer class. If we know that a user will show all the information of a customer, and will get a set of Customers to always work with. We can create a method that will return a list of CustomerDetails. If we create a small applications for few users and it’s an intranet application, the bandwidth may not be a problem, so in that case we can return more data that isn’t needed in specific scenario but is needed for other scenarios to reduce the number of classes created etc. So everything depends on!

    Presentation Layer Pattern

    I often use a UI patterns like the Presentation Model/ViewModel pattern. The MVC pattern could be used, but I prefer the Presentation Model pattern in a RIA. If you are interested in how a Presentation Model could look like when using Silveright, you can read the following post on my blog: http://weblogs.asp.net/fredriknormen/archive/2009/01/30/how-the-presentation-model-could-look-like-when-using-silverlight-2-0.aspx

    The end

    There is so much to write about when it comes to the topic of this blog post but I hope you have found some useful tip. If there is something you don’t agree on, please let me know, I only share my experience ;)

    Read more...

  • A different view of the .Net RIA Services

    Some of you have probably heard about the Microsoft .Net RIA Services, if not you can find some info here. In this post I will show you a different view of the .Net RIA Services, how it can be used to create a RESTfull Service, or at least try ;)

    REST Services is about “nouns” (resources, like friends, customers etc) with few “verbs” for example create, read, update and destroy. We can easily create a “resource”, where the resource can be in different kind of formats like JSON, XAML, RSS etc. It’s more or less up to us what kind of formats we want to use. If we take a look at Twitter, the REST API they use can return a resource in different formats. When we create the resource, we need to create the response value (A Response value is the value returned from a REST API, it’s a resource in a specific format). If we want to get all of our Followers by using one of the Twitter’s REST API, we simply use the following URL: http://twitter.com/statuses/followers.xml the .xml at the end specify the resource “followers” format. The response value is something like this:

    <?xml version="1.0" encoding="UTF-8" ?> 
    <users type="array">
       <user>
         <id>1111111</id> 
         <name>John Doe</name> 
         <location>Stockholm</location> 
         <description /> 
         <profile_image_url></profile_image_url> 
         ...
    
       </user>
    
       ...
    
    </users>

    The resource is something the developers of the API have decided. If we want to use the .NET RIA Services we can simply define the resource of the response value like a simple POCO class. Like this:

    public partial class User
    {
        [Key]
        public string ID { get; set; }
    
        public string Name { get; set; }
    
        public string Description { get; set; }
    }


    Note: The KeyAttribute is needed to specify a way to specify a property which will work as an identity for the “entity”.
    When using the .Net RIA Services the the classes we can create are referred as a Entity in a model. So we create a “model” more or less, but don’t see the User class as an entity in a Model, instead as a resource used by a specific REST API.

    By default .NET RIA Services will “serialize” the above class to a JSON format similar to this:

    {
       "__type":"User:http://schemas.datacontract.org/2004/07/SilverlightApplication8.Web.DataModel",
       "ID":"1",
       "Name":"John Doe",
       "Description":"John Doe\u0027s description"
    }


    Remember that this post is a different view of the .Net RIA Services, so once again try to see the POCO as a simple resource, not as an object which we will distribute (We all know that we shouldn’t distribute objects).

    Now when the resource is created, we can simply create a “fake” object which will return a list of it.

    public class UserDataService
    {
        public IEnumerable<User> Users
        {
           get
           {
               return new List<User>()
                      {
                          new User()
                          {
                              ID = "1",
                              Name = "John Doe",
                              Description = "John Doe's description"
                          },
                          new User()
                          {
                              ID = "2",
                              Name = "Jane Doe",
                              Description = "Jane Doe's description"
                          }
                      };
            }
        }
    }


    Note: I couldn’t find a good name for this class, it looks like its a some kind of data access class but it isn’t. It’s more like taking a existing model and transform it to a resource.

    The next step is to create our REST API, in this case we can for example call it Followers, the same name as Twitter uses to get Followers. We can for example use ASP.NET MVC or a normal WebForm as a REST Service to get our resource.

    The following is a REST Service where ASP.NET MVC is used with a Controller named UserController with and an Action method called Followers.


    public class UserController : Controller
    {
        public ActionResult Followers()
        {
            var userDataService = new UserDataService();
    
            return View(userDataService.Users);
        }
    }


    Followers.aspx


    <%@ Page Language="C#" 
             Inherits="System.Web.Mvc.ViewPage<List<Models.User>>" %> 
    <users type="array"> 
        <% foreach (var user in ViewData.Model) { %>
            <user> 
                <id><%= Html.Encode(user.ID)%></id> 
                <name><%= Html.Encode(user.Name)%></name> 
                <description><%= Html.Encode(user.Description)%></description> 
            </user>
        <% } %> 
        </user> 
    </users>

    We can get the Followers by simply use the following URL:   /User/Followers">http://<servername>/User/Followers

    To call the REST Service and it’s API, we can for example use the Silverlight’s WebClient class. We can also use the XDocument to get the data out from the resource:

    public MainPage()
    {
         InitializeComponent();
    
         var wc = new WebClient();
    
         wc.OpenReadCompleted += wc_OpenReadCompleted;
         wc.OpenReadAsync(new Uri("/User/Followers", UriKind.Relative));
    }
    
    void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
        XDocument xmlUsers = XDocument.Load(e.Result);
    
        var users = from user in xmlUsers.Descendants("user")
                    select new
                           {
                             ID = (string)user.Element("ID").Value,
                             Name = (string)user.Element("Name").Value,
                             Description = (string)user.Element("Description").Value
                           }; 
    
    }


    If we use the above solution we need to do some plumbing. We first need to do a request to our URL to get the followers, then we need to read from the XML and get the values and map it to a type (if we want to work with a typed result). In this case wouldn’t it be nice to avoid some plumbing and instead use a solution where we simply use a typed API (not a string), and also get the result as typed classes with properties?

    Instead of doing all the plumbing, we can use the .Net RIA Services to create a REST Service. To create and implement our REST Service and API, we create a DomainService. A DomainService within the .NET RIA Services is a class where we add our CURD API and we can also add shared domain methods etc. To create a DoaminService we create a new class which will inherits from the .NET RIA Service’s DomainService base class. We will also add our Followers API to the DomainService:


    [EnableClientAccess()]
    public class UserService : DomainService
    {
        private UserDataService _userDataService = new UserDataService();
    
        [Query(PreserveName=true)]
        public IEnumerable<User> Followers()
        {
            return this._userDataService.Users;
        }
    }


    Note: The EnableClientAccessAttribute is only used to make sure .NET RIA Services creates a client-side proxy for our DomainService, this proxy is called a DomainContext. The QueryAttribute with the property PreserverName, will make sure the generated DomainContext for the DomainService will preserver the name Followers. Normally we should add a method called “GetFollowers”, and the .NET RIA Services code generation will generate a method for the DomainContext called “LoadFollowers”.

    The Followers method will use the UserDataService’s Users method to get all the followers and return them.

    When we build our solution, the .NET RIA Services will generate a DomainContext for our Silverlight app, a proxy class which will make it easier for us to “call” the DominService. The generated DomainContext will communicate to the service through an AXD called DomainService.axd using REST. After we have created our DomainService, we can if we wants to, do a direct call to the DomainService.axd and use it as a REST Service:

    http://<servername>/DataService.axd/SilverlightApplication8-Web-DataModel-UserService/Followers

    When we enter the above URL we will get a response value in a JSON format like this:

    {
        "__type":"DataServiceResult:DomainServices",
        "IsDomainServiceException":false,
        "Results":
            [
                {
                    "__type":"User:http://schemas.datacontract.org/2004/07/SilverlightApplication8.Web.DataModel",
                    "ID":"1",
                    "Name":"John Doe",
                    "Description":"John Doe\u0027s description"
                },
                {
                    "__type":"User:http://schemas.datacontract.org/2004/07/SilverlightApplication8.Web.DataModel",
                    "ID":"2",
                    "Name":"Jane Doe",
                    "Description":"Jane Doe\u0027s description"}
            ],
        "TotalCount":-2
    }

    Note: The DomainService.axd will by default using the JavaScriptSerializer.

    The DomainSevice.axd will take the first “parameter” “SilverlightApplication8-Web-DataModel-UserService”  and replace “-“ to “.” to get the DomainService to instantiate. In this case it will be the UserService. It will then call a method with the same name as the last “parameter” of the URL, in this case “Followers” and use the JavaScriptSerializer to serialize the result of the Followers method.

    By using a class we create our resource. We have used the .NET RIA Services to create a REST Service with the API Followers to return a list of Users. We can then use the DomainService.axd to call our REST API. To make it simple for us to call the REST API and get a list of Users, we can now use the generated client-side proxy class (DomainContext) in our Silverlight project. It will give us a typed API and also a typed resource. So we don’t need to use the WebClient or a JSON Serializer on the client-side, the generated DomainContext for our DominService, will handle that for us. The following code is the code-behind file of the MainPage.xaml in a Silverlight app:


    public partial class MainPage : UserControl
    {
        UserContext _uc = new UserContext();
    
        public MainPage()
        {
            InitializeComponent();
    
            myGrid.ItemsSource = _uc.Users;
            _uc.Followers();
    
        }
    }

    To make a call to the Followers API, we simply instantiate the generated DomainContext class “UserContext” and make a call to the Followers API. Every “entity/resource” we creates and returns from the DomainService will be added to the DomainContext as properties. So to get the User class after we make a call to the Followers method, we can use the Users property. When we call the Followers method, an asynchronous call to the DomainService will be made. The DomainContext will use REST behind the scene and call the DomainService.axd.

    Wouldn’t it be nice if we could instead of getting a whole list of Users, make it possible to define a query which will only returns the Users we want based on a criteria? It’s possible, and that is really cool:


    public MainPage()
    {
        InitializeComponent();
    
        myGrid.ItemsSource = _uc.Users;
        _uc.Followers(_uc.Users.AsQueryable<User>().Where( c => c.ID == "1") , null);
    }


    By default all “Query” methods added to the DomainService, takes a IQueryable as an argument. So we can pass a query as an argument. So now we can use the DomainContext as a proxy to call a RESTful Service and also define a query.

    In this post, I wanted to give you a “different” view of .NET RIA Services, more or less to make sure you know how it works behind the scene, and also how it can be used to define a resource and a RESTful Service, because behind the scene .NET RIA Services uses REST.

    Read more...