在框架中使用 Func 代替实例
当查看几个项目的源代码时,我发现了一个我不太理解的模式。 例如在 FubuMVC 和 公共服务定位器 a Func
在静态提供者更改时使用。 谁能解释一下使用:
private static Func<IServiceLocator> currentProvider;
public static IServiceLocator Current
{
get { return currentProvider(); }
}
public static void SetLocatorProvider(Func<IServiceLocator> newProvider)
{
currentProvider = newProvider;
}
而不是:有什么好处?
private static IServiceLocator current;
public static IServiceLocator Current
{
get { return current; }
}
public static void SetLocator(IServiceLocator newInstance)
{
current = newInstance;
}
When looking at the source code of a couple of projects I found a pattern I can not quite understand.
For instance in FubuMVC and Common Service Locator a Func
is used when a static provider is changed.
Can anyone explain what the benefit is of using:
private static Func<IServiceLocator> currentProvider;
public static IServiceLocator Current
{
get { return currentProvider(); }
}
public static void SetLocatorProvider(Func<IServiceLocator> newProvider)
{
currentProvider = newProvider;
}
instead of:
private static IServiceLocator current;
public static IServiceLocator Current
{
get { return current; }
}
public static void SetLocator(IServiceLocator newInstance)
{
current = newInstance;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
第一个模型相对于第二个模型的主要优点是所谓的“延迟初始化”。在第二个示例中,一旦调用 SetLocator,您就必须将 IServiceLocator 实例加载到内存中并准备就绪。如果创建此类实例的成本很高,和/或与一堆其他对象一起创建(例如在应用程序启动时),那么最好尝试延迟对象的实际创建以减少对用户的明显延迟。另外,如果依赖类可能不使用依赖项(假设它只用于某些操作,并且该类可以执行不需要依赖项的其他操作),则实例化一个依赖项将是一种浪费。
解决方案是提供“工厂方法”而不是实际实例。当实际需要实例时,会调用工厂方法,并在使用前的最后一刻创建实例。这减少了前端加载时间并避免创建不需要的依赖项。
The major advantage of the first model over the second is what's called "lazy initialization". In the second example, as soon as SetLocator is called, you must have an IServiceLocator instance loaded in memory and ready to go. If such instances are expensive to create, and/or created along with a bunch of other objects at once (like on app startup), it's a good idea to try to delay actual creation of the object to reduce noticeable delays to the user. Also, if the dependency may not be used by the dependent class (say it's only needed for certain operations, and the class can do other things that don't require the dependency), it would be a waste to instantiate one.
The solution is to provide a "factory method" instead of an actual instance. When the instance is actually needed, the factory method is called, and the instance is created at the last possible moment before it's used. This reduces front-end loading times and avoids creating unneeded dependencies.
@KeithS 的回答很好。这里需要注意的另一件事是在某些实例的初始化背后发生的事情。保留对故意易失性对象的引用可能很棘手。
例如,FubuMVC 针对每个 HTTP 请求启动一个嵌套的 StructureMap 容器,该容器将所有服务位置限制在该特定请求范围内。如果您有在已构建的管道中运行的类,您将需要使用通过 IServiceLocator 的该实例提供的上下文注入。
Good answer by @KeithS. Another thing to note here is what happens under the covers of the initialization of certain instances. Keeping a reference to intentionally volatile objects can be tricky.
FubuMVC, for instance, spins up a nested StructureMap container per HTTP request which scopes all service location to that specific request. If you have classes running within that pipeline that have been built up, you'll want to use the contextual injection provided to you via THAT instance of IServiceLocator.
newProvider 的实现者有更多的灵活性。他们可以延迟加载、异步加载(然后,如果在调用 func 时尚未加载,则可以有代码等待),他们可以允许它根据运行时参数等进行更改。
Theres a lot more flexibility to the implementer of newProvider. They can lazy load, async load (and and then if it's not loaded by the time the func is called it can have code to wait), they can allow it change based on runtime parameters etc.
func 允许执行多种操作
我相信设计师所做的可以给你比我更多的观点,为什么抽象出“简单”的东西(比如返回服务定位器的实例)是一个好主意。
你的,
阿洛伊斯·克劳斯
A func allows several things
I am sure the designers did could give you more points than I did why it can be a good idea to abstract away "simple" things like to return an instance of a service locator.
Yours,
Alois Kraus