关于mvc里面的依赖注入和ninject的使用

1 篇文章 0 订阅

依赖注入:为了在引用接口的方法的时候为了耍帅,不引用实现这个接口方法的类,导致了一系列解决方案,实际我感觉只是把接口和对应的实现类放在了一起,方便修改,本质貌似没变(个人见解,不对请在留言区喷我)。

可能第一段话比较难理解,先看一个例子:

没有依赖注入的情况:

有一个发送邮件的接口(IEmailSender):

public interface IEmailSender
    {
        string SendEmail(string str);
    }

需要一个类(MyEmailSender)来实现这个接口:

public class MyEmailSender : IEmailSender
    {
        public string SendEmail(string str)
        {
            return "发送内容:" + str;
        }
    }

然后我们在需要发邮件的时候,通常就这样做了:

IEmailSender mySender = new MyEmailSender();//引入了接口类,和实现这个接口的方法的类
mySender.SendEmail("123");//为了使用SendEmail,我们引用了两个类

从上面的代码可以看出,我们为了调用一个发邮件的方法,使用了两个类,如果MyEmailSender这个类改了名字或者修改了话,就要这里也要改,大牛们就说,这个的耦合性太高,不好,应该做到只关联接口,但是这不可能,我甚至觉得,不要用接口不就好了吗?确实开发有时候用的接口也不多,就写个普通类就好,但是,大神的世界我们不懂,接口也有接口的好处,接口就是要依赖于这个实现接口的类的,所以,依赖注入就是解决这样的情况。

个人理解:当使用接口的方法的时候才考虑使用依赖注入。

具体mvc里面怎么用,可以使用一个第三方dll,ninject,github:https://github.com/ninject/Ninject

建议使用nu'get获取即可。

使用依赖注入之后的样子:

接口类和实现接口方法的类不需要修改,主要修改的是调用的时候:

//1:创建一个Ninject的内核
IKernel ninject = new StandardKernel();
//2:就是配置Ninject内核,其实就是将实现类和接口类绑定在一起
ninject.Bind<IEmailSender>().To<MyEmailSender>();
//3:最后一步就是使用Ninject创建一个对象了
IEmailSender mySender = ninject.Get<IEmailSender>();
mySender.SendEmail("123");

从原来的两行代码变成了四行代码,呵呵了,怎么越加解耦越加多代码,并且还是引用了实现接口的方法的类啊,我只能说,不绑定,怎么可能知道是对应的类,很明显第一二行是可以放在一个初始化类里面,然后真正使用的时候就用下面两行代码就可以了,所以开头就说了:感觉只是把接口和对应的实现类放在了一起,方便修改,本质貌似没变(个人见解,不对请在留言区喷我)。

所以在mvc里面:

初始化的注入类:NinjectControllerFactory

以后所有的接口和实现接口方法的类都绑定在这里了

public class NinjectControllerFactory : DefaultControllerFactory
    {
        private IKernel ninjectKernel;

        public NinjectControllerFactory()
        {
            ninjectKernel = new StandardKernel();
            AddBindings();
        }

        private void AddBindings()
        {
            ninjectKernel.Bind<IEmailSender>().To<MyEmailSender>();//绑定关系都在这里了
        }

        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            return controllerType == null ? null : (IController)ninjectKernel.Get(controllerType);//这里的作用就是把这些绑定关系传递到控制器上面
        }
    }

然后在Global.asax里面的Application_Start方法里面加入这一句:

ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());

这是第一种方法,第二种是这样:

public class NinjectResolver : IDependencyResolver
    {
        private IKernel kernel;
        public NinjectResolver()
        {
            this.kernel =new StandardKernel();
            AddBinding();
        }
        public IEnumerable<Object> GetServices(Type serviceType)
        {
            return kernel.GetAll(serviceType);
        }
        public Object GetService(Type serviceType)
        {
            return kernel.TryGet(serviceType);
        }
        void AddBinding()
        {
            kernel.Bind<IEmailSender>().To<MyEmailSender>();
        }
    }

然后在Global.asax里面的Application_Start方法里面加入这一句:

DependencyResolver.SetResolver(new NinjectResolver());//注册Ioc容器

两种都可以,记得global里面的代码更换就行

然后在控制器里面就可以通过构造函数获得了,具体为什么也说不清,网上查的就是这样:

private IEmailSender _sender;
public HomeController(IEmailSender sender) {
       _sender = sender;//通过控制器的构造函数获取了这个接口
}
public ActionResult Index()
{
      _sender.SendEmail("123");//使用这个接口的方法
      return View();
}

其实可以看出,是真的没有引用到MyEmailSender这个类,把他们放在一起了,其实说到最后,这样是不是好的做法,不敢说,说不定以后有更好的方法,现在大家都这样用,就这样了,并且.net core的依赖注入更加强烈了,不需要使用ninject了,微软直接集成了,回头再重复看看,以前core时候的注入看的一脸懵逼。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值