Friday 24 August 2012

POCO vs EntityObject (EF) model

What is a poco object?

POCO is a short for Plain old clr object and refers to an object that does not depends on the framework. It will not inherits and it should support it's own functionnalities.

For example, when you get to chose a generation template for your edmx, you will have Self-Tracked entity objects. These will be generated over a POCO model and will contain their own methods for propertyChanged and will also contains it's own EntityState property as it cannot rely on it's base object.

What is the EF model?

The alternative to POCO is to generate your entities and inherits them from EntityObject. This is the other text template offered in VS2010. The base EntityObject class will support a common PropertyChanged method and the EntityState method but you will still have a partial member for each of your primitive properties.

What should i choose?

It depends on your needs. If you use a WCF service or if you need your data to be exposed to other frameworks or languages , you should go for the POCO option. These objects does not rely on .net and could be easily consumed by any other language like php or java.

If you are using RIA services and have no plan in the future to expose your data, you can go with the EntityObject approach. In a silverlight context for example, the client proxy for your domain context class will be generated using the EF model no matter if you are using POCO or not.

This is the main difference over the two models, you should go with POCO if you need to expose data to other technologies or need a better portability for your objects. If you want to avoid some redundant code and add some common functionality to your objects , the EF model is an option.

Remember that there is a few differences in the text template itself so you can easily do the switch later in your development.

Wednesday 22 August 2012

Text template: Attribute writer

Here’s a function I wrote that can take an attribute as a parameter and return its string equivalence into a text template. This is useful if you need to generate data annotations attributes for your metadata class but will work anywhere you need to output an attribute instance.
private static string AttributeToString(Attribute obj)
        {
            Type attrType;
            StringBuilder sb_AttrParts;
            StringBuilder sb_Attributes = new StringBuilder();

            sb_AttrParts = new StringBuilder();
            attrType = obj.GetType();

            PropertyInfo[] props = attrType.GetProperties();

            sb_AttrParts.Append("[");
            sb_AttrParts.Append(attrType.Name);
            sb_AttrParts.Append("(");

            bool first = true;
            foreach (PropertyInfo pi in props)
            {
                try
                {
                    if (pi.Name == "TypeId")
                        continue;

                    object value = pi.GetValue(obj, null);

                    if (value == null)
                        continue;

                    if (!first)
                        sb_AttrParts.Append(",");
                    else
                        first = false;

                    sb_AttrParts.Append(pi.Name);
                    sb_AttrParts.Append("=");

                    if (value != null)
                    {
                        if (value.GetType() == typeof(string))
                            sb_AttrParts.Append("\"" + value.ToString() + "\"");
                        else if (value.GetType() == typeof(bool))
                        {
                            if ((bool)value)
                                sb_AttrParts.Append("true");
                            else
                                sb_AttrParts.Append("false");
                        }
                        else
                            sb_AttrParts.Append(value.ToString());
                    }
                }
                catch { continue; }
            }
            sb_AttrParts.Append(")");
            sb_AttrParts.Append("]");

            sb_Attributes.Append(sb_AttrParts);
            return sb_Attributes.ToString();
        }

Monday 20 August 2012

RIA: Get EntitySet DomainContext extension method

The default RIA class generates an EntitySet for each type in your ObjectContext.While doing some generics data operation in a generic control inheritance, it's difficult to know on which EntitySet of the DomainContext an action should be performed. In my case i only have one EntitySet for each Entity type so i created the following DomainContext extension.
    public static class DomainContextExtension
    {
        /// <summary>
        /// DavidB : This provides a generic access to an entitySet of a given type.
        /// </summary>
        /// <typeparam name="T">An entity type</typeparam>
        public static EntitySet<T> GetEntitySet<T>(this DomainContext source) where T : Entity
        {
            Type domainType = source.GetType();
            var properties = domainType.GetProperties();

            foreach (PropertyInfo pi in properties)
            {
                if (!pi.PropertyType.Name.Contains("EntitySet"))
                    continue;

                var tArgs = pi.PropertyType.GetGenericArguments();

                if (tArgs.Count() > 0 && tArgs.FirstOrDefault() == typeof(T))
                {
                    EntitySet<T> entitySet = (EntitySet<T>)pi.GetValue(source, null);

                    return entitySet;
                }

            }
            return null;
        }
    }

Tuesday 14 August 2012

RIA: Load ComplexObject with async CTP


Async ctp is great but is not integrated with RIA services yet. Usualy we write a loadOperation from the domain context and then perform some task when the completed event is raised.  With the async ctp you can write the code as you would usualy do in a synchronous context allowing you to write code in a logical order.  

