private object GetService(ServiceMetadata serviceMetadata)
        {
            for (int i = 0; i < serviceMetadata.ArgumentsLength; i++)
            {
                serviceMetadata.ArgumentArray[i] = this.GetService(serviceMetadata.ArgumentMetadataArray[i]);
            }

            return(serviceMetadata.NewObj(serviceMetadata.ArgumentArray));
        }
        public void AddService <TService, TImpl>() where TService : class where TImpl : class
        {
            Type            serviceType     = typeof(TService);
            ServiceMetadata serviceMetadata = new ServiceMetadata();

            serviceMetadata.ImplType              = typeof(TImpl);
            serviceMetadata.Constructor           = serviceMetadata.ImplType.GetConstructors()[0];
            serviceMetadata.ParameterTypes        = serviceMetadata.Constructor.GetParameters().Select(p => p.ParameterType).ToArray();
            serviceMetadata.ArgumentsLength       = serviceMetadata.ParameterTypes.Length;
            serviceMetadata.ArgumentArray         = new object[serviceMetadata.ArgumentsLength];
            serviceMetadata.ArgumentMetadataArray = new ServiceMetadata[serviceMetadata.ArgumentsLength];
            serviceMetadata.NewObj = this.CreateDelegate(serviceMetadata);
            this.serviceTypeToMetadata.Add(serviceType, serviceMetadata);
        }
        public override NewObjDelegate CreateDelegate(ServiceMetadata serviceMetadata)
        {
            var parametersExpr          = Expression.Parameter(typeof(object[]));
            var constructorArgumentList = new List <Expression>();

            for (int i = 0; i < serviceMetadata.ParameterTypes.Length; i++)
            {
                var indexExpr     = Expression.Constant(i);
                var arrayItemExpr = Expression.ArrayIndex(parametersExpr, indexExpr);
                var castExpr      = Expression.Convert(arrayItemExpr, serviceMetadata.ParameterTypes[i]);
                constructorArgumentList.Add(castExpr);
            }

            var newExpr     = Expression.New(serviceMetadata.Constructor, constructorArgumentList.ToArray());
            var lambda      = Expression.Lambda <NewObjDelegate>(newExpr, parametersExpr);
            var newDelegate = lambda.Compile();

            return(newDelegate);
        }
        public override NewObjDelegate CreateDelegate(ServiceMetadata serviceMetadata)
        {
            DynamicMethod dynamicMethod = new DynamicMethod(
                "NewInstance",
                typeof(object),
                new Type[] { typeof(object[]) });
            var il = dynamicMethod.GetILGenerator();

            for (int i = 0; i < serviceMetadata.ParameterTypes.Length; i++)
            {
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldc_I4, i);
                il.Emit(OpCodes.Ldelem_Ref);
                il.Emit(OpCodes.Castclass, serviceMetadata.ParameterTypes[i]);
            }

            il.Emit(OpCodes.Newobj, serviceMetadata.Constructor);
            il.Emit(OpCodes.Ret);
            var newObj = (NewObjDelegate)dynamicMethod.CreateDelegate(typeof(NewObjDelegate));

            return(newObj);
        }
        public object GetService(Type serviceType)
        {
            ServiceMetadata serviceMetadata = this.serviceTypeToMetadata[serviceType];

            return(this.GetService(serviceMetadata));
        }
 public abstract NewObjDelegate CreateDelegate(ServiceMetadata serviceMetadata);