0

通用接口使用Ninject 2.2,我有以下的失敗測試(簡體):如何檢索所有綁定使用Ninject

public interface IGenericView<T> 
{ 
} 

public interface IDefaultConvention 
{ 
} 

public class DefaultConvention : IDefaultConvention 
{ 
} 

public class DefaultConventionView : IGenericView<IDefaultConvention> 
{ 
} 

public class StringView : IGenericView<string> 
{ 
} 

[TestFixture] 
public class NinjectTests 
{ 
    private static IKernel _kernel; 

    [SetUp] 
    public void Setup() 
    { 
     _kernel = new StandardKernel(); 
    } 

    [Test] 
    public void CanResolveAllClassesClosingOpenGenericInterface() 
    { 
     // Arrange 
     _kernel.Bind<IDefaultConvention>().To<DefaultConvention>(); 
     _kernel.Scan(
      x => 
      { 
       x.FromCallingAssembly(); 
       x.BindWith(new GenericBindingGenerator(typeof(IGenericView<>))); 
      }); 

     // Act 
     object target1 = _kernel.Get<IGenericView<IDefaultConvention>>(); 
     object target2 = _kernel.Get<IGenericView<string>>(); 

     // Assert 
     Assert.IsAssignableFrom<DefaultConventionView>(target1); 
     Assert.IsAssignableFrom<StringView>(target2); 
     Assert.AreEqual(2, _kernel.GetAll(typeof(IGenericView<>)).Count()); // Always returns 0 
    } 
} 

前兩個斷言過,所以我知道該類型本身的限制正確,但我不能像我想要的那樣檢索開放式泛型界面的所有綁定。這是可能嗎?

回答

3

不,這是不可能的。 Ninject應該知道哪些類型可以作爲通用參數?假設你爲什麼認爲2是正確的值? IGenericView<int>爲什麼不能返回呢?此外,什麼應該是返回類型? IEnumerable<IGenericView<>>不是允許的運行時類型。 IEnumerable<IGenericView<object>>可能並不是人們所期望的。

GetAll爲請求類型的每個綁定返回一個實例,在這種情況下只有一個實例。在這種情況下,您必須定義一個通用非通用基接口,併爲每種類型進行註冊併爲此接口調用GetAll。

+0

感謝您的回答,聖雷莫 - 我理解您的觀點。它看起來並不完全正確,但我甚至嘗試過這種路由的唯一原因是因爲GetAll不適用於繼承的接口。 如果我定義'interface IGenericView :IView',那麼即使我指定class StringView:GenericView ,IView',我也不能調用GetAll ()。 這是我碰到的基本問題,我非常希望能夠抓住由前面的Scan方法調用創建的所有綁定。有沒有可能實現這一目標? – Genyus

+0

你必須爲所有類的IView定義一個綁定。既然你使用的是慣例,你可以輕鬆地做到這一點,例如使用RegexBindingGenerator或你自己的Generator。 –

+0

許多hanks爲您的援助,雷莫。最後,我決定採取非通用的方式,因爲這會給我帶來太多的麻煩,但是您的迴應肯定會指引我走向正確的方向,並讓我渡過這個直接的障礙。 – Genyus