Click here to Skip to main content
15,894,825 members
Articles / Web Development / CSS

Building a 3-Tier App with Silverlight 3, .NET RIA Services, and Azure Table Storage

Rate me:
Please Sign up or sign in to vote.
4.89/5 (28 votes)
11 Jul 2009CDDL19 min read 165.6K   1.7K   148  
This article presents the techniques and caveats of building a 3-tire Azure hosted application using Silverlight 3 (presentation tier), .NET RIA services (business logic and data access), and Windows Azure Table (data storage).
// AzureContext.cs
//

using System;
using System.ComponentModel;
using System.Runtime.Serialization;
using Microsoft.Azure.Linq;
using System.ComponentModel.DataAnnotations;

namespace Microsoft.Azure.DomainServices {

    public sealed class AzureTypeDescriptionProvider : TypeDescriptionProvider {

		public AzureTypeDescriptionProvider()
			: base()
		{
		}

		public AzureTypeDescriptionProvider(TypeDescriptionProvider parentProvider)
			: base(parentProvider)
		{
		}
		
		public AzureTypeDescriptionProvider(TypeDescriptionProvider parentProvider, Type domainServiceType, bool isDesignTime)
            : base(parentProvider) {
        }

        public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) {
            ICustomTypeDescriptor baseTypeDescriptor = base.GetTypeDescriptor(objectType, instance);
            if (typeof(Entity).IsAssignableFrom(objectType) == false) {
                return baseTypeDescriptor;
            }

            return new AzureTypeDescriptor(objectType, baseTypeDescriptor);
        }


        private sealed class AzureTypeDescriptor : CustomTypeDescriptor {

            private Type _entityType;

            public AzureTypeDescriptor(Type entityType, ICustomTypeDescriptor parentTypeDescriptor)
                : base(parentTypeDescriptor) {
                _entityType = entityType;
            }

            public override PropertyDescriptorCollection GetProperties() {
                PropertyDescriptorCollection propDescs = base.GetProperties();

                PropertyDescriptor[] newPropDescs = new PropertyDescriptor[propDescs.Count + 1];
                propDescs.CopyTo(newPropDescs, 0);

                newPropDescs[newPropDescs.Length - 1] = new ETagPropertyDescriptor(_entityType);

                return new PropertyDescriptorCollection(newPropDescs);
            }
        }


        private sealed class ETagPropertyDescriptor : PropertyDescriptor {

            private Type _entityType;

            public ETagPropertyDescriptor(Type entityType)
                : base("_ETag", new Attribute[] {
                                    // new ReadOnlyAttribute(true),
                                    new BindableAttribute(false),
                                    new DataMemberAttribute(),
									new DisplayAttribute() { AutoGenerateField = false }
                                }) {
                _entityType = entityType;
            }

            public override Type ComponentType {
                get {
                    return _entityType;
                }
            }


            public override bool IsReadOnly {
                get {
                    // TODO: Hack to make the GetValue hack which returns random values
                    //       on each call work as expected.
                    // return true;
                    return false;
                }
            }

            public override Type PropertyType {
                get {
                    return typeof(string);
                }
            }

            public override bool SupportsChangeEvents {
                get {
                    return false;
                }
            }

            public override void AddValueChanged(object component, EventHandler handler) {
            }

            public override bool CanResetValue(object component) {
                return false;
            }

            public override object GetValue(object component) {
                // TODO: How do we get to the parent domain service
                // TODO: Hack to make the entity appear as if it changed during an update.
                return Guid.NewGuid().ToString();
                // return null;
            }

            public override void RemoveValueChanged(object component, EventHandler handler) {
            }

            public override void ResetValue(object component) {
                throw new NotSupportedException();
            }

            public override void SetValue(object component, object value) {
                // TODO: How do we get to the parent domain service
            }

            public override bool ShouldSerializeValue(object component) {
                return true;
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)


Written By
Technical Lead
United States United States
https://github.com/modesty

https://www.linkedin.com/in/modesty-zhang-9a43771

https://twitter.com/modestyqz

Comments and Discussions