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;
}
}