2011-01-29 5 views
21

オートファックはFunc<T>の工場を自動的に生成します。私はパラメータを渡すことさえできます。NinjectはFunc(自動生成された工場)をサポートしていますか?

public class MyClass 
{ 
    public MyClass(Func<A> a, Func<int, B> b) 
    { 
     var _a = a(); 
     var _b = b(1); 
    } 
} 

Ninjectでも同じことができますか?そうでない場合は、どのような回避策を適用できますか?

ありがとうございました。

更新

ちょうど、この記事を見つけた答えは何であるようだ。後で

How do I handle classes with static methods with Ninject?

答えて

29

NB Ninject 3.0と、これは完全にNinject.Extensions.Factoryパッケージを使用してサポートしている、Wikiを参照してください。 - https://github.com/ninject/ninject.extensions.factory/wiki


EDIT:NBありNinject 2.3での実装(完全にテストされたリリースではありませんが、is available from the CodeBetter server

Ninjectはこれをネイティブで現時点でサポートしていません。これを次のバージョンに追加する予定です。しかし、適切なバインディングを設定することで、サポートを簡単に追加できます。下にモジュールをロードしてお楽しみください。

public class FuncModule : NinjectModule 
{ 
    public override void Load() 
    { 
     this.Kernel.Bind(typeof(Func<>)).ToMethod(CreateFunc).When(VerifyFactoryFunction); 
    } 

    private static bool VerifyFactoryFunction(IRequest request) 
    { 
     var genericArguments = request.Service.GetGenericArguments(); 
     if (genericArguments.Count() != 1) 
     { 
      return false; 
     } 

     var instanceType = genericArguments.Single(); 
     return request.ParentContext.Kernel.CanResolve(new Request(genericArguments[0], null, new IParameter[0], null, false, true)) || 
       TypeIsSelfBindable(instanceType); 
    } 

    private static object CreateFunc(IContext ctx) 
    { 
     var functionFactoryType = typeof(FunctionFactory<>).MakeGenericType(ctx.GenericArguments); 
     var ctor = functionFactoryType.GetConstructors().Single(); 
     var functionFactory = ctor.Invoke(new object[] { ctx.Kernel }); 
     return functionFactoryType.GetMethod("Create").Invoke(functionFactory, new object[0]); 
    } 

    private static bool TypeIsSelfBindable(Type service) 
    { 
     return !service.IsInterface 
       && !service.IsAbstract 
       && !service.IsValueType 
       && service != typeof(string) 
       && !service.ContainsGenericParameters; 
    } 

    public class FunctionFactory<T> 
    { 
     private readonly IKernel kernel; 

     public FunctionFactory(IKernel kernel) 
     { 
      this.kernel = kernel; 
     } 

     public Func<T> Create() 
     { 
      return() => this.kernel.Get<T>(); 
     } 
    } 
} 
+0

ありがとうございます!次のバージョンを楽しみにしています。 –

+0

すべてのあなたの勤勉Remoをありがとう。 Func >で動作するようにコードを拡張することは可能ですか? – Anders

+0

そうです。 FunctionFactory.Createメソッドを変更し、IEnumerableをチェックし、代わりにGetAllを返します。 –

関連する問題