9

有时,我发现自己处于仅在满足特定条件时才需要解决服务的情况。例如,用户可能选择发送电子邮件或短信通知。我想根据用户的选择延迟加载电子邮件或短信服务,这样我就不必同时加载它们并浪费资源(例如,如果用户有 10 个选项...? )。

我遇到的问题是在我的引导代码之外使用容器(我不希望我的代码依赖于容器)。我似乎找不到将容器用于延迟加载服务的方法(除非我手动创建所需的服务并手动执行所有 DI)。这是可以改变规则的情况还是有更好的方法?

4

3 回答 3

5

如果您使用的是 Castle Windsor 3.0 或更新版本,您可以使用惰性解析。

有关详细信息,请参阅Windsor 3 中的新增功能

注册过程有一点变化(必须注册新的组件加载器)。

之后,您只是像往常一样注册组件,但将依赖项解析为Lazy<T>而不是T. 除非您不访问.Value的属性Lazy<T>,否则不会解决依赖关系,因此您可以传递一些惰性评估的对象,并仅在需要时访问您需要的对象。

如果您对用户有更多选择,也许您应该考虑创建某种抽象工厂接口。然后,您将只注册并解析该工厂,工厂本身将创建适当的服务来发送通知(无论是邮件、短信还是任何其他选项)。工厂的实现可以手动编码,或者您可以用 Castle Windsor 编码(我认为是从 3.0 版开始)。

通常当我确实使用这样的工厂时,我会手动实现它并将容器作为它的依赖项传递,所以只有工厂实现依赖于我的容器。

于 2012-12-26T15:36:56.907 回答
3

只是一个简化的例子(基于 Marcin Deptuła 的回答)

// activate Lazy initialization feature  for all Components
.Register(Component.For<ILazyComponentLoader>().ImplementedBy<LazyOfTComponentLoader>())     
// register rest of component(s)
.Register(Component.For<IIssueRepository>().ImplementedBy<IssueRepository>()) 
. ....

懒惰地解决(属性注入)

public Lazy<IIssueRepository> IssueRepository { get; set; }
IssueRepository.Value.GetLastIssue();

解析正常(属性注入)

public IIssueRepository IssueRepository { get; set; }
IssueRepository.GetLastIssue();
于 2013-08-21T05:04:46.763 回答
1

通常,您可以使用Typed Factory Facility来做到这一点。

简而言之,当您解析使用这些服务的组件时,不是给它一个电子邮件或短信服务,而是给它一个可以创建它们的工厂(由您定义,不引用容器)

该设施将负责“实现”您的工厂(从您创建的界面),因此几乎没有什么可做的。

于 2012-12-26T15:37:51.257 回答