我有一个类PluginProvider,它使用PluginLoader组件从文件系统加载插件(托管/本机)。在PluginProvider类中,当前定义了一个名为' PluginTypes'它调用了“InitializePlugins”' get()的实例方法。
class PluginProvider
{
IEnumerable<IPluginType> PluginTypes
{
get
{
//isInitialized is set inside InitializePlugins method
if(!isInitialized)
{
InitializePlugins(); //contains thread safe code
}
//_pluginTypes is set within InitializePlugins method
return _pluginTypes;
}
}
}
我正在考虑重构这段代码。我想知道在属性中这种初始化是否正常。我知道不能在财产中进行繁重的操作。但当我查看此链接时:http://msdn.microsoft.com/en-us/library/vstudio/ms229054.aspx,发现了这个&#34;特别是,访问网络或文件系统的操作(不是一次初始化)应该很可能是方法,而不是属性。&#34;。现在我有点困惑。请帮忙。
答案 0 :(得分:2)
InitializePlugins()
并在访问该属性之前显式调用它。此选项还可以异步初始化。例如,您可以使用InitializePluginsAsync()
返回Task
。答案 1 :(得分:1)
任何初始化类型的代码都应该在构造函数中完成,这样你知道它只会被调用一次。
public class PluginProvider
{
IEnumerable<IPluginType> PluginTypes
{
get
{
return _pluginTypes;
}
}
public PluginProvider()
{
InitializePlugins();
}
}
答案 2 :(得分:1)
这当然是品味问题。但我会做什么取决于你尝试执行的操作的长度。如果加载插件需要时间,我会创建一个公共方法,任何用户在使用该类之前都需要调用它。另一种方法是将方法放在构造函数中,但IMO构造函数应该尽快返回并且应该包含字段/属性初始化。
class PluginProvider
{
private bool _isInitialized;
IEnumerable<IPluginType> PluginTypes { get; set;}
public void Initialize()
{
if (_isInitialized)
{
return;
}
InitializePlugins();
_isInitialized = true;
}
}
请注意,这方面的缺点是您必须确保在执行任何操作之前调用Initialize方法。
支持这种方法的另一件事是异常处理。我确定你不希望你的构造函数抛出任何类型IOException
,以防它无法从文件系统加载类型。
答案 3 :(得分:1)
你在做什么叫做延迟初始化。你推迟进行可能代价高昂的操作,直到需要输出为止。
现在,这不是一个绝对的规则。如果您的InitializePlugins
方法需要很长时间才能完成并且可能会影响用户体验,那么您可以考虑将其移动到公共方法中,甚至将其设置为异步并在属性之外调用它:在应用启动时或每当您找个好时机来做一个持久的操作。
否则,如果它是一个短暂的一次性事物,它可以留在那里。正如我所说,不是绝对的规则。通常,这些是适用于特定情况的一些指导原则。