我有一个接口IFoo,并且有不同的类实现了这个接口,如Foo1,Foo2,Foo3等。现在我有一个服务IBarService,由BarService实现,它的构造函数中有一个参数Foo1。
public class BarService : IBarService
{
private readonly Foo1 _foo1;
public BarService (Foo1 foo1)
{
this._foo1 = foo1; // foo1 this parameter value is not loaded
}
public virtual string SomeFunction()
{
var value =_foo1.x; //This value is empty
}
}
现在我的问题是如何注册它。现在我正在这样做。
container.RegisterType<IFoo , Foo1>();
container.RegisterType<IBarService, BarService >();
此代码在管理期间使用空值实例化foo1我正在更新Foo1属性但它没有在BarService中注入。我怎样才能做到这一点?
此外,我的IFoo界面正在关注
public interface IFoo
{
}
它由其他类实现,如
public class Foo1: IFoo
{
public bool X{ get; set; }
public string Y{ get; set; }
public List<string> Z{ get; set; }
}
在unityconfig中注册类时我正在从数据库加载所有Foo1值并进行设置。在这一点上,每一个都工作正常但现在我希望Foo1类在BarService中注入加载的值。
我想将构造函数参数注入到带有预加载值的BarService中,我可以这样做吗
答案 0 :(得分:1)
首先,BarService
的构造函数不应该使用Foo1
,而是应该使用IFoo
,否则Unity将不会考虑您设置的任何参数在container.RegisterType<IFoo, Foo1>();
注册中,如果有的话(也就是:那条线变得无用。)
现在,当你container.Resolve<IBarService>()
时,Unity所做的是:
IBarService
。我有什么?哦,我应该实例化一个BarService
!BarService
?我想我只会使用我看到的构造函数,但我需要Foo1
。Foo1
的食谱吗?没有?好吧,我将使用我的公共构造函数。 由于它是默认构造函数,因此不会设置任何属性。 我看到了两个问题的解决方案:
1)向另一个生命周期管理器注册Foo,并修改对象。
container.RegisterType<IFoo, Foo>(new ContainerControlledLifetimeManager());
如果你以这种方式注册foo,一旦它被解析,它将始终返回相同的实例。然后,您可以修改它,并且更改将保持不变。
2)使用构造覆盖注册Foo。
container.RegisterType<IFoo, Foo>(
new InjectionProperty("X", valueOfX),
new InjectionProperty("Y", valueOfY),
new InjectionProperty("Z", valuesOfZ));
有了这个,一旦Foo被实例化,将设置名为“X”,“Y”,“Z”的公共属性。
答案 1 :(得分:0)
您没有在容器中注册Foo1类型。
myContainer.RegisterType<Foo1>();
更多信息: Unity注册对象的默认生命周期(生活方式)是 transient 。这意味着Unity将在每次调用时创建Foo1的 new 对象。 你应该检查单身寿命。这是来自MSDN的代码:
myContainer.RegisterType<IMyObject, MySingletonObject>(new ContainerControlledLifetimeManager());
答案 2 :(得分:0)
正如@Tipx指出的那样,
public BarService (Foo1 foo1)
应改为
public BarService (IFoo foo1)
使用任何形式的依赖注入。在此之前,集装箱登记没有任何区别。
或者你的意思是以这种方式将Foo1作为参数:
private readonly IFoo _foo;
public BarService (Foo1 foo1)
{
this._foo = foo1;
}
这也是有效的,在这种情况下,IFoo仍然不需要容器注册。
如果您真的打算进行依赖注入,那么应该如何完成。
public class BarService : IBarService
{
private readonly IFoo _foo;
public BarService(IFoo foo)
{
this._foo = foo;
}
}
在容器注册中,您可以继续将解析类型更改为任何具体类Foo1,Foo2或Foo3。
container.RegisterType<IFoo , Foo1>();
或
container.RegisterType<IFoo , Foo2>();
如果仍然是空值,在遵循合适的方法后,请发布更多代码,这将有助于我们理解为什么它为空。我尝试了上面的代码,正确的值即将到来。