Does Ninject support Func (auto generated factory)?
Autofac automatically generates factories for Func<T>
; I can even pass parameters.
public class MyClass
{
public MyClass(Func<A> a, Func<int, B> b)
{
var _a = a();开发者_如何学运维
var _b = b(1);
}
}
Can I do the same with Ninject? If not, what workaround can I apply?
Thanks.
Update:
Just found this post, seems the answer is no:
How do I handle classes with static methods with Ninject?
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>();
}
}
}
精彩评论