引数名に依存せずに、コンストラクター パラメーターを使用してインスタンスを作成する ninject ファクトリを使用するにはどうすればよいですか。
問題は、ToConstructor()
-Method が機能しないことです。これは、一般的な定義にバインドしているためです。
次の例は、対応するコンストラクター引数名でファクトリ メソッドを使用すると機能しますが、名前に依存するのは好きではありません。
次の解決策は非常に脆弱であり、誰かが間違った名前を選択したり、派生クラスの ctor-argument の名前を変更したりすると機能しなくなるためです。
解決策はありますか?
コード例は次のとおりです。
[TestFixture]
public class NinjectFactoryBindingsTest
{
[Test]
public void ConstructorSelectionWithArguments()
{
NinjectSettings ninjectSettings = new NinjectSettings();
ninjectSettings.LoadExtensions = false;
using (var kernel = new StandardKernel(ninjectSettings, new FuncModule()))
{
// IDependencyA will be passed to the factory, therefore it is not bounded
//kernel.Bind<IDependencyA>().To<DependencyA>();
kernel.Bind<IDependencyB>().To<DependencyB>();
kernel.Bind(typeof(IGenericBaseClass<>)).To(typeof(GenericDerivedClass<>));
kernel.Bind<IGenericClassFactory>().ToFactory();
IGenericClassFactory factory = kernel.Get<IGenericClassFactory>();
DependencyA dependencyA = new DependencyA();
IGenericBaseClass<GenericImpl> shouldWorkInstance = factory.Create<GenericImpl>(dependencyA);
Assert.NotNull(shouldWorkInstance);
}
}
}
public interface IGenericClassFactory
{
IGenericBaseClass<TGeneric> Create<TGeneric>(IDependencyA someName) where TGeneric : IGeneric;
// This works, but relies on ctor-param-names!!!
// IGenericBaseClass<TGeneric> Create<TGeneric>(IDependencyA otherNameThanInBaseClass) where TGeneric : IGeneric;
}
public class DependencyA : IDependencyA
{
}
public class DependencyB : IDependencyB
{
}
public class GenericDerivedClass<TGeneric> : GenericBaseClass<TGeneric> where TGeneric : IGeneric
{
public GenericDerivedClass(IDependencyA otherNameThanInBaseClass, IDependencyB dependencyB)
: base(otherNameThanInBaseClass, dependencyB)
{
}
}
public abstract class GenericBaseClass<TGeneric> : IGenericBaseClass<TGeneric> where TGeneric : IGeneric
{
protected GenericBaseClass(IDependencyA dependencyA, IDependencyB dependencyB)
{
}
}
public interface IGenericBaseClass<TGeneric> where TGeneric : IGeneric
{
}
public interface IDependencyB
{
}
public interface IDependencyA
{
}
public class GenericImpl : IGeneric
{
}
public interface IGeneric
{
}