One very useful class I found and currently use is one created by Kyle McClellan, explained on his blog: http://blogs.msdn.com/b/kylemc/archive/2010/11/02/using-the-visual-studio-async-ctp-with-ria-services.aspx

This extension static class is very simple to use and brings the async functionalities to load entities from your DomainContext. 

One feature it’s missing is the ability to load a non-persisted class that is not an entity. When you reference a complex type in a function, the RIA generated class for your client interface will inherit it to a ComplexObject. 

Using the same approach described above, I created a load wrapper extension method that will return the complex type from a query asynchronously.
 public static class DomainContextExtension
    {
        public static Task<T> LoadComplexObjectAsync<T>(this DomainContext source, InvokeOperation<T> task) where T : ComplexObject
        {
            TaskCompletionSource<T> taskCompletionSource = new TaskCompletionSource<T>();
       
            Action<InvokeOperation<T>> callback =
                cb =>
                {
                    if (cb.HasError && !cb.IsErrorHandled)
                    {
                        taskCompletionSource.TrySetException(cb.Error);
                        cb.MarkErrorAsHandled();
                    }
                    else if (cb.IsCanceled)
                    {
                        taskCompletionSource.TrySetCanceled();
                    }
                    else
                    {
                        taskCompletionSource.TrySetResult(cb.Value);
                    }
                };


            var op = ((InvokeOperation<T>)(source.InvokeOperation(task.OperationName, typeof(T), task.Parameters, true, callback, null)));


            return taskCompletionSource.Task;
        }
   }

Wednesday 1 August 2012

Load assembly from file and enforce strong name verification

Loading an external assembly in your application context may represent an important security hazard. An assembly loaded from  Assembly.LoadFrom will not check for a strong name.

During the development process , you probably don't want everyone to have your SN key pair and it's a lot easier to delay sign your assembly.

Here is a way to check your public key token with an expected byte array representing a known public key token.


        public static bool CheckToken(string assembly, byte[] expectedToken)
        {
            if (assembly == null)
                throw new ArgumentNullException("assembly");
            if (expectedToken == null)
                throw new ArgumentNullException("expectedToken");

            try
            {
                // Get the public key token of the given assembly
                Assembly asm = Assembly.LoadFrom(assembly);
                byte[] asmToken = asm.GetName().GetPublicKeyToken();

                // Compare it to the given token
                if (asmToken.Length != expectedToken.Length)
                    return false;

                for (int i = 0; i < asmToken.Length; i++)
                    if (asmToken[i] != expectedToken[i])
                        return false;

                return true;
            }
            catch (System.IO.FileNotFoundException)
            {
                // couldn't find the assembly
                return false;
            }
            catch (BadImageFormatException)
            {
                // the given file couldn't get through the loader
                return false;
            }
        }
This is fine but it will not allow you to check if you have a strong name signed, and you cant make sure you are not delay signed.

A solution would be to import external funcion from mscoree.dll that will make this check for you. This is a good approach to make sure you dont rely on the standard .net check that could be easily bypassed (http://msdn.microsoft.com/en-us/library/cc713694.aspx)

[DllImport("mscoree.dll", CharSet = CharSet.Unicode)]
static extern bool StrongNameSignatureVerificationEx(string wszFilePath, bool fForceVerification, ref bool pfWasVerification);

        public static bool CheckStrongName(string assembly)
        {
            // check the signature first
            bool notForced = false;
            bool verified = StrongNameSignatureVerificationEx(assembly, false, ref notForced);

            byte[] your_key = null;

     //Check different key for debug / release ..
            #if DEBUG
            your_key = new byte[] { 0x11, 0x11, 0x11, 0x38, 0x12, 0x11, 0x61, 0xF4 };
            #else
            your_key = new byte[] { 0x11, 0x11, 0x11, 0x38, 0x12, 0x11, 0x61, 0xF4 };
            #endif

            bool isSecureAsm = CheckToken(assembly, your_key);

            if (isSecureAsm  && verified && notForced)
                return true; //signed assembly
            else if (isSecureAsm && verified && !notForced)
                throw new InvalidOperationException("Delay signed assembly");
            else if (isSecureAsm && !verified)
                throw new InvalidOperationException("Assembly modified since signing");
            else
                throw new InvalidOperationException("Not a valid assembly"); 
        }
By setting the notForced parameter to false, you will check for a correct assembly no matter what has been set as a bypass.