2013-03-07 45 views
8

我使用工廠來返回一個datasender:Ninject條件基於參數類型的結合

Bind<IDataSenderFactory>() 
    .ToFactory(); 

public interface IDataSenderFactory 
{ 
    IDataSender CreateDataSender(Connection connection); 
} 

我有datasender的兩種不同的實現(WCF和遠程),其採取不同的類型:

public abstract class Connection 
{ 
    public string ServerName { get; set; } 
} 

public class WcfConnection : Connection 
{ 
    // specificProperties etc. 
} 

public class RemotingConnection : Connection 
{ 
    // specificProperties etc. 
} 

我想使用Ninject綁定這些特定類型的數據集根據從參數傳遞的連接類型。我曾嘗試以下失敗:

Bind<IDataSender>() 
    .To<RemotingDataSender>() 
    .When(a => a.Parameters.Single(b => b.Name == "connection") as RemotingConnection != null) 

我相信這是因爲「當」只是提供了一個請求,我就需要完整的上下文能夠檢索的實際參數值,並檢查它的類型。我手足無措,不知道該做什麼,比使用命名綁定,實際執行的工廠,把邏輯在裏面,即

public IDataSender CreateDataSender(Connection connection) 
{ 
    if (connection.GetType() == typeof(WcfConnection)) 
    { 
     return resolutionRoot.Get<IDataSender>("wcfdatasender", new ConstructorArgument("connection", connection)); 
    } 

    return resolutionRoot.Get<IDataSender>("remotingdatasender", new ConstructorArgument("connection", connection)); 
} 

回答

6

經過一番尋找到Ninject源,我發現下面的其他:

  • a.Parameters.Single(b => b.Name == "connection")給你變量的類型IParameter,而不是真正的參數。

  • IParameter有方法object GetValue(IContext context, ITarget target),它要求非空上下文參數(目標可以爲空)。

  • 我還沒有找到任何方法從請求中獲取IContext(樣本中的變量a)。

  • Context類沒有無參數構造函數,所以我們不能創建新的上下文。

爲了使它工作,你可以創建虛擬IContext實現,如:

public class DummyContext : IContext 
{ 
    public IKernel Kernel { get; private set; } 
    public IRequest Request { get; private set; } 
    public IBinding Binding { get; private set; } 
    public IPlan Plan { get; set; } 
    public ICollection<IParameter> Parameters { get; private set; } 
    public Type[] GenericArguments { get; private set; } 
    public bool HasInferredGenericArguments { get; private set; } 
    public IProvider GetProvider() { return null; } 
    public object GetScope() { return null; } 
    public object Resolve() { return null; } 
} 

,比使用它

kernel.Bind<IDataSender>() 
     .To<RemotingDataSender>() 
     .When(a => a.Parameters 
        .Single(b => b.Name == "connection") 
        .GetValue(new DummyContext(), a.Target) 
       as RemotingConnection != null); 

這將是很好,如果有人可以張貼有關獲取上下文的一些信息從內部When() ...