C# 使用Ninject在运行时进行依赖项注入
当只在运行时确定要注入哪个类时,如何使用Ninject注入特定的依赖项?我有一个接口和实现,如下所示:C# 使用Ninject在运行时进行依赖项注入,c#,dependency-injection,ninject,C#,Dependency Injection,Ninject,当只在运行时确定要注入哪个类时,如何使用Ninject注入特定的依赖项?我有一个接口和实现,如下所示: public interface ICompanyDAL { Company LoadProfile(int companyID); } public class TechCompanySqlDAL : ICompanyDAL { Company LoadProfile(int companyID) { //Call Stored procs relat
public interface ICompanyDAL
{
Company LoadProfile(int companyID);
}
public class TechCompanySqlDAL : ICompanyDAL
{
Company LoadProfile(int companyID)
{
//Call Stored procs related to TechCompany
//Populate Model class TechCompany which is derived from abstract class Company
}
}
public class BankingCompanySqlDAL : ICompanyDAL
{
Company LoadProfile(int companyID)
{
//Call Stored procs related to BankingCompany
//Populate Model class BankingCompany which is derived from abstract class Company
}
}
我有一个服务类,需要调用以下两个具体类中的一个
public class CompanyService
{
private readonly ICompanyDAL companyDAL;
public CompanyHousingService(ICompanyDAL compDAL)
{
this.companyDAL = compDAL;
}
public Company LoadProfile(int companyID, CompanyType type)
{
if(type == CompanyType.Tech)
//Need to call TechCompanyDAL
else if (type == CompanyType.Banking)
//Need to call BankingCompanyDAL
}
}
我不希望服务类依赖于任何具体的类,因为这些类可能会改变。此外,我们可能会添加更多的公司类型。那么,如何基于反射将ICompanyDAL注入服务中呢
如果有人解释了更好的替代方案,我也愿意接受关于更改上述模式的建议。您可以将
ICompanyDAL
设置为通用,并将两个依赖项注入公司服务中,如下所示:
public interface ICompanyDAL<T> where T:Company
{
T LoadProfile(int companyID);
}
public class TechCompanySqlDAL : ICompanyDAL<TechCompany>
{
public TechCompany LoadProfile(int companyID)
{
//Call Stored procs related to TechCompany
//Populate Model class TechCompany which is derived from abstract class Company
}
}
public class BankingCompanySqlDAL : ICompanyDAL<BankingCompany>
{
public BankingCompany LoadProfile(int companyID)
{
//Call Stored procs related to BankingCompany
//Populate Model class BankingCompany which is derived from abstract class Company
}
}
public class CompanyService
{
private readonly ICompanyDAL<BankingCompany> bankingCompanyDAL;
private readonly ICompanyDAL<TechCompany> techCompanyDAL;
public CompanyService(ICompanyDAL<BankingCompany> banking_company_dal, ICompanyDAL<TechCompany> tech_company_dal)
{
bankingCompanyDAL = banking_company_dal;
techCompanyDAL = tech_company_dal;
}
public Company LoadProfile(int companyID, CompanyType type)
{
if (type == CompanyType.Tech)
return techCompanyDAL.LoadProfile(companyID);
else if (type == CompanyType.Banking)
return bankingCompanyDAL.LoadProfile(companyID);
//handle case of invalid type
}
}
您可以将ICompanyDAL
设置为泛型,并将两个依赖项注入CompanyService
中,如下所示:
public interface ICompanyDAL<T> where T:Company
{
T LoadProfile(int companyID);
}
public class TechCompanySqlDAL : ICompanyDAL<TechCompany>
{
public TechCompany LoadProfile(int companyID)
{
//Call Stored procs related to TechCompany
//Populate Model class TechCompany which is derived from abstract class Company
}
}
public class BankingCompanySqlDAL : ICompanyDAL<BankingCompany>
{
public BankingCompany LoadProfile(int companyID)
{
//Call Stored procs related to BankingCompany
//Populate Model class BankingCompany which is derived from abstract class Company
}
}
public class CompanyService
{
private readonly ICompanyDAL<BankingCompany> bankingCompanyDAL;
private readonly ICompanyDAL<TechCompany> techCompanyDAL;
public CompanyService(ICompanyDAL<BankingCompany> banking_company_dal, ICompanyDAL<TechCompany> tech_company_dal)
{
bankingCompanyDAL = banking_company_dal;
techCompanyDAL = tech_company_dal;
}
public Company LoadProfile(int companyID, CompanyType type)
{
if (type == CompanyType.Tech)
return techCompanyDAL.LoadProfile(companyID);
else if (type == CompanyType.Banking)
return bankingCompanyDAL.LoadProfile(companyID);
//handle case of invalid type
}
}
例如,您可以使用ganerics解决许多问题,但其中之一是:
您可以将ctor依赖项更改为IEnumerable
。
因此,也许这对您来说很好,请参见下面的代码:
现在是服务:
public class CompanyService
{
private readonly IEnumerable<ICompanyDAL>compDALs;
public CompanyHousingService(IEnumerable<ICompanyDAL> compDALs)
{
this.companyDALs = compDALs;
}
public Company LoadProfile(int companyID, CompanyType type)
=> companyDALs.FirstOrDefault(s => s.CompanyType==type)?.LoadProfile(companyID);
}
公共类公司服务
{
私有只读IEnumerablecompDALs;
上市公司住房服务(IEnumerable compdal)
{
this.companyDALs=compDALs;
}
上市公司LoadProfile(int companyID,CompanyType类型)
=>companyDALs.FirstOrDefault(s=>s.CompanyType==type)?.LoadProfile(companyID);
}
有许多方法可以解决,例如,您可以使用ganerics,但其中之一是:
您可以将ctor依赖项更改为IEnumerable
。
因此,也许这对您来说很好,请参见下面的代码:
现在是服务:
public class CompanyService
{
private readonly IEnumerable<ICompanyDAL>compDALs;
public CompanyHousingService(IEnumerable<ICompanyDAL> compDALs)
{
this.companyDALs = compDALs;
}
public Company LoadProfile(int companyID, CompanyType type)
=> companyDALs.FirstOrDefault(s => s.CompanyType==type)?.LoadProfile(companyID);
}
公共类公司服务
{
私有只读IEnumerablecompDALs;
上市公司住房服务(IEnumerable compdal)
{
this.companyDALs=compDALs;
}
上市公司LoadProfile(int companyID,CompanyType类型)
=>companyDALs.FirstOrDefault(s=>s.CompanyType==type)?.LoadProfile(companyID);
}
您需要注入两个代码> ICOMPANYDAL < /COD>依赖项。您可能还需要考虑一个通用的代码> ICOMPANYDAL < /Cord>接口,它是一个返回ICOMPANYDAL的单一工厂类。我喜欢这两个想法——使用通用接口和使用工厂类。你们是否介意提供一点代码来启动我?您需要注入两个代码> ICOMPANYDAL < /COD>依赖项。您可能还需要考虑一个通用的代码> ICOMPANYDAL < /COD>接口,它是一个返回ICOMPANYDAL的单一工厂类。我喜欢这两个想法——使用泛型接口和使用工厂类。你们介意提供一些代码让我开始吗?谢谢!这很有帮助!谢谢这很有帮助!注意:Ninject的多重注入特性注入到ctor中的IEnumerable
应该在构造函数中具体化(枚举),否则会导致严重的并发问题。因此,不要注入一个<代码> iQueDeaby/Cube >一个可以考虑注入一个<代码> IIST < /C>或一个数组<代码> []/Cord>。当然,我的坏XD,我用DICATIONATION编写了<<代码> iQueDebug <代码>。好吧,这个问题并不广为人知,我认为它是个bug。我建议取消对IEnumerable
注入的支持,但我认为它保持向后兼容。但是我建议不要使用它,因为这是一个陷阱。注意:Ninject的多重注入特性注入到ctor中的IEnumerable
应该在构造函数中具体化(枚举),否则会导致严重的并发问题。因此,不要注入一个<代码> iQueDeaby/Cube >一个可以考虑注入一个<代码> IIST < /C>或一个数组<代码> []/Cord>。当然,我的坏XD,我用DICATIONATION编写了<<代码> iQueDebug <代码>。好吧,这个问题并不广为人知,我认为它是个bug。我建议取消对IEnumerable
注入的支持,但我认为它保持向后兼容。不过我建议不要用它,因为它是一个陷阱。