C# 依赖注入-将参数传递给构造的类型
我正在我的项目中引入依赖注入。我有一个对话框窗口,可以作为新实体或现有实体的编辑器。其ViewModel如下所示:C# 依赖注入-将参数传递给构造的类型,c#,parameters,constructor,dependency-injection,unity-container,C#,Parameters,Constructor,Dependency Injection,Unity Container,我正在我的项目中引入依赖注入。我有一个对话框窗口,可以作为新实体或现有实体的编辑器。其ViewModel如下所示: public class ContractWindowViewModel { private IRepository<Contract> contractRepository; private Contract model; private bool isNew; public ContractWindowViewModel(Contr
public class ContractWindowViewModel
{
private IRepository<Contract> contractRepository;
private Contract model;
private bool isNew;
public ContractWindowViewModel(Contract contract, IRepository<Contract> contractRepository)
{
if (contract == null)
throw new ArgumentNullException(nameof(contract));
if (contractRepository == null)
throw new ArgumentNullException(nameof(contractRepository));
this.contractRepository = contractRepository;
this.model = contract;
this.isNew = false;
}
public ContractWindowViewModel(IRepository<Contract> contractRepository)
{
this.contractRepository = contractRepository;
this.model = new Contract();
this.isNew = true;
}
// (...)
}
公共类合同WindowViewModel
{
私人电子储存库;
私人合同模式;
私有布尔是新的;
public ContractWindowViewModel(合同、IRepository contractRepository)
{
如果(合同==null)
抛出新的异常(合同名称);
如果(contractRepository==null)
抛出新ArgumentNullException(nameof(contractRepository));
this.contractRepository=contractRepository;
该模型=合同;
this.isNew=false;
}
public ContractWindowViewModel(IRepository contractRepository)
{
this.contractRepository=contractRepository;
this.model=新合同();
this.isNew=true;
}
// (...)
}
计划是注入
IRepository
。但有时我需要将合同
传递给ViewModel(如果我想编辑现有的),或者不传递给ViewModel(如果我想创建新的)。我应该如何使用Unity来实现这一点?可能是这样的
unityContainer.Resolve<ContractWindowViewModel>(
new ResolverOverride[] {
new ParameterOverride("contract", new Contract()),
new ParameterOverride("contractRepository", new Repository<Contract>())
});
unityContainer.Resolve(
新罗维瑞德[]{
新参数覆盖(“合同”,新合同()),
新参数覆盖(“contractRepository”,new Repository())
});
来源
使用代码中的DI容器(例如在按钮事件处理程序中)称为服务位置和 相反,您应该有一个工厂,允许您从按钮处理程序(或ViewModel命令)内部创建视图模型 以下是一个工厂的示例:
public interface IContractWindowViewModelFactory
{
ContractWindowViewModel CreateForNewContract();
ContractWindowViewModel CreateForExistingContract(Contract existing_contract);
}
public class ContractWindowViewModelFactory : IContractWindowViewModelFactory
{
private readonly IRepository<Contract> m_Repository;
public ContractWindowViewModelFactory(IRepository<Contract> repository)
{
m_Repository = repository;
}
public ContractWindowViewModel CreateForNewContract()
{
return new ContractWindowViewModel(m_Repository);
}
public ContractWindowViewModel CreateForExistingContract(Contract existing_contract)
{
return new ContractWindowViewModel(existing_contract, m_Repository);
}
}
在处理程序中,您可以将其用于新合同:
var viewmodel_for_new = container.Resolve<ContractWindowViewModel>("ForNew");
Contract existing_contract = ...
var viewmodel_for_existing = container.Resolve<ContractWindowViewModel>(
"ForExisting",
new ParameterOverride("contract", existing_contract));
var viewmodel_for_new=container.Resolve(“ForNew”);
或者,对于现有合同:
var viewmodel_for_new = container.Resolve<ContractWindowViewModel>("ForNew");
Contract existing_contract = ...
var viewmodel_for_existing = container.Resolve<ContractWindowViewModel>(
"ForExisting",
new ParameterOverride("contract", existing_contract));
现有合同\u合同=。。。
var viewmodel_for_existing=container.Resolve(
“前世的”,
新参数覆盖(“合同”,现有合同);
应用程序运行时,您需要能够稍后创建此视图模型,对吗?例如,当用户单击某个按钮时?也许根据用户单击的按钮,您将决定调用哪个构造函数,对吗?您不应该让ViewModel直接与存储库对话,而应该让它仅依赖于合同
类吗?为什么您需要知道合同
是否是新的?@YacoubMassad当然,但按钮单击处理程序将调用unityContainer.Resolve()
。如何通过该构造传递参数?问题的根源在于将运行时数据(合同实例)注入组件的构造(本例中的合同WindowViewModel)中。您的对象图应该是无状态的,运行时数据应该使用方法调用通过现有的对象图传递。任何时候你违背了这个想法,你就会让一切变得更加困难(正如你已经经历过的那样)。因此,不要使用构造函数注入契约
,而是在视图模型上定义一个允许设置现有契约的方法。