Code Refactoring

Feb 13, 2011 at 9:00 PM

Hi,

Here i want to create discussion about suggestind of refactoring code of MUNQ ioc. 

THanks,

Dima

Feb 13, 2011 at 9:03 PM
Edited Feb 13, 2011 at 9:14 PM

So my first suggestion.

In 57760 changeset Matthew has:

 


    public class CreateInstanceDelegateFactory
       
    {
		public static System.Func<IDependencyResolver, TType> Create<TType, TImpl>()
			where TType : class
			where TImpl : class, TType
		{
			ConstructorInfo constructor = GetConstructorInfo(typeof(TImpl));
			ParameterInfo[] parameters = constructor.GetParameters();

			ParameterExpression container = Expression.Parameter(typeof(IDependencyResolver), "container");

			List arguments = new List();
			// create the arguments for the constructor
			foreach (var paramInfo in parameters)
			{

				var p = Expression.Call(container, "Resolve", new Type[] { paramInfo.ParameterType },
				  new Expression[] { });
				arguments.Add(p);
			}

			NewExpression exp = Expression.New(constructor, arguments);

			var finalExp = Expression.Lambda<System.Func<IDependencyResolver, TType>>(
								exp,
								new ParameterExpression[] { container }
							);
			return finalExp.Compile();
		}

		public static System.Func<IDependencyResolver, object> Create(Type tImpl)
		{
			ConstructorInfo constructor = GetConstructorInfo(tImpl);
			ParameterInfo[] parameters = constructor.GetParameters();

			ParameterExpression container = Expression.Parameter(typeof(IDependencyResolver), "container");

			List arguments = new List();
			// create the arguments for the constructor
			foreach (var paramInfo in parameters)
			{

				var p = Expression.Call(container, "Resolve", new Type[] { paramInfo.ParameterType },
				  new Expression[] { });
				arguments.Add(p);
			}

			NewExpression exp = Expression.New(constructor, arguments);

			return Expression.Lambda<System.Func<IDependencyResolver, object>>(
					exp,
					new ParameterExpression[] { container }
				).Compile();
		}

		private static ConstructorInfo GetConstructorInfo(Type implType)
        {
            var constructors = implType.GetConstructors();
            var constructor = constructors
                                .OrderBy(c => c.GetParameters().Length)
                                .LastOrDefault();
            if (constructor == null)
                throw new ArgumentException("TImpl does not have a public constructor.");

            return constructor;
        }

    }



I suggest to make this code smaller and no repeating:

    public class CreateInstanceDelegateFactory<TType> where TType : class
    {
        public static System.Func<IDependencyResolver, TType> Create<TImpl>() where TImpl : class, TType
        {
            return Create(typeof(TImpl));
        }

        private static System.Func<IDependencyResolver, TType> Create(Type TImpl)
        {
            ConstructorInfo constructor = GetConstructorInfo(TImpl);
            ParameterInfo[] parameters = constructor.GetParameters();

            ParameterExpression container = Expression.Parameter(typeof(IIocContainer), "container");

            List arguments = new List();
            // create the arguments for the constructor
            foreach (var paramInfo in parameters)
            {

                var p = Expression.Call(container, "Resolve", new Type[] { paramInfo.ParameterType },
                  new Expression[] { });
                arguments.Add(p);
            }

            NewExpression exp = Expression.New(constructor, arguments);

            return Expression.Lambda<System.Func<IDependencyResolver, TType>>(
                    exp,
                    new ParameterExpression[] { container }
                ).Compile();
        }

        private static ConstructorInfo GetConstructorInfo(Type TImpl)
        {
            var implType = TImpl;
            var constructors = implType.GetConstructors();
            var constructor = constructors
                                .OrderBy(c => c.GetParameters().Length)
                                .LastOrDefault();
            if (constructor == null)
                throw new ArgumentException("TImpl does not have a public constructor.");

            return constructor;
        }
    }


Coordinator
Feb 14, 2011 at 12:19 AM

Thank you for pointing out the code repetition.  I took it a step further once I realized I only needed the Func<IDependencyResolver, object>Create(Type tImpl) version.