我有一个要解析的接口,其中一个映射对象的依赖项上有一个属性,我想设置一个值,当我解析顶级对象时,我只能使用它。
该属性没有有效的默认值。如果未设置,则它应为null,并且只有在解析时可用的值不为空时才应设置它。
这种条件属性注入是否可行?
我试过了......
container.RegisterType<ProductInstanceValidatorBase, CartItemPurchaseTypeValidator>("CartItemPurchaseTypeValidator", new InjectionProperty("AccountEntity", null);
...但它说我不能使用空值!
我也在解决问题上尝试了这个......
container.Resolve<ProductInstanceValidatorBase>(new PropertyOverride("AccountEntity", value));
...但是当值为null时抛出异常。它说,
参数类型推断不适用于空值。使用正确配置的InjectionParameter或InjectionParameter类实例显式指示参数类型。 参数名称:parameterValue
基本上我想要注册一个仅使用覆盖设置的属性,然后才会覆盖覆盖值为非null。有任何想法吗?当然,从语义的角度来看,属性注入应该是可选的。
干杯,伊恩。
答案 0 :(得分:5)
此问题的一个可能解决方法是在您没有有效帐户时实施Null Object Pattern并传递Account.Empty
。这是课程的样子:
public class Account {
public static readonly Account Empty = new Account();
}
//at resolution time
Account account = null;
if (HasAccount)
account = GetAccount();
else
account = Account.Empty;
container.Resolve<ProductInstanceValidatorBase>(new PropertyOverride("AccountEntity", account));
这样,帐户永远不会null
,实体框架也不会抱怨。
但是我觉得你的系统设计可能会遇到更大的问题。 IoC容器允许更松散耦合的系统,其中组件的布线在>> 程序运行之前定义,而不是而运行。从名称来看,AccountEnyity
是一个实体类,而不是一个服务类,你通常不用IoC容器注册实体,只注册服务。
鉴于上述情况,我建议AccountEntity
不应该是注射财产,而是普通财产。然后,您将ProductInstanceValidatorBase
创建外部化为工厂,并让它负责设置AccountEntity
属性
public interface IProductInstanceValidatorFactory{
ProductInstanceValidatorBase Create(Account account);
}
public class ProductInstanceValidatorFactory : IProductInstanceValidatorFactory{
public ProductInstanceValidatorBase Create(Account account){
var validator = new ProductInstanceValidator();
validator.AccountEnity = account;
return validator;
}
}
您甚至不需要向Unity注册ProductInstanceValidatorBase
,而是注册工厂。这就是使用工厂的样子:
Account account = null;
container.Resolve<IProductInstanceValidatorFactory>().Create(account);
答案 1 :(得分:4)
您可以将InjectionParameter
与空值一起使用,但必须指定类型。
对于您的两个场景,我假设您的AccountEntity参数属于类型或派生自IAccount:
container.RegisterType<ProductInstanceValidatorBase, CartItemPurchaseTypeValidator>("CartItemPurchaseTypeValidator", new InjectionProperty<IAccount>(null);
请注意,我删除了名称,因为在上面的场景中并不是特别需要,但下面的场景需要它。
container.Resolve<ProductInstanceValidatorBase>(new PropertyOverride("AccountEntity", new InjectionProperty<IAccount>(null)));
答案 2 :(得分:-1)
我倾向于同意伊戈尔。但是,如果您绝对必须解析Entity
,为什么不将您的IoC容器作为构造函数依赖项,然后尝试在构造函数中Resolve
?