2012-02-16 10 views
6

Oto mój problem: Chcę przekazać jedną z wartości do konstruktora za każdym razem, gdy zażądam instancji z jądra. Napisałem trochę kodu poniżej, aby zilustrować problem. Test nie zawodzi, więc myślę, że to działa, ale wygląda całkiem paskudnie. Czy istnieje lepszy i czystszy sposób na osiągnięcie tego przy pomocy Ninject? Czy powinienem ponownie przemyśleć mój projekt? Wszystkie sugestie są doceniane.Ninject, przekazujący argument konstruktora do jądra

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

Odpowiedz

13

Jeśli zawsze chcesz określić Connection podczas rozwiązywania IDownloader to myślę, że ConstructorArgument (co jest IParameter) jest to, czego szukasz:

[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

miłym! Działa świetnie, dzięki za pomoc! – Pelle

Powiązane problemy