2013-01-03 24 views
0

我工作的一個項目,以實現DI(使用Ninject)到現有的WinForms應用程序,但我已經打了幾個問題,我在的WinForms與DI工作的知識是有限的,充其量,不過我已經在MVC項目中多次成功使用過它。Ninject ActivationException在WinForms應用程序

我在嘗試創建一個具有需要的存儲庫的接口中的構造形式,當這條消息:

Error activating IProductionRepository 
No matching bindings are available, and the type is not self-bindable. 
Activation path: 
    2) Injection of dependency IProductionRepository into parameter 
    productionRepository of constructor of type Main 
    1) Request for Main 

我已經在網上搜索,但大部分文章我已閱讀本錯誤要麼處理更復雜的設置,要麼與參數注入有關,我不確定這是否是問題。

我有一個形式,是發動那就是使用DI(在kernel.Get通話出現錯誤的形式:

Private Sub txt_Click(sender As System.Object, e As System.EventArgs) Handles txt.Click 

    Try 
     Dim kernel As Ninject.IKernel = 
      New Ninject.StandardKernel(New NinjectFactory()) 
     Dim form As Main = kernel.Get(Of Main)() 
     form.ConnectionString = App.pstrConnectString 
     form.ShowDialog(Me) 
    Catch ex As Exception 
     Support.ErrorHandler.ReportError(ex.Message, ex, True) 
    End Try 

End Sub 

我有我的NinjectFactory與正確的綁定(和其他一些註釋掉的嘗試):

public class NinjectFactory : NinjectModule 
{ 
    private IKernel _ninjectKernel; 

    public NinjectFactory() 
    { 
     _ninjectKernel = new StandardKernel(); 
    } 

    public override void Load() 
    { 
     //_ninjectKernel.Bind(typeof(IRepository<>)) 
     // .To(typeof(GenericRepository<>)); 
     //_ninjectKernel.Bind(typeof(IProductionRepository)) 
     // .To(typeof(ProductionRepository)); 
     _ninjectKernel.Bind<IProductionRepository>().To<ProductionRepository>(); 
    } 
} 

最後我有形式,我嘗試推出:

private IProductionRepository _productionRepository; 

public string ConnectionString 
{ 
    get 
    { 
     return _connectionString; 
    } 
    set 
    { 
     _connectionString = value; 
    } 

    [Inject] 
    public Main(IProductionRepository productionRepository) : this() 
    { 
     this._productionRepository = productionRepository;   
    } 

    public Main() 
    { 
     InitializeComponent(); 
    } 

這就是我用Ninject在MVC項目之前,我還沒有問題,但是顯然是有關於WinForms的不同的東西。

任何幫助將不勝感激。

回答

2

我建議使用Mark Seemann(@ mark-seemann)在其精彩圖書Dependency Injection in .NET中建議的依賴關係解析的單點,即Composition Root。你CompositionRoot可能是這樣的:

public class CompositionRoot 
{ 
    private static IKernel _ninjectKernel; 

    public static void Wire(INinjectModule module) 
    { 
     _ninjectKernel = new StandardKernel(module); 
    } 

    public static T Resolve<T>() 
    { 
     return _ninjectKernel.Get<T>(); 
    } 
} 

public class ApplicationModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind(typeof(IRepository<>)).To(typeof(GenericRepository<>)); 
    } 
} 

可以在Program

CompositionRoot.Wire(new ApplicationModule()); 

Application.EnableVisualStyles(); 
Application.SetCompatibleTextRenderingDefault(false); 

Application.Run(CompositionRoot.Resolve<Form1>()); 

它們連接現在你的按鈕處理程序看起來是這樣的:

private void button1_Click(object sender, EventArgs e) 
{ 
    MessageBox.Show(_productionRepository.ToString()); 
} 

注:,如果你想以不同的依賴性測試您的應用程序(可能是這種情況),然後您創建另一個具有不同佈線配置的模塊iguration。在測試中,你將有另外一種佈線邏輯與存根和嘲諷。 我也不喜歡在我的模型NInject屬性,如果你使用構造器注入 - 你可以擺脫他們。我的實體是簡單的POCO。

public interface IProductionRepository 
{ 
} 

public class ProductionRepository : IProductionRepository 
{ 
    public override string ToString() 
    { 
     return "Foo"; 
    } 
} 

馬克也使得與DI模式以及如何實現的WinForms很大的情況下,我真的建議他的書。

+0

非常感謝您回答我的兩個Ninject相關的問題!我有一種感覺,另一種感覺很快就會出現! – XN16

+0

有很多關於DI話題良好的和複雜的問題,隨便問任何的)乾杯 –

+0

的這裏是我的下一個問題,如果你想嘗試,再幫我出去!謝謝! http://stackoverflow.com/questions/14164443/ninject-dynamic-multiple-constructor-arguments – XN16