我对 Unity BuildUp 方法有一个奇怪的问题。我有一个映射到三个类的接口。我已经为每个映射命名。
现在我需要在现有对象中注入依赖项(它是一个属性,所以我无法控制生命周期)。我调用 BuildUp 方法来注入依赖项,但它总是抛出一个异常,指出接口未映射。
如果我仅将接口映射到一种类型并删除映射名称,则 BuildUp 方法有效。如果我仅将接口映射到一种类型并指定映射名称,则 BuildUp 方法将失败。我尝试在配置和代码中注册类型,但没有任何变化。
我怀疑这是一个错误,但我想知道是否有其他人有其他想法。
这就是我称之为建立方法的方式:
var newAttr = _container.BuildUp(myAttribute.GetType(), myAttribute, "Mapping1");
我试图遵循您的方案,此示例有效
var container = new UnityContainer();
container.RegisterType<IFoo, One>("1", new InjectionProperty("Bar", "1"));
container.RegisterType<IFoo, Two>("2", new InjectionProperty("Bar", "2"));
container.RegisterType<IFoo, Three>("3", new InjectionProperty("Bar", "3"));
One one = new One();
container.BuildUp(one.GetType(), one, "1");
Assert.AreEqual("1", one.Bar);
public interface IFoo
{
string Bar { get; set; }
}
public class One : IFoo
{
public string Bar { get; set; }
}
public class Two : IFoo
{
public string Bar { get; set; }
}
public class Three : IFoo
{
public string Bar { get; set; }
}
更新
var container = new UnityContainer();
container.RegisterType<Person>(new InjectionProperty("Foo"));
container.RegisterType<IFoo, One>("1");
container.RegisterType<IFoo, Two>("2");
container.RegisterType<IFoo, Three>("3");
Person person = container.Resolve<Person>("1");
Assert.IsNotNull(person.Foo);
Assert.IsInstanceOfType(person.Foo, typeof(One));
public class Person
{
public IFoo Foo { get; set; }
}
我想这就是你的意思?简短回答:这不是 Unity 的工作方式。
长答案:您必须指定一个为您执行此操作的ResolverOverride
。但即使这样也不够,因为您希望容器创建要为您注入的值。因此,您需要指定一个ResolvedParameter
作为ResolverOverride
的值。使用Unity的开箱即用部件,Resolve
看起来像这样
Person person = container.Resolve<Person>(new PropertyOverride("Foo", new ResolvedParameter(typeof(IFoo), "1")));
或者,您可以改用此自定义覆盖
public class NamedPropertyOverride : ResolverOverride
{
private readonly string propertyName;
private readonly string registrationName;
public NamedPropertyOverride(string propertyName, string registrationName)
{
this.propertyName = propertyName;
this.registrationName = registrationName;
}
public override IDependencyResolverPolicy GetResolver(IBuilderContext context, Type dependencyType)
{
var currentOperation = context.CurrentOperation as ResolvingPropertyValueOperation;
if (currentOperation != null &&
currentOperation.PropertyName == this.propertyName)
{
Type propertyType = currentOperation
.TypeBeingConstructed
.GetProperty(currentOperation.PropertyName, BindingFlags.Instance | BindingFlags.Public)
.PropertyType;
return new NamedTypeDependencyResolverPolicy(propertyType, this.registrationName);
}
return null;
}
}
将上述示例中包含调用 to Resolve
的行更改为此行
Person person = container.Resolve<Person>(new NamedPropertyOverride("Foo", "1"));
这应该可以解决问题。