2011-01-29 11 views
21

Autofac genera automáticamente fábricas para Func<T>; Incluso puedo pasar parámetros.¿Ninject es compatible con Func (fábrica generada automáticamente)?

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

¿Puedo hacer lo mismo con Ninject? Si no, ¿qué solución puedo aplicar?

Gracias.

actualización:

acaba de encontrar este post, parece que la respuesta es no:

How do I handle classes with static methods with Ninject?

Respuesta

29

NB Ninject 3.0 y posterior tiene esta totalmente compatible con el paquete Ninject.Extensions.Factory, ver la wiki: - https://github.com/ninject/ninject.extensions.factory/wiki


EDITAR: NB hay un Bind<T>().ToFactory() implementación en Ninject 2.3 (que no es una versión completamente compatible con pruebas pero is available from the CodeBetter server)

Ninject no admite esto de forma nativa en este momento. Planeamos agregar esto a la próxima versión. Pero el soporte se puede agregar fácilmente configurando el enlace apropiado. Solo carga el módulo a continuación y disfruta.

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

¡Gracias por el código! Esperando la próxima versión. –

+0

Gracias por todo su arduo trabajo Remo. ¿Es posible extender el código para que funcione con Func >? – Anders

+0

Claro que sí. Cambia el método FunctionFactory.Create, busca IEnumerable y devuelve GetAll en su lugar. –

Cuestiones relacionadas