1

我有一个使用ServiceStack创建的服务。我将 Funq 用于我的依赖注入,因为它默认附带 ServiceStack,但这可能是其他 DI 容器表现出的行为。

我在启动时注册我的类型:

this.AppContainer.RegisterAs<ConcreteDownloadServices, IDownloadServices>();`

我在一个类中有这个构造函数:

private readonly IDownloadServices downloadServices;

public ExampleService(IDownloadServices downloadServices)
{
    this.downloadServices = downloadServices;
}

我的具体实现的构造函数是:

public ConcreteDownloadServices()
{
    this.ArbitraryProperty = "ArbitraryString";
}

一切都解决得很好,我可以进入代码并看到事情按预期工作。但是,AbritraryProperty没有正确设置。我可以逐步查看它设置为字符串值,但是一旦代码返回到调用代码(在本例中,它将是 的构造函数ExampleServiceArbitraryProperty现在为空。

  1. 这种行为是设计使然吗?
  2. 如果是设计使然,那么使用 DI 是否意味着我不应该在具体实现的构造函数中做任何事情?
  3. 如果是设计使然,那么为自动属性设置默认值的正确方法是什么?
  4. 如果不是设计使然,那又是怎么回事?
4

2 回答 2

4

编辑:

我已经决定这不是我们想要的行为,所以我刚刚签入了一个提交,以强制 Funq 不会自动装配字符串(和 ValueType)属性。新行为将在下一个版本的 ServiceStack (v3.9.34) 中可用。

现有行为

RegisterAs 是一个 Autowired API,即:

Container.RegisterAs<ConcreteDownloadServices, IDownloadServices>();

这告诉 ServiceStack 的 IOC 使用 IOC 解决的依赖项填充每个公共属性。这因为它是一个string公共财产将尝试解决string从国际奥委会注册。用代码术语来说,这是在幕后发生的:

new ConcreteDownloadServices { 
    ArbitraryProperty = Container.TryResolve<string>()
};

因为您没有注册任何“字符串”,所以将使用null. 只有公共属性是自动连接的,因此您可以通过将其更改为受保护的私有或内部属性来避免这种行为。

否则,您可以通过注册自定义委托工厂来覆盖默认的 IOC 行为,这使您可以完全控制依赖项的构建,例如:

container.Register<IDownloadServices>(c => new ConcreteDownloadServices());
于 2013-01-24T18:21:36.117 回答
1

我们开发团队的一些成员刚刚花了一些时间调试一个类似的问题。

在我们的一个单元测试中使用的 RegisterAs 类有一个公共成员:public List Mails { get; 放; }

当此类通过 Funq 解析时,该成员被设置为 null,即使它是在构造函数中设置的。

我们的团队成员一致认为,当该成员不是注册为 Container.RegisterAs<> 的类型时,Funq 将此成员设置为 null 是很奇怪的。

我们使用的是 ServiceStack 版本 4.0.33

于 2015-02-24T14:47:12.377 回答