一步一步教你使用Ninject进行依赖注入

首先使用VS新建一个控制台项目TestNinjectConsole,再建立一个类库项目,就叫做Little.Log,打开工具-程序包管理器-程序包管理控制台,输入

install-package ninject

就会自动下载ninject到项目中。

在Little.Log 中新建一个文件夹,叫做ILogs,一个文件夹Logs,项目截图如下

新建一个ILog接口,编码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Little.Log.ILogs
{
    public interface ILog
    {
        void WriteLog(string log);
    }
}

然后再建立两个接口,分别为IFileLog,IDataBaseLog,编码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Little.Log.ILogs
{
    public interface IFileLog:ILog
    {
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Little.Log.ILogs
{
    public interface IDataBaseLog:ILog
    {
    }
}

然后在Log文件中添加Log类,实现ILog接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Little.Log.ILogs;

namespace Little.Log.Los
{
    public class Log:ILog
    {
        public virtual void WriteLog(string log)
        {
            Console.WriteLine(log);
        }
    }
}

紧接着添加FileLog类和DataBaseLog类,分别实现IFileLog和IDataBaseLog接口,并且都继承于Log类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Little.Log.ILogs;

namespace Little.Log.Los
{
    public class FileLog :Log,IFileLog
    {
        private string name = "Filelog:";
        public override void WriteLog(string log)
        {
            base.WriteLog(name + log);
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Little.Log.ILogs;

namespace Little.Log.Los
{
    public class DataBaseLog:Log,IDataBaseLog
    {
        private string name = "DataBaseLog:";

        public override void WriteLog(string log)
        {
            base.WriteLog(name + log);
        }
    }
}

这样一个基于接口编程的组件就已经准备好了,其实这种模式就传说中Repository模式,有兴趣的话可以查阅相关资料了解这种模式。

下面就是依赖注入的关键部分了。

在控制台项目TestNinjectConsole中新建一个类,叫做MyModule,并且继承于NinjectModule,编码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ninject.Modules;
using Little.Log.ILogs;
using Little.Log.Los;

namespace TestNinjectConsole
{
    class MyModule :NinjectModule
    {
        public override void Load()
        {
       //把接口绑定到具体要实现的类
this.Bind<IFileLog>().To<FileLog>(); this.Bind<IDataBaseLog>().To<DataBaseLog>(); } } }

下面建立一个测试的方法,假设这个方法会记录两种不同的日志,文件日志和数据库日志

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Little.Log.ILogs;

namespace TestNinjectConsole
{
    class TestClass
    {
        [Ninject.Inject]
        public IFileLog FileLog { get; set; }

        [Ninject.Inject]
        public IDataBaseLog DataBaseLog { get; set; }

        public void TestFileLog(string log)
        {
            FileLog.WriteLog(log);
        }

        public void TestDataBaseLog(string log)
        {
            DataBaseLog.WriteLog(log);
        }
    }
}

上面的代码,声明了两种不同接口的属性,但是并没有实例化,并且在属性上方加了[Ninject.Inject]的特性,这是说明这两个属性是通过依赖注入实现的,不需要去手动创建

而且注意这个属性必须声明为公有,不然将会导致注入失败,(也可以使用私有,但是会使用一些特殊配置,此处不做解释)

我们再在Pragram类添加如下代码

     private static IKernel kernel;
        static Program()
        {
            kernel = new Ninject.StandardKernel(new MyModule());
        }

        static T GetType<T>()
        {
            return kernel.Get<T>();
        }

这里是在主函数中注册了内核容器,该容器就是用来做依赖注入的,并且我们在静态构造函数中实例化这个容器,使用我们编写的Module,作为实例化参数。然后又创建了静

态泛型方法,用来获取类的实例,下面我们在主函数中这样使用它

        static void Main(string[] args)
        {
            var test = GetType<TestClass>();
            test.TestFileLog("this is file log.");
            test.TestDataBaseLog("this is database log.");
            Console.WriteLine("press any key to continue...");
            Console.ReadKey();
        } 

这样我们就不再需要使用new 方法去创建类了,而是使用GetType<T>()的方法创建类的实例(是不是有点像工厂模式啊...)

而且当我们有很多类的都需要使用到这两个日志记录的类时,难道我们要为每个类都去实例化日志记录类吗?这样的话你的代码可能就是到处都是

FileLog log =  new FileLog()这样的代码喽,现在有了依赖注入,是不是会简化好多啊,只要注册一个全局的容器就可以了,而且Ninject不仅支持属性注入,还支持构造

函数注入,接口绑定也是可以带构造参数的哦,再者,我这里其实只是使用一层依赖注入,ninject强大之处可是在于复杂组件的多层次注入哦,详情请参考Ninject API。

posted @ 2014-01-17 23:50  王晓阳  阅读(1349)  评论(0编辑  收藏  举报