在.NET Core中自动解析没有配置的具体类?

时间:2016-09-30 11:40:23

标签: dependency-injection asp.net-core

我将项目从.NET 4.52移植到.NET Core。此项目以前使用Structuremap进行依赖项注入,而在structmap中,您不需要配置具体类型来启用依赖项注入。有没有办法用.NET Core中的内置依赖注入来做到这一点?

1 个答案:

答案 0 :(得分:1)

如果您尝试解析具体类型并从IoC容器中注入其依赖项,则以下扩展函数可能对您有用。这假设可以通过容器解决具体类型的所有依赖关系。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class ServiceProviderExtensions
    {
        public static TService AsSelf<TService>(this IServiceProvider serviceProvider)
        {
            return (TService)AsSelf(serviceProvider, typeof(TService));
        }
        public static object AsSelf(this IServiceProvider serviceProvider, Type serviceType)
        {
            var constructors = serviceType.GetConstructors(BindingFlags.Public | BindingFlags.Instance)
                .Select(o => o.GetParameters())
                .ToArray()
                .OrderByDescending(o => o.Length)
                .ToArray();

            if (!constructors.Any())
            {
                return null;
            }

            object[] arguments = ResolveParameters(serviceProvider, constructors);

            if (arguments == null)
            {
                return null;
            }

            return Activator.CreateInstance(serviceType, arguments);
        }

        private static object[] ResolveParameters(IServiceProvider resolver, ParameterInfo[][] constructors)
        {
            foreach (ParameterInfo[] constructor in constructors)
            {
                bool hasNull = false;
                object[] values = new object[constructor.Length];
                for (int i = 0; i < constructor.Length; i++)
                {
                    var value = resolver.GetService(constructor[i].ParameterType);
                    values[i] = value;
                    if (value == null)
                    {
                        hasNull = true;
                        break;
                    }
                }
                if (!hasNull)
                {
                    // found a constructor we can create.
                    return values;
                }
            }

            return null;
        }
    }
}