Ninject - how and when to inject

后端 未结 2 1826
孤街浪徒
孤街浪徒 2020-12-25 14:01

I\'m a newbie when it comes to DI and ninject and I\'m struggling a bit about when the actual injection should happen and how to start the binding.

I\'m using it alr

相关标签:
2条回答
  • 2020-12-25 14:42

    You are directly newing TestClass, which Ninject has no way of intercepting - remember there's no magic like code transformation intercepting your news etc.

    You should be doing kernel.Get<TestClass> instead.

    Failing that, you can inject it after you new it with a kernel.Inject( test);

    I think there's an article in the wiki that talks about Inject vs Get etc.

    Note that in general, direct Get or Inject calls are a Doing It Wrong smell of Service Location, which is an antipattern. In the case of your web app, the NinjectHttpModule and PageBase are the hook that intercepts object creation - there are similar interceptors / logical places to intercept in other styles of app.

    Re your Bind<TestClass>().ToSelf(), generally a StandardKernel has ImplicitSelfBinding = true which would make that unnecessary (unless you want to influence its Scope to be something other than .InTransientScope()).

    A final style point:- you're using property injection. There are rarely good reasons for this, so you should be using constructor injection instead.

    And do go buy Dependency Injection in .NET by @Mark Seemann, who has stacks of excellent posts around here which cover lots of important but subtle considerations in and around the Dependency Injection area.

    0 讨论(0)
  • 2020-12-25 14:55

    OK,

    I've found out how to do what I need, thanks in part to your comments Ruben. I've created a new module that basically holds the configuration that I use in the class library. Within this module I can either Bind using a placeholder Interface or I can add a constructor parameter to the CustomerLoader. Below is the code from a dummy console app to demonstrating both ways.

    This might help someone else getting started with Ninject!

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Ninject.Core;
    using Ninject.Core.Behavior;
    
    namespace NinjectTest
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                var kernel = new StandardKernel(new RepositoryModule(), new  ProgramModule());            
                var loader = kernel.Get<CustomerLoader>();
                loader.LoadCustomer();
                Console.ReadKey();
            }
        }
    
        public class ProgramModule : StandardModule
        {
            public override void Load()
            {
                // To get ninject to add the constructor parameter uncomment the line below
                //Bind<CustomerLoader>().ToSelf().WithArgument("fileName", "string argument file name");
                Bind<LiveFileName>().To<LiveFileName>();
            }
        }
    
        public class RepositoryModule : StandardModule
        {
            public override void Load()
            {
                Bind<ICustomerRepository>().To<CustomerRepository>().Using<SingletonBehavior>();
            }
        }
    
        public interface IFileNameContainer
        {
            string FileName { get; }
        }
        public class LiveFileName : IFileNameContainer
        {
            public string FileName
            {
                get { return "live file name"; }
            }
        }
    
    
        public class CustomerLoader
        {
            [Inject]
            public ICustomerRepository CustomerRepository { get; set; }
            private string _fileName;
    
            // To get ninject to add the constructor parameter uncomment the line below
            //public CustomerLoader(string fileName)
            //{
            //    _fileName = fileName;
            //}
            public CustomerLoader(IFileNameContainer fileNameContainer)
            {
                _fileName = fileNameContainer.FileName;
            }
    
            public void LoadCustomer()
            {
                Customer c = CustomerRepository.GetCustomer();
                Console.WriteLine(string.Format("Name:{0}\nAge:{1}\nFile name is:{2}", c.Name, c.Age, _fileName));
            }
        }
    
        public interface ICustomerRepository
        {
            Customer GetCustomer();
        }
        public class CustomerRepository : ICustomerRepository
        {
            public Customer GetCustomer()
            {
                return new Customer() { Name = "Ciaran", Age = 29 };
            }
        }
        public class Customer
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }
    }
    
    0 讨论(0)
提交回复
热议问题