Click here to Skip to main content
15,881,812 members
Articles / Web Development / HTML

Signum Framework Tutorials Part 2 – Southwind Logic

Rate me:
Please Sign up or sign in to vote.
4.45/5 (6 votes)
15 Nov 2012LGPL325 min read 31.3K   1K   22  
In this part, we will focus on writing business logic, LINQ queries and explain inheritance
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Resources;
using System.ComponentModel;
using System.Globalization;
using System.Text.RegularExpressions;
using Signum.Utilities;
using System.Reflection;
using Signum.Utilities.Reflection;
using Signum.Utilities.Properties;
using System.Linq.Expressions;
using Signum.Utilities.ExpressionTrees;


namespace Signum.Utilities
{
    [AttributeUsage(AttributeTargets.Class)]
    public class PluralDescriptionAttribute : Attribute
    {
        public string PluralDescription { get; private set; }

        public PluralDescriptionAttribute(string pluralDescription)
        {
            this.PluralDescription = pluralDescription;
        }
    }

    [AttributeUsage(AttributeTargets.Class)]
    public class GenderAttribute : Attribute
    {
        public Gender Gender { get; private set; }

        public GenderAttribute(Gender gender)
        {
            this.Gender = gender;
        }
    }

    [AttributeUsage(AttributeTargets.Assembly)]
    public class LocalizeDescriptionsAttribute : Attribute
    {

    }
    
    [AttributeUsage(AttributeTargets.All, Inherited = true)]
    public class ForceLocalization : Attribute
    {
    }  

    [AttributeUsage(AttributeTargets.All, Inherited = true)]
    public class AvoidLocalization : Attribute
    {
    }

    public static class DescriptionManager
    {
        public static string NiceToString(this Enum a)
        {
            return DescriptionManager.GetDescription(EnumFieldCache.Get(a)) ??
                a.ToString().NiceName();
        }

        public static Func<Type, string> CleanTypeName = t => t.Name; //To allow MyEntityDN
        public static Func<Type, Type> CleanType = t => t; //To allow Lite<T>

        public static string NiceName(this Type type)
        {
            type = CleanType(type);

            return DescriptionManager.GetDescription(type) ??
                CleanTypeName(type).SpacePascal();
        }

        public static string NiceName(this PropertyInfo pi)
        {
            return DescriptionManager.GetDescription(pi) ??
                (pi.IsDefaultName() ? pi.PropertyType.NiceName() : pi.Name.NiceName());
        }

        public static bool IsDefaultName(this PropertyInfo pi)
        {
            return pi.Name == CleanTypeName(CleanType(pi.PropertyType)); 
        }

        public static string NicePluralName(this Type type)
        {
            return DescriptionManager.GetPluralDescription(type) ??
                   NaturalLanguageTools.Pluralize(type.NiceName());
        }

        public static string GetGenderAwareResource(this ResourceManager resource, string resourceKey, Gender gender)
        {
            string compoundKey = resourceKey + 
                (gender == Gender.Masculine ? "_m" :
                 gender == Gender.Femenine ? "_f" : "_n");

            return resource.GetString(compoundKey) ?? resource.GetString(resourceKey);
        }

        public static string GetGenderAwareResource(this Type type, Expression<Func<string>> resource)
        {
            MemberExpression me = (MemberExpression)resource.Body;
            PropertyInfo pi = me.Member.DeclaringType.GetProperty("ResourceManager", BindingFlags.Static| BindingFlags.NonPublic | BindingFlags.Public);
            ResourceManager rm = (ResourceManager)pi.GetValue(null, null);
            return rm.GetGenderAwareResource(me.Member.Name, type.GetGender());
        }


        static string GetDescription(MemberInfo memberInfo)
        {
            Assembly assembly = (memberInfo.DeclaringType ?? (Type)memberInfo).Assembly;
            if (assembly.HasAttribute<LocalizeDescriptionsAttribute>())
            {
                string key = memberInfo.DeclaringType.TryCC(d => d.Name).Add(memberInfo.Name, "_");
                string result = assembly.GetDefaultResourceManager().GetString(key);
                if (result != null)
                    return result;
            }

            DescriptionAttribute desc = memberInfo.SingleAttribute<DescriptionAttribute>();
            if (desc != null)
            {
                return desc.Description;
            }

            return null;
        }

        static string GetPluralDescription(Type type)
        {
            Assembly assembly = type.Assembly;
            if (assembly.HasAttribute<LocalizeDescriptionsAttribute>())
            {
                string key = type.Name + "_Plural";
                string result = assembly.GetDefaultResourceManager().GetString(key);
                if (result != null)
                    return result;
            }

            PluralDescriptionAttribute desc = type.SingleAttribute<PluralDescriptionAttribute>();
            if (desc != null)
            {
                return desc.PluralDescription;
            }

            return null;
        }

        public static Gender GetGender(this Type type)
        {
            Assembly assembly = type.Assembly;
            if (assembly.HasAttribute<LocalizeDescriptionsAttribute>())
            {
                string key = type.Name + "_Gender";
                string gender = assembly.GetDefaultResourceManager().GetString(key);
                if (gender != null)
                    return ParseGender(gender);
            }

            var ga = type.SingleAttribute<GenderAttribute>();
            if (ga != null)
                return ga.Gender;

            return NaturalLanguageTools.GetGender(type.NiceName());
        }

        static Gender ParseGender(string str)
        {
            str = str.Trim().ToLower();
            if (str == "m") return Gender.Masculine;
            if (str == "f") return Gender.Femenine;
            if (str == "n") return Gender.Neuter;

            throw new FormatException("{0} is not a valid Gender. Use m, f or n");
        }

        public static ResourceManager GetDefaultResourceManager(this Assembly assembly)
        {
            string[] resourceFiles = assembly.GetManifestResourceNames();
            string name = resourceFiles.Single(a => a.Contains("Resources.resources"));
            return new ResourceManager(name.Replace(".resources", ""), assembly);
        }
    }
}

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 GNU Lesser General Public License (LGPLv3)


Written By
Software Developer (Senior) Signum Software
Spain Spain
I'm Computer Scientist, one of the founders of Signum Software, and the lead developer behind Signum Framework.

www.signumframework.com

I love programming in C#, Linq, Compilers, Algorithms, Functional Programming, Computer Graphics, Maths...

Comments and Discussions