私のコードでは、これと同様の状況があり、次のように、2 つの祖先抽象クラスから派生したクラスがあります。
BaseAbstractClassExample <|-- AbstractClassExample <|-- ConcreteClassExample
フレームワークで定義された抽象クラスを拡張するためにこれを行いました。私の状況により適したデザイン パターンが他にもあることは承知していますが、この規約に基づくバインディングが機能しない理由が気になります。
using Ninject.Extensions.Conventions;
public abstract class BaseAbstractClassExample
{
public abstract int Number { get; set; }
}
public abstract class AbstractClassExample : BaseAbstractClassExample
{
public abstract bool Flag { get; set; }
}
public class ConcreteClassExample : AbstractClassExample
{
public override int Number { get; set; }
public override bool Flag { get; set; }
}
[TestMethod]
public void Concrete_classes_are_bound_to_grandfathers()
{
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses().InheritedFrom<BaseAbstractClassExample>()
.BindBase());
AssertCanResolveBindingToType<ConcreteClassExample, ConcreteClassExample>(); // pass
AssertCanResolveBindingToType<AbstractClassExample, ConcreteClassExample>(); // pass
AssertCanResolveBindingToType<BaseAbstractClassExample, ConcreteClassExample>(); // fail
}
これは、バインディングをテストするために作成した assert メソッドです。これは、私の質問に接しています。
private static void AssertCanResolveBindingToType<TRequestedType, TExpectedType>(params IParameter[] constructorParameters)
{
if (!typeof(TRequestedType).IsAssignableFrom(typeof(TExpectedType)))
Assert.Fail("{0} is not assignable from {1}, this binding wouldn't work anyway", typeof(TRequestedType), typeof(TExpectedType));
IEnumerable<TRequestedType> result = kernel.GetAll<TRequestedType>(constructorParameters);
var requestedTypes = result as TRequestedType[] ?? result.ToArray();
Assert.IsTrue(requestedTypes.Any(), "There are no bindings for {0} at all", typeof (TRequestedType));
Assert.IsTrue(requestedTypes.OfType<TExpectedType>().Any(),
"There are no bindings for {0} of the expected type {1}, bound types are: {2}",
typeof (TRequestedType), typeof (TExpectedType),
string.Join(", ", requestedTypes.Select(x => x.GetType().ToString()).Distinct()));
}
上記の単体テストを試すと、「BaseAbstractClassExample のバインディングはまったくありません」というカスタム メッセージでアサートされます。これは、 へのバインディングがAbstractClassExample
期待どおりに機能していることを示していますがBaseAbstractClassExample
、
編集:BindAllBaseClasses()
この機能を提供するメソッドを作成しました。プル リクエストを送信して承認されたので、この機能はNinject 拡張機能の規約 ライブラリで利用できるようになりました。