Ninject,将构造函数参数传递给内核 [英] Ninject, passing constructor argument to the kernel
问题描述
这里是我的问题:
我想在每次从内核请求一个实例时将其中的一个值传递给构造函数。我在下面写了一些代码来说明问题。测试是不是失败,所以我想这是可行的,但它看起来很丑陋。有没有更好的,更清洁的方式来完成这个与Ninject?还是应该重新考虑我的设计?
[TestFixture]
public class Sandbox
{
[Test ]
public void Run_Forrest_Run()
{
using(var kernel = new StandardKernel(new Module()))
{
var connection = new Connection 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(连接连接,ILogger记录器)
{
连接=连接;
Logger = logger;
}
public Connection Connection {get;私人集}
public void Download()
{
Logger.Log(Downloading ...);
}
public ILogger Logger {get;私人集}
}
public interface IDownloader
{
Connection Connection {get; }
void Download();
}
public class ConsoleLogger:ILogger
{
public void日志(字符串消息)
{
Console.Out.WriteLine );
}
}
public interface ILogger
{
void Log(string message);
}
public class Connection
{
public Connection(string info)
{
Info = info;
}
public string Info {get;私人集}
}
public class Module:NinjectModule
{
public override void Load()
{
Bind< ILogger>至< ConsoleLogger>();
Bind< IDownloader>()。To< Downloader>()
.WithConstructorArgument(connection,context =>
{
var p = context。 Parameters.First(x => x.Name ==connection);
return p.GetValue(context,null);
});
}
}
}
如果您在解析 IDownloader
时总是想指定 Connection
,那么我认为 ConstructorArgument
(这是一个 IParameter
)是您要查找的:
[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>();
}
}
Here is my problem: I want to pass in one of the values to the constructor every time I request an instance form the kernel. I written some code below to illustrate the problem. The test is not failing so I guess that this works, but it does look pretty ugly. Is there a better, cleaner way to accomplish this with Ninject? Or should I rethink my design? All suggestions are appreciated.
[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);
});
}
}
}
If you always want to specify the Connection
when resolving a IDownloader
then I think the ConstructorArgument
(which is a IParameter
) is what you are looking for:
[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>();
}
}
这篇关于Ninject,将构造函数参数传递给内核的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!