简体   繁体   English

在温莎城堡使用临时工厂

[英]Using transient factories in Castle Windsor

If you use the TypedFactoryFacility in Windsor to generate factories for you based on an interface, the factory itself can be registered as Transient. 如果您使用Windsor中的TypedFactoryFacility根据接口为您生成工厂,则工厂本身可以注册为Transient。 It turns out that the factory will then release all transient objects that it created when the factory itself is disposed after release. 事实证明,工厂将在释放后处置工厂本身时释放它创建的所有临时对象。

container.AddFacility<TypedFactoryFacility>();
container.Register(
    Types.FromThisAssembly().BasedOn<IFactory>().Configure(
        x => x.AsFactory()).LifestyleTransient());

This means that if I create the auto-generated factories as transient it neatly allows me to forget about Release ing the object created from the factory (as long as I manage the lifetime of the factory itself, of course). 这意味着,如果我将自动生成的工厂创建为临时工厂,那么它可以使我完全忘记Release从工厂创建的对象(当然,只要我管理工厂本身的生命周期即可)。 The lifetime of such a transient factory would be tied to some other transient object, so when that object gets released, the factory is released, and everything that factory created. 这样的瞬态工厂的生存期将与其他瞬态对象相关联,因此,当释放该对象时,工厂将被释放,并且工厂创建的所有内容都将被释放。

Personally, I hate having to remember to explicitly Release() objects, and this cleans up the code a lot, so this makes me very happy. 就我个人而言,我讨厌不得不记住显式地Release()对象,这可以清理很多代码,因此这让我感到非常高兴。 But the question is: Is this reasonable practice? 但是问题是:这是合理的做法吗? It all just seems too easy. 这一切似乎太简单了。

Is there a downside to creating a new factory instance each time a factory is required? 每次需要工厂时创建新工厂实例都有不利之处吗?

Am I digging myself a terrible hole? 我在挖一个可怕的洞吗?

So the deeper question is related to IDisposable. 因此,更深层的问题与IDisposable有关。 Why are you using it? 你为什么要用它? Are you really keeping track of unmanaged/limited resources? 您是否真的在跟踪不受管理/有限的资源? Are you using it to really dispose something or as a shutdown protocol? 您是使用它来真正处置某些东西还是将其作为关闭协议?

All these will go away if you change Windsor's release policy -- thus making you take care of when/if [to] call dispose. 如果您更改了Windsor的发布政策,所有这些都将消失-因此使您可以(何时)致电处置。 The container is trying to help you by keeping track of what and when to dispose things, but it can only do so much, so sometimes it's better to step up and take over the responsibility. 容器试图通过跟踪处置内容和时间来帮助您,但是它只能做很多事情,因此有时最好加紧责任。

Another option is to turn off the tracking and expose a service that keeps track of things to dispose. 另一个选择是关闭跟踪并公开跟踪要处理的事物的服务。 This can be more semantical and understand your business/infrastructure needs. 这可以更加语义化并了解您的业务/基础架构需求。

In sum: what you're doing is fine, but it's not all that common to instantiate a transient factory every time you need the factory to create something. 总而言之:您正在做的事情很好,但是每次需要工厂创建实例时实例化一个临时工厂并不是所有常见的事情。 Make sure you document this for the your own future self. 确保为自己将来的自己记录下来。

The automatic factory mechanism in Castle is based on Castle.DynamicProxy; Castle中的自动工厂机制基于Castle.DynamicProxy; I imagine that if you use the factory as a transient component you have to pay for the creation of the ProxyGenerator at each resolution, unless some other caching mechanism exists. 我想像一下,如果您将工厂用作临时组件,则ProxyGenerator为每种分辨率下的ProxyGenerator创建付出代价,除非存在其他某种缓存机制。

The documentation warns against recreating the the ProxyGenerator each time: 文档警告您不要每次都重新创建ProxyGenerator

If you have a long running process (web site, windows service, etc.) and you have to create many dynamic proxies, you should make sure to reuse the same ProxyGenerator instance. 如果您的进程运行时间较长(网站,Windows服务等),并且必须创建许多动态代理,则应确保重用相同的ProxyGenerator实例。 If not, be aware that you will then bypass the caching mechanism. 如果不是,请注意您将绕过缓存机制。 Side effects are high CPU usage and constant increase in memory consumption 副作用是高CPU使用率和不断增加的内存消耗

However it is entirely possible that there is some mechanism that prevents this problem in Windsor, or that the documentation is obsolete. 但是,完全有可能在Windsor中有某种机制可以防止此问题,或者文档已过时。

My recommendation: test with a loop on your transient factory resolution, then resolve your component; 我的建议:对您的瞬态出厂分辨率进行循环测试,然后解析您的组件; keep an eye on memory (also loaded assemblies; maybe the proxied code is loaded in a side assembly) and processor usage to determine whether or not your trick is viable 密切关注内存(也加载了程序集;可能将代理代码加载到了侧面程序集中)和处理器使用情况,以确定技巧是否可行

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

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