2013-03-07 6 views
8

sto usando una fabbrica per restituire un datasender:Ninject condizione vincolante in base al tipo di parametro

Bind<IDataSenderFactory>() 
    .ToFactory(); 

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

Ho due diverse implementazioni di datasender (WCF e remoti), che prendono diverse tipologie:

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

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

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

Sto cercando di utilizzare Ninject per associare questi tipi specifici di datasender in base al tipo di connessione passata dal parametro. Ho provato quanto segue senza successo:

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

Credo che questo sia perche '.Quando' fornisce solo una richiesta e avrei bisogno di un contesto pieno di essere in grado di recuperare il valore del parametro reale e controllare il suo tipo. Sono ad una perdita quanto a che cosa fare, altro che usare attacchi di nome, in realtà l'attuazione della fabbrica e mettendo la logica in là vale a dire

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)); 
} 

risposta

6

Dopo un po 'guardando fonte Ninject Ho trovato seguente:

  • a.Parameters.Single(b => b.Name == "connection") fornisce una variabile di tipo IParameter, non parametro reale.

  • IParameter ha il metodo object GetValue(IContext context, ITarget target) che richiede un parametro di contesto non nullo (la destinazione può essere nullo).

  • Non ho trovato alcun modo per ottenere IContext dalla richiesta (variabile a nel campione).

  • Context classe non ha costruttore senza parametri, quindi non è possibile creare nuovo contesto.

Per farlo funzionare è possibile creare implementazione IContext manichino come:

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; } 
} 

e poi usarlo

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

Sarebbe bello se qualcuno potesse inserire alcune informazioni su come ottenere Context dall'interno When() ...