NB Ninject 3.0 and later has this fully supported using the Ninject.Extensions.Factory
package, see the wiki:- https://github.com/ninject/ninject.extensions.factory/wiki
EDIT: NB there is a Bind<T>().ToFactory()
implementation in Ninject 2.3 (which is not a fully tests supported release but is available from the CodeBetter server)
Ninject does not support this natively at the moment. We planned to add this to the next version. But support can be added easily by configuring the appropriate binding. Just load the module below and enjoy.
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>();
}
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…