Ninject,将构造函数参数传递给内核 [英] Ninject, passing constructor argument to the kernel

查看:174
本文介绍了Ninject,将构造函数参数传递给内核的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是我的问题:
我想在每次从内核请求一个实例时将其中的一个值传递给构造函数。我在下面写了一些代码来说明问题。测试是不是失败,所以我想这是可行的,但它看起来很丑陋。有没有更好的,更清洁的方式来完成这个与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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