gpt4 book ai didi

c# - 依赖注入(inject) - 将参数传递给构造类型

转载 作者:太空狗 更新时间:2023-10-29 23:13:43 28 4
gpt4 key购买 nike

我正在为我的项目引入依赖注入(inject)。我有一个对话框窗口,它充当新实体或现有实体的编辑器。它的 ViewModel 如下所示:

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

// (...)
}

计划是注入(inject)IRepository<Contract> .但有时我需要通过 Contract到 ViewModel(如果我想编辑现有的)或不(如果我想创建新的)。我应该如何使用 Unity 做到这一点?

最佳答案

使用代码中的 DI 容器(例如在按钮事件处理程序中)称为服务位置和 is considered to be an anti-pattern .

您应该拥有一个允许您从按钮处理程序(或您的 ViewModel 命令)内部创建 View 模型的工厂。

这是一个工厂的例子:

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

现在你需要注入(inject)IContractWindowViewModelFactory进入需要能够创建 ContractWindowViewModel 的类查看模型(例如,通过构造函数注入(inject))。

由于您使用的是 DI 容器,因此需要注册 IContractWindowViewModelFactoryContractWindowViewModelFactoryComposition Root .您还需要注册 IRepository<Contract> (我猜你已经完成了)。

现在,在您的按钮处理程序(或命令处理程序)中,您可以使用工厂创建一个 ContractWindowViewModel对于新的或现有的 Contract .

如果出于某种原因,您仍然想使用按钮处理程序中的容器(我鼓励您不要这样做),那么您可以使用named registrations像这样:

在你的组合根目录中:

container.RegisterType<ContractWindowViewModel>(
"ForNew",
new InjectionConstructor(
new ResolvedParameter<IRepository<Contract>>()));

container.RegisterType<ContractWindowViewModel>(
"ForExisting",
new InjectionConstructor(
new ResolvedParameter<Contract>(),
new ResolvedParameter<IRepository<Contract>>()));

在您的处理程序中,您可以将其用于新契约(Contract):

var viewmodel_for_new = container.Resolve<ContractWindowViewModel>("ForNew");

或者对于现有契约(Contract):

Contract existing_contract = ...
var viewmodel_for_existing = container.Resolve<ContractWindowViewModel>(
"ForExisting",
new ParameterOverride("contract", existing_contract));

关于c# - 依赖注入(inject) - 将参数传递给构造类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33065104/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com