c#与Repository相关的设计模式

本文关键字:设计模式 Repository | 更新日期: 2023-09-27 18:21:18

我有一个在C#托管层中工作的存储库类,比如调用FileRepository()。有一个方法调用LoadRecordFromFile(),它访问C++非托管COM DLL以加载大量记录,如图所示:

LoadRecordFromFile()
{
     for (uint index = 1; index <= this.File.Count; index++)
     {
      // create new record object here
     }
}

记录对象中的信息稍后将用于生成AnalysisViewModel对象。因此,还有另一个for循环用于生成AnalysisViewModel对象的集合,然后才能在视图中使用该集合进行显示。

问题是第二个for循环使用了大量的加载时间。我试图通过在LoadRecordFromFile()中使用一个for循环来替换两个for循环,从而优化加载时间。即在FileRepository类的LoadRecordFromFile()中的for循环中同时创建记录对象和AnalysisViewModel()对象。然而,它打破了存储库设计模式的封装。请有人提出如何重新设计两个类(AnalysisVeiwModel和FileRepository),以实现只使用一个for循环来减少文件加载时间?感谢

c#与Repository相关的设计模式

创建一个自定义枚举器,包装对COM dll的API调用。

首先声明您的集合。集合只是创建枚举器的包装器:

public class MyCustomCollection : IEnumerable<YouRecordType>
{
    private readonly string _fileName;
    public MyCustomCollection(string fileName)
    {
        if (fileName == null) throw new ArgumentNullException(nameof(fileName));
        _fileName = fileName;
    }
    public IEnumerator<YouRecordType> GetEnumerator()
    {
        return new MyCustomEnumerator(_fileName);
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

集合应该由您的存储库返回。

枚举器本身就是使用COM对象的类:

public class MyCustomEnumerator : IEnumerator<YouRecordType>
{
    private readonly string _fileName;
    private int _index;
    YouRecordType _current;
    public MyCustomEnumerator(string fileName)
    {
        _fileName = fileName;
        //open COM object here
    }
    public void Dispose()
    {
        //Dispose used COM resources.
    }
    public bool MoveNext()
    {
        //Read next row from the COM object
        var couldReadAnotherRow = true;
        _current = null; //comObject.Read(_index++); 
        return couldReadAnotherRow;
    }
    public void Reset()
    {
        //want to start over
    }
    public YouRecordType Current { get { return _current; } }
    object IEnumerator.Current
    {
        get { return Current; }
    }
}

您可以将其视为一个懒惰加载的集合。即在调用行之前不加载行。

因此,从存储库中返回该对象应该不会花费任何时间。并且您不必从一开始就预先加载所有内容。

enumerable的工作原理与任何其他集合一样。可以使用yourCollection.ToList()加载所有行,也可以使用foreach(var yourType in yourCollection)在每次迭代中加载新行。

我会在视图模型中存储一个记录集合,而不是只存储一个。

因此,您可以有一个AnalysisRecordsViewModel,它可以同时从存储库中获取所有记录。

如果要在视图中显示或编辑单个记录,可以使用第二个视图模型(如AnalysisViewModel)来显示单个记录。