2016-09-30 50 views
3

我將一個項目從.NET 4.52移植到.NET Core。此項目以前使用Structuremap進行依賴注入,而在結構圖中,您不需要配置具體類型以啓用依賴注入。有什麼辦法可以用.NET Core內置的依賴注入來做到這一點嗎?自動解析.NET Core中沒有配置的具體類?

+1

如果需要,您仍然可以使用結構圖。 http://andrewlock.net/getting-started-with-structuremap-in-asp-net-core/ – mbudnik

+1

是的,但我想盡可能原生,這似乎是他們應該添加或做的事情你肯定知道這是不可能的? –

+0

堅持核心DI庫[可能不是個好主意](https://stackoverflow.com/a/30682214/264697)。 – Steven

回答

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; 
     } 
    } 
}