3

我有一个类 PluginProvider,它使用 PluginLoader 组件从文件系统加载插件(托管/本机)。在 PluginProvider 类中,当前定义了一个名为“PluginTypes”的属性,它调用 get() 上的“InitializePlugins”实例方法。

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,发现这个“特别是访问网络或文件系统的操作(除了一次初始化) 应该很可能是方法,而不是属性。”。现在我有点困惑。请帮忙。

4

4 回答 4

2
  • 如果您想尽可能多地延迟初始化并且您不知道何时调用您的属性(或属性),那么您正在做的事情很好。
  • 如果您想延迟并且您可以控制何时首次调用您的属性,那么您可能希望InitializePlugins()公开您的方法并在访问该属性之前显式调用它。此选项还开启了异步初始化的可能性。例如,您可以有一个InitializePluginsAsync()返回 a 的 a Task
  • 如果延迟初始化不是一个大问题,那么只需在构造函数中执行初始化。
于 2014-08-11T05:45:14.143 回答
1

这当然是口味问题。但我会做什么取决于您尝试执行的操作的长度。如果加载插件需要时间,我会创建一个公共方法,任何用户在使用该类之前都需要调用该方法。另一种方法是将方法放在构造函数中,但 IMO 构造函数应尽快返回,并应包含字段/属性初始化。

class PluginProvider
{
    private bool _isInitialized;
    IEnumerable<IPluginType> PluginTypes { get; set;}

    public void Initialize()
    {
        if (_isInitialized)
        {
             return;
        }      

        InitializePlugins();
        _isInitialized = true;  
    }
}

请注意,这样做的不利方面是您必须确保在执行任何操作之前调用了 Initialize 方法。

刚刚想到支持这种方法的另一件事是异常处理。我确定你不希望你的构造函数抛出任何类型的东西IOException,以防它无法从文件系统加载类型。

于 2014-08-11T05:38:57.467 回答
1

您在那里所做的事情称为延迟初始化。您正在推迟执行一项可能成本高昂的操作,直到需要其输出的那一刻。

现在,这不是一个绝对的规则。如果您的InitializePlugins方法需要很长时间才能完成并且可能会影响用户体验,那么您可以考虑将其移动到公共方法中,甚至将其设为异步并在属性之外调用它:在应用程序启动时或每当您找到一个好时机调用一个持久的操作。

否则,如果它是短暂的一次性事物,它可以留在那里。正如我所说,不是绝对规则。通常,这些是适用于特定情况的一些指导方针。

于 2014-08-11T05:41:47.277 回答
1

任何初始化类型的代码都应该在构造函数中完成,这样你就知道它只会被调用一次。

public class PluginProvider
{
   IEnumerable<IPluginType> PluginTypes
   {
      get
      {
        return _pluginTypes;
      }
   }

   public PluginProvider()
   {
      InitializePlugins();
   }
}
于 2014-08-11T05:27:48.107 回答