How can I use Ninject to instantiate in child classes?

I am learning how to use nInject for a new application that I am developing and have created the following sample code that can be copied / pasted into a simple console application. It returns an IFoo instance successfully, but I have a question about that.

How do I change the code so that the FooManager class instantiates the Foo object without doing "new". Do I need to introduce the kernel as well? But if the kernel is injected and I change the line to read var foo = _kernel.Get<IFoo>()

, isn't that introducing an anti-service locator pattern?

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

    //******************************************************
}

      

+3


source to share


2 answers


First you need to think about the purpose of Foo. Is this some kind of datacontainer or some kind of service?

In the first case, your code is fine as it is. Datacontainers have no dependencies and should not be created by an IoC container.

For the second case, read about Ninject.Extensions.Factory.



http://www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction/

https://github.com/ninject/ninject.extensions.factory/wiki

+4


source


There are several ways to eliminate this dependency. You can do the same as with the database dependency and use constructor injection. You can do property injection ( https://github.com/ninject/ninject/wiki/Injection-Patterns ). Another way, and perhaps what you are looking for, is the location of the service. For that, you can update your FooManager ctor to require IKernel. This will be resolved automatically, and you can use the kernel that is passed in to get 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;
    }
}

      

+2


source







All Articles