2011-01-29 2 views
21

Autofac génère automatiquement des usines pour Func<T>; Je peux même passer des paramètres.Est-ce que Ninject supporte Func (usine générée automatiquement)?

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

Puis-je faire de même avec Ninject? Si non, quelle solution de contournement puis-je appliquer?

Merci.

Mise à jour:

Je viens de trouver ce poste, semble la réponse est non:

How do I handle classes with static methods with Ninject?

Répondre

29

NB Ninject 3.0 et a plus tard cette entièrement pris en charge en utilisant le package Ninject.Extensions.Factory, voir le wiki: - https://github.com/ninject/ninject.extensions.factory/wiki


EDIT: NB il y a un Bind<T>().ToFactory() implémentation dans Ninject 2.3 (qui n'est pas une version entièrement testée, mais is available from the CodeBetter server)

Ninject ne supporte pas ce natif pour le moment. Nous avions prévu d'ajouter ceci à la prochaine version. Mais le support peut être facilement ajouté en configurant la liaison appropriée. Il suffit de charger le module ci-dessous et profitez-en.

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

Merci pour le code! Va hâte pour la prochaine version. –

+0

Merci pour tout votre dur travail Remo. Est-il possible d'étendre le code pour travailler avec Func >? – Anders

+0

Bien sûr, c'est. Modifiez la méthode FunctionFactory.Create, recherchez IEnumerable et renvoyez GetAll à la place. –

Questions connexes