Click here to Skip to main content
15,892,746 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.5K   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 Signum.Entities;
using Signum.Services;
using Signum.Utilities;
using Signum.Entities.DynamicQuery;
using Signum.Entities.Reflection;
using System.Reflection;
using System.ServiceModel;
using System.Windows;
using System.ServiceModel.Security;

namespace Signum.Windows
{
    public static class Server
    {
        static Func<IBaseServer> getServer;
        
        static IBaseServer current;

        public static event Action Connecting;

        static Server()
        {
            Connecting += () => ServerTypes = current.ServerTypes();
        }

        public static void SetNewServerCallback(Func<IBaseServer> server)
        {
            getServer = server;
        }

        public static void Connect()
        {
            if (!Connected)
            {
                current = getServer();

                if (current == null)
                    throw new InvalidOperationException(Properties.Resources.AConnectionWithTheServerIsNecessaryToContinue);

                if (Connecting != null)
                    Connecting();                     
            }
        }

        public static bool Connected
        {
            get
            {
                return (current is ICommunicationObject) && ((ICommunicationObject)current).State != CommunicationState.Faulted;
            }
        }
       
        public static void Execute<S>(Action<S> action)
            where S : class
        {
        retry:
            Connect();

            S server = current as S;
            if (server == null)
                throw new InvalidOperationException("Server {0} does not implement {1}".Formato(server.GetType(), typeof(S)));
            
            try
            {
                action(server);
            }
            catch (MessageSecurityException e)
            {
                HandleSessionException(e);
                current = null;
                goto retry;
            }
        }

        public static R Return<S, R>(Func<S, R> function)
          where S : class
        {
        retry:
            Connect();

            S server = current as S;
            if (server == null)
                throw new InvalidOperationException("Server {0} does not implement {1}".Formato(current.GetType(), typeof(S)));

            try
            {
                return function(server);
            }
            catch (MessageSecurityException e)
            {
                HandleSessionException(e);
                current = null;
                goto retry;
            }
        }

        static void HandleSessionException(MessageSecurityException e)
        {
            MessageBox.Show(Properties.Resources.SessionExpired, Properties.Resources.SessionExpired, MessageBoxButton.OK, MessageBoxImage.Hand);
        }

        public static bool Implements<T>()
        {
            Connect();
            return current is T;
        }

        public static T Save<T>(this T entidad) where T : IdentifiableEntity
        {
            return (T)Return((IBaseServer s)=>s.Save(entidad));
        }

        public static IdentifiableEntity Save(IdentifiableEntity entidad)
        {
            return Return((IBaseServer s)=>s.Save(entidad)); 
        }

        public static T Retrieve<T>(int id) where T : IdentifiableEntity
        {
            return (T)Return((IBaseServer s)=>s.Retrieve(typeof(T), id)); 
        }

        public static IdentifiableEntity Retrieve(Type type, int id)
        {
            return Return((IBaseServer s)=>s.Retrieve(type, id)); 
        }

        public static IdentifiableEntity Retrieve(Lite lite)
        {
            if (lite.UntypedEntityOrNull == null)
            {
                lite.SetEntity(Return((IBaseServer s)=>s.Retrieve(lite.RuntimeType, lite.Id))); 
            }
            return lite.UntypedEntityOrNull;
        }

        public static T Retrieve<T>(this Lite<T> lite) where T : class, IIdentifiable
        {
            if (lite.EntityOrNull == null)
            {
                lite.SetEntity((IdentifiableEntity)(IIdentifiable)Return((IBaseServer s)=>s.Retrieve(lite.RuntimeType, lite.Id))); 
            }
            return lite.EntityOrNull;
        }

        public static IdentifiableEntity RetrieveAndForget(Lite lite)
        {
            return Return((IBaseServer s)=>s.Retrieve(lite.RuntimeType, lite.Id)); 
        }

        public static T RetrieveAndForget<T>(this Lite<T> lite) where T : class, IIdentifiable
        {
            return (T)(IIdentifiable)Return((IBaseServer s)=>s.Retrieve(lite.RuntimeType, lite.Id)); 
        }

        public static List<T> RetrieveAll<T>() where T : IdentifiableEntity
        {
            return Return((IBaseServer s)=>s.RetrieveAll(typeof(T)).Cast<T>().ToList<T>()); 
        }

