C# 注入要求对象取决于构造函数注入中的条件

C# 注入要求对象取决于构造函数注入中的条件,c#,unity-container,solid-principles,C#,Unity Container,Solid Principles,我有一个接口 public interface ITrnsitReport { List<UserDefinedType> GetTransitReportData (); } 当其为“PAI”时,我如何将PAIValidateInput和PaiTransitrPository对象注入到TransitrPort构造函数和“PPDC”PPDCValidateInput和ppdcTransitrPository对象中。您有几个选项,我更喜欢使用命名注册: container.R

我有一个接口

public interface ITrnsitReport
{
    List<UserDefinedType> GetTransitReportData ();
}

当其为“PAI”时,我如何将
PAIValidateInput
PaiTransitrPository
对象注入到
TransitrPort
构造函数和“PPDC”
PPDCValidateInput
ppdcTransitrPository
对象中。

您有几个选项,我更喜欢使用命名注册:

container.RegisterType<IValidateInput, PPDCValidateInput>("PPDC");        
container.RegisterType<IValidateInput, PAIValidateInput>("PAI");
container.RegisterType<IValidateInput, PPDCValidateInput>("PPDC");
container.RegisterType<IValidateInput, PAIValidateInput>("PAI");
container.RegisterType<ITransitRepository, PPDCTransitRepository>("PPDC");
container.RegisterType<ITransitRepository, PAITransitRepository>("PAI");
container.RegisterType<ITransitReport, PAITransitReport>("PAI");
container.RegisterType<ITransitReport, PPDCTransitReport>("PPDC");
container.RegisterType(“PPDC”);
容器注册类型(“PAI”);
然后,您需要使用覆盖解析ITransitInfo:

