2009-07-19 57 views
2

好依賴忍者的,這裏有一個你...Ninject:基於依賴鏈HOWTO設置綁定

我想改變Ninject建立基於我從內核請求的類型依賴的方式。

我有以下構造一個DbConnectionFactory類:

public DbConnectionFactory() 
     : this(MyDatabase.ConnectionString) 
    { 
    } 

    public DbConnectionFactory(string connectionString) 
     : this(DbProviderFactories.GetFactory("System.Data.SqlClient"), connectionString) 
    { 
    } 

爲「默認」的結合,我想Ninject使用參數的構造函數:

 this.Bind<IDbConnectionFactory>().To<DbConnectionFactory>(); 

某些類別在我的代碼需要Ninject提供connectionString參數。我試圖設置綁定像這樣:

 this.Bind<IDbConnectionFactory>().To<DbConnectionFactory>().Only(
      When.Context.InstanceOf(typeof(IRepository))).WithArgument(
      "connectionString", MyOtherDatabase.ConnectionString); 

但是,我只能得到Ninject使用默認的構造函數。

我必須錯過明顯的東西!

回答

3

聽起來好像這裏有太多的圖層。爲什麼你需要一個DatabaseGateway?爲什麼不使用ADO.NET提供程序工廠創建連接(您也可以通過Ninject連接它們)來直接管理連接?或者更好,與存儲庫模式使用像NHibernate的東西,並用它來映射對象?

無論如何,總是使用更長的構造函數,並根據情況交替傳入MyDatabase.ConnectionString或MyOtherDatabase.ConnectionString?你可以使用一個供應商描述herehere,但我會盡量避免他們,除非絕對必要:

  1. 定義兩個新的屬性

    public class DefaultDatabaseAttribute : Attribute {} 
    public class OtherDatabaseAttribute : Attribute {} 
    
  2. 裝飾與構造適當的屬性DatabaseGateway參數

    public class OneRepository : IRepository 
    { 
        public OneRepository([DefaultDatabase]DatabaseGateway factory) 
        { 
        } 
    } 
    
    public class TwoRepository : IRepository 
    { 
        public TwoRepository([OtherDatabase]DatabaseGateway factory) 
        { 
        } 
    } 
    

    和您的提供者看起來像:

    public class DatabaseGatewayProvider : SimpleProvider<DatabaseGateway> 
    { 
         protected override DatabaseGateway CreateInstance(Ninject.Core.Activation.IContext context) 
         { 
          IDbConnectionFactory factory; 
          if (context.Member.IsDefined(typeof(DefaultDatabaseAttribute), false)) 
          { 
           factory = context.Kernel.get<IDbConnectionFactory>(With.Parameters.ConstructorArgument("connectionString", MyDatabase.ConnectionString))); 
          } 
          else if (context.Member.IsDefined(typeof(OtherDatabaseAttribute), false)) 
          { 
           factory = context.Kernel.get<IDbConnectionFactory>(With.Parameters.ConstructorArgument("connectionString", MyOtherDatabase.ConnectionString))); 
          } 
    
          return new DatabaseGateway(factory); 
         } 
    } 
    

可以擴大這種模式添加到決定附加屬性如果工廠甚至需要在DatabaseGateway歸還。

這是尷尬的,但可能是最好的,你可以做給定的層數涉及。

1

article也可以幫助你。像傑夫說的,你會想使用With.Parameters.ConstructorArgument()。您可以通過繼續鏈接ConstructorArgument或使用Dictionary來傳入多個參數。希望這可以幫助!