下面这段代码,会报一个错误:
k.Bind<DALInterface>().To<SqlserverUserDAL>().Named("SqlServer");
k.Bind<DALInterface>().To<AccessUserDAL>().Named("Access");
var ord = k.Get<Order>();"Error activating DALInterface More than one matching bindings are available. Matching bindings: 1) binding from DALInterface to SqlserverUserDAL 2) binding from DALInterface to AccessUserDAL Activation path: 2) Injection of dependency DALInterface into parameter _dal of constructor of type Order 1) Request for Order Suggestions: 1) Ensure that you have defined a binding for DALInterface only once.
这个错误提示表明在尝试激活 DALInterface 时,Ninject 找到了多个匹配的绑定(SqlserverUserDAL 和 AccessUserDAL),
这导致了冲突。根据提供的错误信息,这个问题发生在尝试构造 Order 类型的对象时,因为 Order 的构造函数依赖于 DALInterface。
要解决这个问题,你需要确保在解析 Order 对象时明确指定使用哪个 DALInterface 的实现。
由于你已经使用了命名绑定,你可以在解析时通过指定绑定的名称来选择具体的实现。
// 首先获取你想要的DALInterface实现,这里以"SqlServer"为例
var sqlDal = k.Get<DALInterface>("SqlServer");
// 然后使用这个实现来构造Order对象
var ord = new Order(sqlDal);
ord.Insert();我们首先解析名为 "SqlServer" 的 DALInterface 实现,然后使用这个实现来手动构造 Order 对象。
这样,Ninject 就不会在尝试自动注入 DALInterface 时产生冲突了。
另外,你还可以考虑重构你的代码或配置来避免这种冲突。
例如,你可以为每个实现创建不同的接口,这样你就可以在 Order 类中直接依赖于特定的接口,而不是通用的 DALInterface。
或者,你可以使用条件绑定来确保在不同的上下文中使用不同的实现。
但是这样用不就不是自动注入了吗,怎么即有多组绑定,又可以自动注入?
这是一个常见的问题,即如何在有多个绑定的情况下实现自动注入。
通常,依赖注入框架(如 Ninject)在自动注入时会查找匹配的绑定,并且如果有多个匹配项,就会导致冲突。
在这种情况下,你可以使用一些技巧来解决问题并保留自动注入的功能。
上下文绑定(Contextual Binding)
你可以使用 Ninject 的上下文绑定功能来根据不同的上下文自动注入不同的实现。
这样,你可以定义多个绑定,但每个绑定只在特定的上下文中有效。
例如:
k.Bind<DALInterface>().To<SqlserverUserDAL>().WhenInjectedInto<Order>(); k.Bind<DALInterface>().To<AccessUserDAL>().WhenInjectedInto<SomeOtherClass>();
条件绑定(Conditional Binding)
除了上下文绑定,你还可以使用条件绑定,基于某些条件(如配置文件、环境变量等)选择不同的实现。
这样,Ninject 在解析依赖项时会根据条件选择合适的绑定。
例如:
k.Bind<DALInterface>().To<SqlserverUserDAL>(). When(ctx => ConfigurationManager.AppSettings["UseSqlServer"] == "true"); k.Bind<DALInterface>().To<AccessUserDAL>(). When(ctx => ConfigurationManager.AppSettings["UseSqlServer"] != "true");
工厂模式(Factory Pattern)
另一种解决方案是使用工厂模式来创建对象。你可以定义一个工厂接口和相应的实现,让 Ninject 解析工厂接口,
然后在工厂实现中根据需要使用不同的 DALInterface 实现。
这样,你可以在运行时决定使用哪个实现,同时仍然利用 Ninject 的自动注入功能。
例如:
public interface IDALFactory
{
DALInterface GetDAL();
}
public class DALFactory : IDALFactory
{
private readonly IKernel _kernel;
public DALFactory(IKernel kernel) { _kernel = kernel; }
public DALInterface GetDAL()
{ /* 根据需要使用 _kernel.Get<DALInterface>("...") 获取实现 */ }
}然后在你的 Order 类中:
public class Order
{
private readonly IDALFactory _dalFactory;
public Order(IDALFactory dalFactory) { _dalFactory = dalFactory; }
public void Insert()
{ /* 使用 _dalFactory.GetDAL() 获取需要的 DALInterface 实现 */ }
}总结
有多种方法可以在有多个绑定的情况下实现自动注入。
选择哪种方法取决于你的具体需求和项目结构。
上下文绑定和条件绑定是常用的技巧,而工厂模式则可以提供更灵活的对象创建方式。
下面的是构造函数方式的自动注入:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ninject;
using Ninject.Parameters;
namespace IOC容器_Ninject
{
class Program
{
static void Main(string[] args)
{
var k = new StandardKernel(); // 初始化Ninject的内核
k.Bind<DALInterface>().To<SqlserverUserDAL>(); // 绑定接口到具体的实现
var ord = k.Get<Order>(); // 获取Order对象,Ninject会自动注入其依赖项
ord.Insert();
Console.ReadKey();
}
}
public class User
{
public int ID { get; set; }
public string Name { get; set; }
}
//数据库读写
public class SqlserverUserDAL : DALInterface
{
public void Insert(User user)
{
Console.WriteLine("SQL Server给User表插入一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("SQL Server根据ID得到User表一条记录");
return null;
}
}
public class AccessUserDAL : DALInterface
{
public void Insert(User user)
{
Console.WriteLine("Access给User表插入一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("Access根据ID得到User表一条记录");
return null;
}
}
public interface DALInterface
{
void Insert(User user);
User GetUser(int id);
}
public class Order
{
private DALInterface dal;
public Order(DALInterface _dal)
{
this.dal = _dal;
}
public void Insert()
{
dal.Insert(new User() { ID = 1, Name = "lxy1" });
}
}
}下面是多个绑定下实现自动注入,使用上下文绑定:
static void Main(string[] args)
{
var k = new StandardKernel();
//k.Bind<DALInterface>().To<SqlserverUserDAL>();
//k.Bind<DALInterface>().To<AccessUserDAL>();
//上下文绑定
k.Bind<DALInterface>().To<SqlserverUserDAL>().WhenInjectedInto<Order>();
var ord = k.Get<Order>();
ord.Insert();
Console.ReadKey();
}下面是多个绑定下实现自动注入,使用条件绑定:
static void Main(string[] args)
{
var k = new StandardKernel();
k.Bind<DALInterface>().To<SqlserverUserDAL>()
.When(ctx => ConfigurationManager.AppSettings["UseSqlServer"] == "true");
k.Bind<DALInterface>().To<AccessUserDAL>()
.When(ctx => ConfigurationManager.AppSettings["UseAccessServer"] == "true");
var ord = k.Get<Order>();
ord.Insert();
Console.ReadKey();
}配置文件如下:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /> </startup> <appSettings> <add key="UseSqlServer" value="true" /> <add key="UseAccessServer" value="false" /> <!-- 其他设置 --> </appSettings> </configuration>
注意:要使用 ConfigurationManager.AppSettings,你得先引入下面的命名空间:

下面是多个绑定下实现的自动注入,使用工厂模式:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ninject;
using Ninject.Parameters;
using System.Configuration;
namespace IOC容器_Ninject
{
class Program
{
static void Main(string[] args)
{
var k = new StandardKernel();
k.Bind<DALInterface>().To<SqlserverUserDAL>().Named(DALNameEnum.Sqlserver.ToString());
k.Bind<DALInterface>().To<AccessUserDAL>().Named(DALNameEnum.Access.ToString());
var ord = new Order(new DALFactory(k) { daltype= DALNameEnum.Sqlserver });
ord.Insert();
Console.ReadKey();
}
}
public interface IDALFactory
{
DALInterface GetDAL();
}
public enum DALNameEnum
{
Sqlserver,Access
}
public class DALFactory : IDALFactory
{
private readonly IKernel _kernel;
public DALFactory(IKernel kernel) { _kernel = kernel; }
public DALNameEnum daltype { get; set; }
public DALInterface GetDAL()
{
DALInterface dal = _kernel.Get<DALInterface>(daltype.ToString()); ;
return dal;
}
}
public class User
{
public int ID { get; set; }
public string Name { get; set; }
}
//数据库读写
public class SqlserverUserDAL : DALInterface
{
public void Insert(User user)
{
Console.WriteLine("SQL Server给User表插入一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("SQL Server根据ID得到User表一条记录");
return null;
}
}
public class AccessUserDAL : DALInterface
{
public void Insert(User user)
{
Console.WriteLine("Access给User表插入一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("Access根据ID得到User表一条记录");
return null;
}
}
public interface DALInterface
{
void Insert(User user);
User GetUser(int id);
}
public class Order
{
private readonly IDALFactory _dalFactory;
public Order(IDALFactory dalFactory)
{
_dalFactory = dalFactory;
}
public void Insert()
{
var dal = _dalFactory.GetDAL();
dal.Insert(new User() { ID = 1, Name = "lxy1" });
}
}
}其它参考资料:
下面是NInject的系列教程,请大家观看:
https://www.cnblogs.com/uncle_danny/p/6394887.html
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!


少有人走的路


















