grumpydev / TinyIoC

An easy to use, hassle free, Inversion of Control Container for small projects, libraries and beginners alike.
MIT License
830 stars 235 forks source link

The type.gettypeconStructors method gets seven constructors in .Net Core #140

Open a764578566 opened 4 years ago

a764578566 commented 4 years ago

I use .net core 3.1 and .net 5 RC2

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using TinyIoC;

namespace ConsoleApp4
{
    class Program
    {
        static void Main(string[] args)
        {
            var personLazy = TinyIoCContainer.Current.Resolve<Lazy<Person>>();
            //var person = personLazy.Value;

            var candidateCtors = typeof(Lazy<Person>).GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                 .Where(x => !x.IsPrivate) // Includes internal constructors but not private constructors
                 .Where(x => !x.IsFamily) // Excludes protected constructors
                 .ToList();

            var ctors = candidateCtors.OrderByDescending(ctor => ctor.GetParameters().Count());

            foreach (var ctor in ctors)
            {
                Console.WriteLine(ctor.ToString());
            }
            Console.ReadKey();
        }
    }

    class Person
    {
        public Person()
        {
            Console.WriteLine("new Person");
        }
    }
}

image

but The type.gettypeconStructors method gets six constructors in Framework 4.5 image

Causes the Resolve lazy object to be initialized image

niemyjski commented 4 years ago

Would you mind submitting a fix and test for this via PR. Thanks for reporting this.

a764578566 commented 4 years ago

we want this Void. Ctor (System.Func '1[consoleapp5.person]) constructor ,Sort the constructor

        private IEnumerable<ConstructorInfo> GetTypeConstructors(Type type)
        {
            //#if NETFX_CORE
            //          return type.GetTypeInfo().DeclaredConstructors.OrderByDescending(ctor => ctor.GetParameters().Count());
            //#else
            var candidateCtors = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                .Where(x => !x.IsPrivate) // Includes internal constructors but not private constructors
                .Where(x => !x.IsFamily) // Excludes protected constructors
                .ToList();

            var attributeCtors = candidateCtors.Where(x => x.GetCustomAttributes(typeof(TinyIoCConstructorAttribute), false).Any())
                .ToList();

            if (attributeCtors.Any())
                candidateCtors = attributeCtors;

            return candidateCtors.OrderByDescending(ctor => ctor.GetParameters().Count()).ThenByDescending(ctor => ctor.ToString());
            //#endif
        }

I wonder if this is ok? image

niemyjski commented 4 years ago

I'm not sure without digging in, what happens if you try and do this with the Microsoft di? I'd think one would prefer the boolean parameter instead of the safety mode, but how would either of those get injected?