仅当使用Unity在运行时值不为null时,才如何注入属性? [英] How can I inject a property only if the value is non-null at runtime using Unity?

查看:151
本文介绍了仅当使用Unity在运行时值不为null时,才如何注入属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个要解析的接口,并且映射对象的一个​​依赖项上有一个属性,我想为其设置一个仅在解析顶级对象时才可用的值。

I have an interface to resolve and one of the mapped object's dependencies has a property on it which I would like to set with a value that I only have available when I resolve the top level object.

该属性没有有效的默认值。如果未设置,则应为null,并且仅当我在解析时可用的值不为null时才设置。

There's no valid default value for the property. If its not set it should be null and it should only be set if the value that I have available at resolve time is not null.

这种条件属性注入是否可能?

Is this conditional property injection possible?

我尝试了这个...

container.RegisterType<ProductInstanceValidatorBase, CartItemPurchaseTypeValidator>("CartItemPurchaseTypeValidator", new InjectionProperty("AccountEntity", null);

...但是它说我不能使用空值!

... but it said I couldn't use a null value!

我也尝试过使用此方法...

I also tried this on the resolve...

container.Resolve<ProductInstanceValidatorBase>(new PropertyOverride("AccountEntity", value));

...但是当值为null时会抛出异常。

...but this throws an exception when the value is null. It says,


参数类型推断不适用于null值,请使用正确配置的InjectionParameter或InjectionParameter cl实例显式指示参数类型驴子。
参数名称:parameterValue

Parameter type inference does not work for null values. Indicate the parameter type explicitly using a properly configured instance of the InjectionParameter or InjectionParameter classes. Parameter name: parameterValue

基本上我想注册的属性仅设置为覆盖,然后仅如果重写值不为null。有任何想法吗?当然,从语义的角度来看,属性注入应该是可选的。

Basically I'm looking to register a property that is only set with an override and then only if the override value is non-null. Any ideas? Surely from a semantic point of view, property injection should be optional.

干杯,伊恩。

推荐答案

此问题的一种潜在解决方法是实施空对象模式,当您没有有效的帐户时,传递 Account.Empty 。这是一个类的样子:

One potential fix to this problem is to implement a Null Object Pattern and pass Account.Empty when you haven't got a valid account. Here is what a class could look like:

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 并且实体框架不会抱怨。

This way the account is never null and Entity framework wouldn't complain.

但是我觉得您的系统设计可能有更大的问题。 IoC容器允许更松散的耦合系统,其中,组件的接线是在程序运行之前 定义的,而不是在运行程序 定义的。从名称来看, AccountEnyity 是实体类,而不是服务类,并且您通常不要在IoC容器中注册实体,仅服务

However I sense that you might have a larger problem with the design of the system. IoC container allows a more loosely coupled system, where the wiring of the components is defined before the program is run, not while it's run. Judging by the name, AccountEnyity is an entity class, not a service class, and you normally do not register entities with the IoC container, only services.

鉴于上述情况,我建议 AccountEntity 不应该是可注入的属性,而应该是正常财产。然后,您将 ProductInstanceValidatorBase 的创建外部化为工厂,并让它负责设置 AccountEntity 属性

In the light of the above I would suggest that AccountEntity shouldn't be an injectable property, but instead a normal property. You then externalize the ProductInstanceValidatorBase creation into a factory and let it take care of setting AccountEntity property

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

您甚至不需要注册 ProductInstanceValidatorBase 与Unity,而是注册工厂。这就是使用工厂的样子:

You don't even need to register ProductInstanceValidatorBase with Unity, but instead register the factory. This is how using the factory would look like:

Account account = null;
container.Resolve<IProductInstanceValidatorFactory>().Create(account);

这篇关于仅当使用Unity在运行时值不为null时,才如何注入属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