container.Resolve<ITransitInfo>(new InjectionConstructor(new ResolvedParameter<IValidateInput>("PPDC"), ...)
container.Resolve(新的InjectionConstructor(新的ResolvedParameter(“PPDC”),…)

有几种方法

1。使用命名注册

container.RegisterType<IValidateInput, PPDCValidateInput>("PPDC");

container.RegisterType<IValidateInput, PAIValidateInput>("PAI");
或在您的注册中:

container.Register<ITrnsitReport>(new InjectionConstructor(new ResolvedParameter<IValidateInput>("PPDC"));
好的方面是,逻辑在接口本身内部,与注册无关。但是,它仍然要求接口的使用者知道它想要什么


3.使用不同的界面。(可能是我的工作中最好的选择)

然后在容器中分别注册它们,并注入实际需要的接口

public TransitReport (IPAIValidateInput inputValidation,
                        ITransitRepository transitRepo)
{
    _inputValidation = inputValidation;
    _transitRepo = transitRepo;
}
需要没有实际声明的接口。但在我看来,它使DI逻辑更加纯净


4.使用基类并将它们全部组合起来

第一个修复命名注册:

container.RegisterType<IValidateInput, PPDCValidateInput>("PPDC");        
container.RegisterType<IValidateInput, PAIValidateInput>("PAI");
container.RegisterType<IValidateInput, PPDCValidateInput>("PPDC");
container.RegisterType<IValidateInput, PAIValidateInput>("PAI");
container.RegisterType<ITransitRepository, PPDCTransitRepository>("PPDC");
container.RegisterType<ITransitRepository, PAITransitRepository>("PAI");
container.RegisterType<ITransitReport, PAITransitReport>("PAI");
container.RegisterType<ITransitReport, PPDCTransitReport>("PPDC");
然后将其注入您的
transitioninfo

public TransitInfo : ITransitInfo
{
    private ITransitReportFactory _transitReportFactory;
    public TransitInfo (ITransitReportFactory transitReportFactory)
    {
        _transitReportFactory = transitReportFactory;
    }
    public List<UserDefinedType> GetReportData (string reportType, string input1, string input2)
    {
        // Create your transitreport object.
        ITransitReport report = _transitReportFactory.Create(reportType);
        var reportData = report.GetTransitReportData (input1, input2);
        return reportData;
    }
}
public-transitioninfo:ITransitInfo
{
私营ITransitReportFactory(运输工厂);;
公共传输信息(ITransitReportFactory传输工厂)
{
_transitReportFactory=transitReportFactory;
}
公共列表GetReportData(字符串reportType、字符串input1、字符串input2)
{
//创建transitreport对象。
ITransitReport=\u transitReportFactory.Create(reportType);
var reportData=report.GetTransitReportData(input1,input2);
返回报告数据;
}
}

但是我必须说,工厂本身并没有给解决方案添加太多内容。如果您不介意服务定位器模式,您可以将
IUnityContainer
直接注入
transitioninfo

很抱歉问这个问题,但我对工厂有点困惑,我如何传递
IUnityContainer
类型和调用位置
Create
方法。你问得对。一点也不明显。我调整了答案。
public TransitInfo : ITransitInfo
{
    private ITransitReportFactory _transitReportFactory;
    public TransitInfo (ITransitReportFactory transitReportFactory)
    {
        _transitReportFactory = transitReportFactory;
    }
    public List<UserDefinedType> GetReportData (string reportType, string input1, string input2)
    {
        // Create your transitreport object.
        ITransitReport report = _transitReportFactory.Create(reportType);
        var reportData = report.GetTransitReportData (input1, input2);
        return reportData;
    }
}
public TransitReport (IPAIValidateInput inputValidation,
                        ITransitRepository transitRepo)
{
    _inputValidation = inputValidation;
    _transitRepo = transitRepo;
}
container.RegisterType<IValidateInput, PPDCValidateInput>("PPDC");
container.RegisterType<IValidateInput, PAIValidateInput>("PAI");
container.RegisterType<ITransitRepository, PPDCTransitRepository>("PPDC");
container.RegisterType<ITransitRepository, PAITransitRepository>("PAI");
container.RegisterType<ITransitReport, PAITransitReport>("PAI");
container.RegisterType<ITransitReport, PPDCTransitReport>("PPDC");
public abstract class TransitReportBase : ITrnsitReport
{
    private readonly IValidateInput _inputValidation;
    private readonly ITransitRepository _transitRepo;

    protected TransitReportBase(IValidateInput inputValidation,
                            ITransitRepository transitRepo)
    {
        _inputValidation = inputValidation;
        _transitRepo = transitRepo;
    }

    public List<UserDefinedType> GetTransitReportData(string input1, string input2)
    {
        List<UserDefinedType> ppdcReportList = null;
        bool isValid = _inputValidation.IsInputValid(input1, input2);
        if (isValid)
        {
            ppdcReportList = _transitRepo.GetTransitData(input1, input2);
            // do something with data
        }
        return ppdcReportList;
    }
}

public class PAITransitReport : TransitReportBase
{

    public PAITransitReport([Dependency("PAI")] IValidateInput inputValidation,
                            [Dependency("PAI")] ITransitRepository transitRepo) : base(inputValidation, transitRepo)
    {

    }
}

public class PPDCTransitReport : TransitReportBase
{
    public PPDCTransitReport([Dependency("PPDC")] IValidateInput inputValidation,
                            [Dependency("PPDC")] ITransitRepository transitRepo) : base(inputValidation, transitRepo)
    {

    }
}
public class TransitReportFactory : ITransitReportFactory
{
    private readonly IUnityContainer _container;

    public TransitReportFactory(IUnityContainer container) // container is injected automatically.
    {
        _container = container;
    }

    ITrnsitReport Create(string reportType)
    {
        return _container.Resolve<ITrnsitReport>(reportType);
    }
}
container.RegisterType<ITransitReportFactory, TransitReportFactory>();
public TransitInfo : ITransitInfo
{
    private ITransitReportFactory _transitReportFactory;
    public TransitInfo (ITransitReportFactory transitReportFactory)
    {
        _transitReportFactory = transitReportFactory;
    }
    public List<UserDefinedType> GetReportData (string reportType, string input1, string input2)
    {
        // Create your transitreport object.
        ITransitReport report = _transitReportFactory.Create(reportType);
        var reportData = report.GetTransitReportData (input1, input2);
        return reportData;
    }
}