如何在 gremlin 中将 DocumentClient 转换为 IDocumentClient?

How to convert DocumentClient to IDocumentClient in gremlin?

我正在使用 cosmos db 来存储和获取数据。以前我像这样使用 DocumentClient:

 public class ProductRepository : IProductRepository
    {
        private DocumentClient _documentClient;
        private DocumentCollection _graphCollection;        

        public ProductRepository(DocumentClient documentClient, DocumentCollection graphCollection)
        {
            _documentClient = documentClient;
            _graphCollection = graphCollection;

        }

        public async Task Create(Product product)
        {
            var createQuery = CreateQuery(product);
            IDocumentQuery<dynamic> query = _documentClient.CreateGremlinQuery<dynamic>(_graphCollection, createQuery);
            if(query.HasMoreResults)
            {
                await query.ExecuteNextAsync();
            }
        }

     public async Task<Product> Get(string id)
     {
        Product product = null;
        var getQuery = @"g.V('" + id + "')";
        var query = _documentClient.CreateGremlinQuery<dynamic>(_graphCollection, getQuery);
        if (query.HasMoreResults)
        {
            var result = await query.ExecuteNextAsync();
            if (result.Count == 0)
                return product;
            var productData = (JObject)result.FirstOrDefault();
            product = new Product
            {
               name = productData["name"].ToString()
            };
        }
        return product;
     }
    }
}

但它不可单元测试,所以我想将它转换为 IDocumentClient,但 IDocumentClient 不包含 CreateGremlinQuery 的定义。那么转换我的方法以便它们使用 IDocumentClient 的最佳方法是什么?我需要使用 CreateDocumentQuery 吗?如果是,我如何将 CreateGremlimQuery 转换为 CreateDocumentQuery?

有几种方法可以解决这个问题。最简单的方法是简单地将您的 IDocumentClient 强制转换为 DocumentClient。

如果您采用这种方法,您的代码将变为:

public class ProductRepository : IProductRepository
{
    private IDocumentClient _documentClient;
    private DocumentCollection _graphCollection;        

    public ProductRepository(IDocumentClient documentClient, DocumentCollection graphCollection)
    {
        _documentClient = documentClient;
        _graphCollection = graphCollection;

    }

    public async Task Create(Product product)
    {
        var createQuery = CreateQuery(product);
        IDocumentQuery<dynamic> query = ((DocumentClient)_documentClient).CreateGremlinQuery<dynamic>(_graphCollection, createQuery);
        if(query.HasMoreResults)
        {
            await query.ExecuteNextAsync();
        }
    }

     public async Task<Product> Get(string id)
     {
        Product product = null;
        var getQuery = @"g.V('" + id + "')";
        var query = ((DocumentClient)_documentClient).CreateGremlinQuery<dynamic>(_graphCollection, getQuery);
        if (query.HasMoreResults)
        {
            var result = await query.ExecuteNextAsync();
            if (result.Count == 0)
                return product;
            var productData = (JObject)result.FirstOrDefault();
            product = new Product
            {
               name = productData["name"].ToString()
            };
        }
        return product;
    }
}

您还可以为 IDocumentClient 创建自己的扩展。

public static class MoreGraphExtensions
    {
        public static IDocumentQuery<T> CreateGremlinQuery<T>(this IDocumentClient documentClient, DocumentCollection collection, string gremlinExpression, FeedOptions feedOptions = null, GraphSONMode graphSONMode = GraphSONMode.Compact)
        {
            return GraphExtensions.CreateGremlinQuery<T>((DocumentClient)documentClient, collection, gremlinExpression, feedOptions, graphSONMode);
        }

        public static IDocumentQuery<object> CreateGremlinQuery(this IDocumentClient documentClient, DocumentCollection collection, string gremlinExpression, FeedOptions feedOptions = null, GraphSONMode graphSONMode = GraphSONMode.Compact)
        {
            return GraphExtensions.CreateGremlinQuery<object>((DocumentClient)documentClient, collection, gremlinExpression, feedOptions, graphSONMode);
        }
    }

不过这是一个预发布版,所以我确实认为 Microsoft 会绕过在接口级别移动扩展方法。