繁体   English   中英

在Unity DI中使用带参数的RegisterType

[英]RegisterType with parameter in Unity DI

问题

我有一个接口IFoo,并且有不同的类实现了该接口,例如Foo1,Foo2,Foo3等。 现在,我有一个由BarService实现的服务IBarService,它在其构造函数中采用了参数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中,我可以这样做吗

首先,您的BarService构造BarService不应采用Foo1 ,而应采用IFoo ,否则Unity将不考虑您在container.RegisterType<IFoo, Foo1>();设置的任何参数container.RegisterType<IFoo, Foo1>(); 注册(如果有)(又名:该行变得无用。)

现在,当您执行container.Resolve<IBarService>() ,Unity会执行以下操作:

  1. “他想要一个IBarService 。我有什么?哦,我应该实例化BarService
  2. 我应该如何实例化BarService 我想我只会使用我看到的构造函数,但是我需要一个Foo1
  3. 我有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”的公共属性。

您没有在容器中注册类型Foo1。

 myContainer.RegisterType<Foo1>();

更多信息:Unity注册对象的默认生存期(生命周期)是瞬态的 这意味着Unity将在每次调用时创建Foo1的对象。 您应该检查单例寿命。 这是来自MSDN的代码:

myContainer.RegisterType<IMyObject, MySingletonObject>(new ContainerControlledLifetimeManager());

正如@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>();

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM