我只是在阅读控制反转 (IOC) 的内容,这让我感到困扰,它似乎让内存管理变得很痛苦。当然,似乎 ioc 主要用于垃圾收集环境(Net、Java、脚本),而我关心的是非 gc 设置。
我担心的是 IOC 在某种程度上违背了 RAII,因为我们将资源生命周期与对象生命周期分离。这种增加的复杂性不会打扰其他人吗?真正的问题是,可以使用哪些技术使事情顺利进行?
我只是在阅读控制反转 (IOC) 的内容,这让我感到困扰,它似乎让内存管理变得很痛苦。当然,似乎 ioc 主要用于垃圾收集环境(Net、Java、脚本),而我关心的是非 gc 设置。
我担心的是 IOC 在某种程度上违背了 RAII,因为我们将资源生命周期与对象生命周期分离。这种增加的复杂性不会打扰其他人吗?真正的问题是,可以使用哪些技术使事情顺利进行?
正是出于这个原因,我制作了自己的 IoC 容器,它返回(在 C#/.NET 中)一次性服务包装器,当处理这些包装器时,将在服务方面“做正确的事情”。
就这样吧:
这意味着使用我的服务的所有代码都在一个 using 块内,但意图更清楚,至少对我来说:
using (var service = container.Resolve<ISomeService>())
{
service.Instance.SomeMethod();
}
基本上它说:解析服务,在服务实例上调用 SomeMethod,然后处置服务。
由于消费者不知道是否处置服务实例,因此要么完全忽略 IDisposable 实现,要么处置所有实现 IDisposable 的服务。这对我来说都不是一个好的解决方案。第三种选择是将服务实例包装在一个对象中,一旦包装器被处理掉,该对象就知道如何处理该服务。
是和不是。IoC 不会将资源生命周期与对象生命周期解耦,它会将方法调用范围与对象生命周期解耦——您通常希望在方法结束时被销毁的对象存在,直到进行另一个 IoC 调用。因此,您要么必须将方法的局部变量移动到类范围中,并确保没有方法是可重入的,要么采用另一种方法,例如传递一个额外的“环境”以允许对象归其所有并销毁在随后的 IoC 方法调用中。如果你想要一个通用的事件驱动系统,这两种方法都会变得相当复杂——要么你的模型最终不得不自己实现显式递归和迭代,亲属代替。
我首先想到的是 SmartPointers。和模板参数。但我不确定模板参数是否算作 IOC 技术,尽管我认为它们应该。至少这些可以缓解国际奥委会的一些问题,但并没有完全相信这个想法。