RegisterType与Unity DI中的参数

时间:2017-05-16 21:30:32

标签: c# asp.net-mvc-5 unity-container

问题

我有一个接口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中,我可以这样做吗

3 个答案:

答案 0 :(得分:1)

首先,BarService的构造函数不应该使用Foo1,而是应该使用IFoo,否则Unity将不会考虑您设置的任何参数在container.RegisterType<IFoo, Foo1>();注册中,如果有的话(也就是:那条线变得无用。)

现在,当你container.Resolve<IBarService>()时,Unity所做的是:

  1. “他想要一个IBarService。我有什么?哦,我应该实例化一个BarService
  2. 我应该如何实例化BarService?我想我只会使用我看到的构造函数,但我需要Foo1
  3. 我有Foo1的食谱吗?没有?好吧,我将使用我的公共构造函数。 由于它是默认构造函数,因此不会设置任何属性。
  4. 我看到了两个问题的解决方案:

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

如果仍然是空值,在遵循合适的方法后,请发布更多代码,这将有助于我们理解为什么它为空。我尝试了上面的代码,正确的值即将到来。