2012-02-16 17 views
6

Este es mi problema: Quiero pasarle uno de los valores al constructor cada vez que solicito una instancia del kernel. Escribí algunos códigos a continuación para ilustrar el problema. La prueba no está fallando, así que supongo que esto funciona, pero se ve bastante feo. ¿Hay alguna forma mejor y más limpia de lograr esto con Ninject? ¿O debería reconsiderar mi diseño? Todas las sugerencias son apreciadas.Ninject, pasando el argumento del constructor al kernel

[TestFixture] 
public class Sandbox 
{ 
    [Test] 
    public void Run_Forrest_Run() 
    { 
     using (var kernel = new StandardKernel(new Module())) 
     { 
      var connection = new Connection(Guid.NewGuid().ToString()); 
      var downloader = kernel.Get<IDownloader>(new IParameter[] { new Parameter("connection", connection, false) }); 

      Assert.That(downloader.Connection.Info, Is.EqualTo(connection.Info)); 
     } 
    } 

    public class Downloader : IDownloader 
    { 
     public Downloader(Connection connection, ILogger logger) 
     { 
      Connection = connection; 
      Logger = logger; 
     } 

     public Connection Connection { get; private set; } 

     public void Download() 
     { 
      Logger.Log("Downloading..."); 
     } 

     public ILogger Logger { get; private set; } 
    } 

    public interface IDownloader 
    { 
     Connection Connection { get; } 
     void Download(); 
    } 

    public class ConsoleLogger : ILogger 
    { 
     public void Log(string message) 
     { 
      Console.Out.WriteLine(message); 
     } 
    } 

    public interface ILogger 
    { 
     void Log(string message); 
    } 

    public class Connection 
    { 
     public Connection(string info) 
     { 
      Info = info; 
     } 

     public string Info { get; private set; } 
    } 

    public class Module : NinjectModule 
    { 
     public override void Load() 
     { 
      Bind<ILogger>().To<ConsoleLogger>(); 

      Bind<IDownloader>().To<Downloader>() 
       .WithConstructorArgument("connection", context => 
       { 
        var p = context.Parameters.First(x => x.Name == "connection"); 
        return p.GetValue(context, null); 
       }); 
      } 
    } 
} 

Respuesta

13

Si siempre desea especificar la hora de resolver un ConnectionIDownloader entonces creo que el ConstructorArgument (que es un IParameter) es lo que busca:

[Test] 
public void Run_Forrest_Run() 
{ 
    using (var kernel = new StandardKernel(new Module())) 
    { 
     var connection = new Connection(Guid.NewGuid().ToString()); 
     var downloader = kernel.Get<IDownloader>(new [] { 
      new ConstructorArgument("connection", connection) }); 

     Assert.That(downloader.Connection.Info, Is.EqualTo(connection.Info)); 
    } 
} 

public class Module : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<ILogger>().To<ConsoleLogger>(); 
     Bind<IDownloader>().To<Downloader>(); 
    } 
} 
+0

Un agradable! Funciona muy bien, gracias por ayudarme! – Pelle

Cuestiones relacionadas