2016-09-30 6 views
3

私は.NET 4.52から.NETコアにプロジェクトを移植しています。このプロジェクトでは、これまでDependency InjectionにStructure Mapを使用していましたが、構造マップでは依存関係注入を可能にするために具体的なタイプを設定する必要はありません。 .NET Coreに組み込まれた依存関係注入でこれを行う方法はありますか?.NETコアで設定なしでコンクリートクラスを自動的に解決しますか?

+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; 
     } 
    } 
} 
関連する問題