2009-07-19 8 views
2

좋아 종속성 닌자의가, 여기에 내가 Ninject에 내가 커널에서 요청하고있어 유형에 따라 종속 관계를 구축하는 방식을 변경하려는 당신을 위해 하나 ...Ninject에 : 종속성 체인을 기반으로 노하우 설정 바인딩

입니다. 내 코드를 필요로

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

특정 클래스 : 나는 Ninject에이 매개 변수가없는 생성자를 사용하려면, 바인딩 "기본"을 위해

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

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

:

나는 다음과 같은 생성자와 DbConnectionFactory 클래스가 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) 
        { 
        } 
    } 
    

    와 제공자는 같을 것이다

    공장에도 DatabaseGateway에 반환해야 할 경우 16,
    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); 
         } 
    } 
    

당신은 결정에 추가 속성을 추가하려면이 모델을 확장 할 수 있습니다.

불편하지만 관련 레이어 수를 고려할 때 가장 좋을 수 있습니다.

1

article도 도움이 될 수 있습니다. Jeff가 말했듯이 With.Parameters.ConstructorArgument()를 사용하려고합니다. ConstructorArgument 체인을 계속하거나 사전을 사용하여 여러 인수를 전달할 수 있습니다. 희망이 도움이!