简单的构造函数注入的例子如下
public interface IDataAccess { void Add(); } public class SqlServerDal:IDataAccess { public void Add() { Console.WriteLine("在数据库中添加一条订单!"); } } public class Order { private IDataAccess _ida;//定义一个私有变量保存抽象 //构造函数注入 public Order(IDataAccess ida) { _ida = ida;//传递依赖 } public void Add() { _ida.Add(); } } static void Main(string[] args) { SqlServerDal dal = new SqlServerDal();//在外部创建依赖对象 Order order = new Order(dal);//通过构造函数注入依赖 order.Add(); Console.Read(); }
但我用泛型类一样可以实现啊,而且看起来比依赖注入代码轻松简介多了。
如果有多个注入,我泛型类参数就多加几个就是了。
(请不要回答泛型类参数个数有限制这种,一般也用不到那么多需要注入的)
它们在应用上有什么区别吗,求告知。
public interface IDataAccess { void Add(); } public class SqlServerDal:IDataAccess { public void Add() { Console.WriteLine("在数据库中添加一条订单!"); } } public class Order<T> where T:IDataAccess,new() { private T _ida = new T();//定义一个私有变量保存抽象 public void Add() { _ida.Add(); } } static void Main(string[] args) { Order order = new Order<SqlServerDal>(); order.Add(); Console.Read(); }
2333,那么问题来了。如果SqlServerDal也是有依赖的呢。你应该如何来写。
SqlServerDal 也变成泛型类啊
public class SqlServerDal<T>:IDataAccess { T abc = new T(); public void Add() { Console.WriteLine("在数据库中添加一条订单!"); } }
T就是那个依赖
@acfun: 你把main里的写出来
@长蘑菇星人:
public class SqlServerDal<T> : IDataAccess where T :new() { T abc = new T(); public void Add() { Console.WriteLine("在数据库中添加一条订单!"); } } static void Main(string[] args) { var order = new Order<SqlServerDal<tmp>>(); order.Add(); Console.Read(); } public class tmp { }
编译能通过,语法没错
@acfun: 看起来很完美了。233333。那么问题又来了。假如tmp构建一次需要大量系统资源,可能有IO,数据库之类操作。怎么办。
@长蘑菇星人:
首先非常感谢你的回答。
public class SqlServerDal<T> : IDataAccess where T : new() { T abc; public void initT() {
if (abc == null) abc = new T(); } public void Add() { initT(); Console.WriteLine("在数据库中添加一条订单!" + abc.ToString()); } public void Edit() { Console.WriteLine("在数据库中编辑一条订单!"); } } static void Main(string[] args) { var order = new Order<SqlServerDal<tmp>>(); order.Add(); order.Edit(); Console.Read(); } public class tmp { public tmp() { }//大量资源操作 }
你说的问题在构造器注入时也有。
上面代码是仿方法注入的,只不过“注入”是在内部执行了。
只不过依赖注入把tmp的实例化放在外部,而我这个方法是放在里面而已。
@acfun: 我的意思是如果tmp这个类是单例怎么办。
好像确实如你所说的,单例类的话,必须在外部传入,也就是注入了。
虽然我没碰到过这种情况。
或许这就是它们的区别?
我在查查其它资料吧,感谢你的回答
@acfun: 别急,慢慢想。
当项目大起来。依赖复杂起来。人肉依赖基本会累死个人。都要有一个工厂来自动DI的。
而你觉得做的优雅的地方却并没有什么用处。它刚好是一个大量可重复的过程。最终必然会交给工厂来自动实现。工厂是好东西,你可以在里面施魔法。
通过泛型约束却实实在在增加了开发人员维护的成本。有种被绑了手脚的感觉。
@长蘑菇星人:
嗯,谢谢你的回答,确实我之前一直在用泛型类来做,项目也并不复杂,所以跟DI比较起来才有疑惑的。