Ninject.Extensions.Factory with non-generic type parameter

本文关键字:type parameter non-generic with Extensions Factory Ninject | 更新日期: 2023-09-27 18:35:03

我知道我可以用ToFactory方法绑定以下泛型接口。

public interface IFoo {}
public interface IFooFactory {
  TFoo Create<TFoo>() where TFoo : IFoo;
}
...
kernel.Bind<IFooFactory>().ToFactory();

此代码按预期工作。但是,如果我想使用非通用变体,我会得到一个 Ninject 激活异常,因为它搜索IFoo的绑定,因此工厂扩展似乎无法识别Type参数。

public interface IFooFactoryWithType {
  IFoo Create(Type concreteType);
}
...
kernel.Bind<IFooFactoryWithType>().ToFactory();

我做错了什么,还是不支持这种方式?在我当前的情况下,我无法使用通用版本,因为该类型来自运行时参数。当然,我可以与MakeGenericMethod和朋友一起使用一些反射技巧,但我想避免这种情况。

Ninject.Extensions.Factory with non-generic type parameter

不是开箱即用的。但是,您可以通过执行以下操作将IInstanceProvider与自定义实现交换:

kernel.Bind<IFooFactory>()
    .ToFactory(() => new MyCustomInstanceProvider());

另请参阅维基以获取更多信息。

此外,Ninject工厂创建基于枚举的T可能会对你感兴趣。

您的IInstanceProvider实现可能看起来像这样(我还没有测试它是否实际编译,抱歉(:

internal class TypeDefinedByArgumentInstanceProvider : StandardInstanceProvider
{
    protected override Type GetType(MethodInfo methodInfo, object[] arguments)
    {
        return (Type)arguments.Single();
    }
}
kernel.Bind<IFooFactory>()
    .ToFactory(() => new TypeDefinedByArgumentInstanceProvider());

我不确定我是否正确理解了您的问题。不是必须将 IFoo 绑定到具体类型吗?

     kernel = new StandardKernel();
     kernel.Bind(typeof(IFoo)).To<Class2>();
     kernel.Bind<IFooFactoryWithType>().ToFactory();
     var createdInstance = kernel.Get<IFooFactoryWithType>().Create(typeof(IFoo));