        public static List<IdentifiableEntity> RetrieveAll(Type type)
        {
            return Return((IBaseServer s)=>s.RetrieveAll(type)); 
        }

        public static List<Lite> RetrieveAllLite(Type liteType, Implementations implementations)
        {
            return Return((IBaseServer s)=>s.RetrieveAllLite(liteType, implementations)); 
        }

        public static List<Lite<T>> RetrieveAllLite<T>(Implementations implementations) where T : class, IIdentifiable
        {
            return Return((IBaseServer s)=>s.RetrieveAllLite(typeof(T), implementations).Cast<Lite<T>>().ToList()); 
        }


        public static List<Lite> FindLiteLike(Type liteType, Implementations implementations, string subString, int count)
        {
            return Return((IBaseServer s)=>s.FindLiteLike(liteType, implementations, subString, count)); 
        }

        public static List<T> SaveList<T>(List<T> list)
            where T: IdentifiableEntity
        {
            return Return((IBaseServer s)=>s.SaveList(list.Cast<IdentifiableEntity>().ToList()).Cast<T>().ToList()); 
        }

        static Dictionary<PropertyRoute, Implementations> implementations = new Dictionary<PropertyRoute, Implementations>(); 

        public static Implementations FindImplementations(PropertyRoute propertyRoute)
        {
            if (Server.ServerTypes.ContainsKey(propertyRoute.RootType))
                return implementations.GetOrCreate(propertyRoute, () => Server.Return((IBaseServer s) => s.FindImplementations(propertyRoute)));

            return null;
        }

        public static object Convert(object obj, Type type)
        {
            if (obj == null) return null;

            Type objType = obj.GetType();

            if (type.IsAssignableFrom(objType))
                return obj;

            if (objType.IsLite() && type.IsAssignableFrom(((Lite)obj).RuntimeType))
            {
                Lite lite = (Lite)obj;
                return lite.UntypedEntityOrNull ?? RetrieveAndForget(lite);
            }
            
            if (type.IsLite())
            {
                Type liteType = Reflector.ExtractLite(type); 
                
                if(objType.IsLite())
                {
                    Lite lite = (Lite)obj;
                    if (liteType.IsAssignableFrom(lite.RuntimeType))
                    {
                        if (lite.UntypedEntityOrNull != null)
                            return Lite.Create(liteType, lite.UntypedEntityOrNull);
                        else
                            return Lite.Create(liteType, lite.Id, lite.RuntimeType, lite.ToStr); 
                    }
                }

                else if(liteType.IsAssignableFrom(objType))
                {
                    return Lite.Create(liteType, (IdentifiableEntity)obj);
                }
            }

            throw new InvalidCastException("Impossible to convert objet {0} from type {1} to type {2}".Formato(obj, objType, type));
        }

        public static bool CanConvert(object obj, Type type)
        {
            if (obj == null) 
                return true;

            Type objType = obj.GetType();

            if (objType == type)
                return true;

            if (objType.IsLite() && ((Lite)obj).RuntimeType == type)
            {
                return true;
            }

            Type liteType;
            if (type.IsLite() && (liteType = Reflector.ExtractLite(type)).IsAssignableFrom(objType))
            {
                return true;
            }

            return false;
        }

        public static Dictionary<Type, TypeDN> ServerTypes { get; private set; }

        public static Type TryGetType(string typeName)
        {
            return ServerTypes.Keys.Where(t => t.Name == typeName).SingleOrDefault();
        }

        public static Type GetType(string typeName)
        {
            return ServerTypes.Keys.Where(t => t.Name == typeName).Single("Type {0} not found in the Server".Formato(typeName));
        }

        public static string GetCleanName(Type type)
        {
            return ServerTypes[type].CleanName;
        }

        public static Lite ParseLite(Type liteType, string liteKey)
        {
            return Lite.ParseLite(liteType, liteKey, TryGetType);
        }

        public static string TryParseLite(Type liteType, string liteKey, out Lite result)
        {
            return Lite.TryParseLite(liteType, liteKey, TryGetType, out result);
        }

        //public static void Execute(Action<global::Signum.Services.ILoginServer> action)
        //{
        //    throw new NotImplementedException();
        //}
    }
}

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