Dependency injection 如何使用Ninject在子类中创建实例?

Dependency injection 如何使用Ninject在子类中创建实例?,dependency-injection,inversion-of-control,ninject,Dependency Injection,Inversion Of Control,Ninject,我正在学习如何将nInject用于我正在开发的一个新应用程序,并且我已经创建了以下示例代码,这些代码可以复制/粘贴到一个简单的控制台应用程序中。它成功地返回了一个IFoo实例,但我有一个问题 我如何修改代码,让FooManager类创建Foo对象的实例而不执行“新建”操作。果仁也必须注射吗?但是如果内核被注入,我将行改为读取var foo=\u kernel.Get(),这不是引入了服务定位器反模式吗 namespace IOCTest { class Program {

我正在学习如何将nInject用于我正在开发的一个新应用程序,并且我已经创建了以下示例代码,这些代码可以复制/粘贴到一个简单的控制台应用程序中。它成功地返回了一个IFoo实例,但我有一个问题

我如何修改代码,让FooManager类创建Foo对象的实例而不执行“新建”操作。果仁也必须注射吗?但是如果内核被注入,我将行改为读取
var foo=\u kernel.Get()
,这不是引入了服务定位器反模式吗

namespace IOCTest
{
    class Program
    {
        static void Main(string[] args)
        {
            using (IKernel kernel = new StandardKernel(new StandardModule()))
            {
                // do something with the kernal
                var mgr = kernel.Get<IFooManager>();
                var foo = mgr.GetById(1);
            }
        }
    }

    public class StandardModule : Ninject.Modules.NinjectModule
    {
        public override void Load()
        {
            Bind<IDatabase>()
                .To<Database>()
                .InTransientScope();

            Bind<IFooManager>()
                .To<FooManager>()
                .InTransientScope();
        }
    }

    //******************************************************

    public interface IDatabase
    {
        object[] GetScalar(int id);
    }

    public class Database : IDatabase
    {
        public object[] GetScalar(int id)
        {
            return new object[] { "RowName" };
        }
    }

    //******************************************************

    public interface IFooManager
    {
        IFoo GetById(int id);
    }

    public class FooManager : IFooManager
    {
        private IDatabase _db;

        public FooManager(IDatabase db) { _db = db; }

        public IFoo GetById(int id)
        {
            var results = _db.GetScalar(id);
            var foo = new Foo();   // <-- HOW DO I ELIMINATE THIS DEPENDENCY?
            foo.Name = results[0].ToString();
            return foo;
        }
    }

    //******************************************************

    public interface IFoo
    {
        string Name { get; set; }
    }

    public class Foo : IFoo
    {
        public string Name { get; set; }
    }

    //******************************************************
}
名称空间IOCTest
{
班级计划
{
静态void Main(字符串[]参数)
{
使用(IKernel内核=新标准内核(新标准模块())
{
//用果仁做点什么
var mgr=kernel.Get();
var foo=mgr.GetById(1);
}
}
}
公共类StandardModule:Ninject.Modules.Ninject模块
{
公共覆盖无效负载()
{
绑定()
.至()
.InTransientScope();
绑定()
.至()
.InTransientScope();
}
}
//******************************************************
公共接口IDatabase
{
对象[]GetScalar(int-id);
}
公共类数据库:IDatabase
{
公共对象[]GetScalar(整数id)
{
返回新对象[]{“RowName”};
}
}
//******************************************************
公共接口IFooManager
{
ifoogetbyid(intid);
}
公共类FooManager:IFooManager
{
私有IDatabase_db;
公共FooManager(IDatabase db){{u db=db;}
公共IFoo GetById(int-id)
{
var results=\u db.GetScalar(id);

var foo=new foo();//有几种方法可以消除这种依赖关系。您可以执行与数据库依赖关系相同的操作,并使用构造函数注入。您可以执行属性注入()。另一种方法,也许您正在寻找的是服务位置。要做到这一点,您可以更新您的FooManager ctor以需要IKernel。这将自动解决,然后您可以使用传入的内核来获取Foo

public class FooManager : IFooManager
{
    private IDatabase _db;
    private IKernel _kernel;

    public FooManager(IDatabase db, IKernel kernel) { _db = db; _kernel = kernel;}

    public IFoo GetById(int id)
    {
        var results = _db.GetScalar(id);
        // var foo = new Foo();   // <-- HOW DO I ELIMINATE THIS DEPENDENCY?
        var foo = kernel.Get<IFoo>(); // Like this perhaps
        foo.Name = results[0].ToString();
        return foo;
    }
}
公共类FooManager:IFooManager
{
私有IDatabase_db;
私有IKernel_内核;
公共FooManager(IDatabase db,IKernel内核){{u db=db;{u kernel=kernel;}
公共IFoo GetById(int-id)
{
var results=\u db.GetScalar(id);

//var foo=new foo();//首先,您必须考虑foo的用途。这是某种数据容器还是某种服务

在第一种情况下,您的代码就像它一样完美。数据容器没有依赖项,不应该由IoC容器创建

在第二种情况下,请阅读Ninject.Extensions.Factory


为服务定位器注入内核不是一种反模式吗?但如果你不这样做,那么你必须注入一个IFoo实例。这对我来说真的很奇怪。我现在非常关注这个概念。@John,如果你愿意,你可以创建一个工厂,建立一个foo对象并作为IFoo返回。是的,服务位置n通常被认为是一种反模式,但这并不意味着它总是不好的,而且可能是正确的决定。谢谢。我也曾与工厂打过交道,但最终它似乎只是内核的包装,仍然必须到处传递。因为我使用Foo作为数据容器,你的评论让我感到安慰,它是可以的要在此实例中使用“new!”:)