使用Ninject

时间:2015-12-02 16:32:43

标签: c# dependency-injection ninject

如何在注入哪个类仅在运行时确定时,如何使用Ninject注入特定的依赖项?我有一个界面和说明如下:

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
    }   

}

我不希望Service类依赖于任何具体的类,因为那些可能会改变。我们也可以添加更多公司类型。那么如何基于反射将ICompanyDAL注入到服务中呢。

如果有人解释更好的替代方案,我也愿意接受改变上述模式的建议。

2 个答案:

答案 0 :(得分:2)

有许多方法可以解决,例如你可以使用优化,但其中一个就是:

  

您可以将 ctor 依赖关系更改为IEnumerable<ICompanyDAL>。   所以这可能对您有用,请参阅下面的代码:

public interface ICompanyDAL
{
   CompanyType CompanyType {get;}
   Company LoadProfile(int companyID);
}

public class TechCompanySqlDAL : ICompanyDAL
{
    public CompanyType CompanyType => CompanyType.Tech;
    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
{
    public CompanyType CompanyType => CompanyType.Banking;
    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 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); 
}

答案 1 :(得分:1)

您可以使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 
    }   
}

以下是注册依赖项并解析CompanyService对象的方法:

StandardKernel kernel = new StandardKernel();

kernel.Bind<ICompanyDAL<TechCompany>>().To<TechCompanySqlDAL>();
kernel.Bind<ICompanyDAL<BankingCompany>>().To<BankingCompanySqlDAL>();

var service = kernel.Get<CompanyService>();