使用仿制药从字符串中解析收集名称
我在mongo db中有一些收藏:autocomplete.brands
and autocomplete.makes
这些集合中的每个集合都基于具有name 属性:
public class AutocompleteEntity
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; } = ObjectId.GenerateNewId().ToString();
[BsonElement("Name")]
public string Name { get; set; }
[BsonElement("Culture")]
public string Culture { get; set; }
[BsonElement("Key")]
public string Key { get; set; }
}
我想在每个集合中使用仿制药进行搜索,这就是我所拥有的。
使用存储库的高级服务:
public class AutocompleteHandler : IAutocompleteHandler
{
private readonly IAutocompleteRepository<Brands> _brandsRepository;
private readonly IAutocompleteRepository<Makes> _makesRepository;
public AutocompleteHandler(
IAutocompleteRepository<Brands> brandsRepository,
IAutocompleteRepository<Makes> makesRepository
)
{
_brandsRepository = brandsRepository;
_makesRepository = makesRepository;
}
public async Task<ICollection<string>> SearchForBrand(string name, string culture)
{
return await _brandsRepository.Search(name, culture);
}
public async Task<ICollection<string>> SearchForMake(string name, string culture)
{
return await _makesRepository.Search(name, culture);
}
}
为此,我为每个存储库类型定义了一个类:
public interface IAutocompleteCollection
{
}
public class Brands : IAutocompleteCollection
{
}
public class Makes : IAutocompleteCollection
{
}
以及通用存储库:
public class AutocompleteRepository<T> : IAutocompleteRepository<T> where T : IAutocompleteCollection
{
private readonly IMongoCollection<AutocompleteEntity> _collection;
public AutocompleteRepository(IMongoTenantResolver mongoResolver)
{
var name = typeof(T).Name;
var collectionName = $"autocomplete.{char.ToLowerInvariant(name[0]) + name.Substring(1)}";
_collection = mongoResolver
.GetMongoDbInstance()
.GetCollection<AutocompleteEntity>(collectionName);
}
public async Task<List<string>> Search(string name, string culture)
{
var filter = Builders<AutocompleteEntity>.Filter.Regex("Name", new BsonRegularExpression(name, "i"));
filter &= Builders<AutocompleteEntity>.Filter.Eq("Culture", culture);
var data = await _collection.FindAsync(filter);
var items = await data.ToListAsync();
return items.Select(i => i.Name).ToList();
}
}
我的问题
我正在使用“空类>为了能够通过通用存储库中的名称解决集合:
var name = typeof(T).Name;
var collectionName = $"autocomplete.{char.ToLowerInvariant(name[0]) + name.Substring(1)}";
是否有一种更优雅的方法可以使用仿制药而不依赖空的类/接口,或者在我的情况下,这是使用仿制药的最佳方法吗?
Update1:
@RoberTharvey的答案之后,我添加了此信息。仿制用法对我很有用,因为我正在使用依赖项注入,因此我可以在startup.cs
中使用此单位,
services.AddTransient(typeof(IAutocompleteRepository<>), typeof(AutocompleteRepository<>));
然后我可以添加许多其他自动完整类型,而无需单独注册它们启动。同样,由于使用DI,我不确定如何将枚举价值注入构造函数。
I have some collections in a mongo DB: autocomplete.brands
and autocomplete.makes
Each of these collections have items based on the same pattern that have a Name
property:
public class AutocompleteEntity
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; } = ObjectId.GenerateNewId().ToString();
[BsonElement("Name")]
public string Name { get; set; }
[BsonElement("Culture")]
public string Culture { get; set; }
[BsonElement("Key")]
public string Key { get; set; }
}
I would like to use generics for searching in each of these collections, here is what I have.
The high-level service using repositories:
public class AutocompleteHandler : IAutocompleteHandler
{
private readonly IAutocompleteRepository<Brands> _brandsRepository;
private readonly IAutocompleteRepository<Makes> _makesRepository;
public AutocompleteHandler(
IAutocompleteRepository<Brands> brandsRepository,
IAutocompleteRepository<Makes> makesRepository
)
{
_brandsRepository = brandsRepository;
_makesRepository = makesRepository;
}
public async Task<ICollection<string>> SearchForBrand(string name, string culture)
{
return await _brandsRepository.Search(name, culture);
}
public async Task<ICollection<string>> SearchForMake(string name, string culture)
{
return await _makesRepository.Search(name, culture);
}
}
For this to work I defined a class for each repository type:
public interface IAutocompleteCollection
{
}
public class Brands : IAutocompleteCollection
{
}
public class Makes : IAutocompleteCollection
{
}
and the generic repository:
public class AutocompleteRepository<T> : IAutocompleteRepository<T> where T : IAutocompleteCollection
{
private readonly IMongoCollection<AutocompleteEntity> _collection;
public AutocompleteRepository(IMongoTenantResolver mongoResolver)
{
var name = typeof(T).Name;
var collectionName = quot;autocomplete.{char.ToLowerInvariant(name[0]) + name.Substring(1)}";
_collection = mongoResolver
.GetMongoDbInstance()
.GetCollection<AutocompleteEntity>(collectionName);
}
public async Task<List<string>> Search(string name, string culture)
{
var filter = Builders<AutocompleteEntity>.Filter.Regex("Name", new BsonRegularExpression(name, "i"));
filter &= Builders<AutocompleteEntity>.Filter.Eq("Culture", culture);
var data = await _collection.FindAsync(filter);
var items = await data.ToListAsync();
return items.Select(i => i.Name).ToList();
}
}
My question
I am using the empty classes Brands
and Makes
in order to be able to resolve the collection by name in the generic repository:
var name = typeof(T).Name;
var collectionName = quot;autocomplete.{char.ToLowerInvariant(name[0]) + name.Substring(1)}";
Is there a more elegant way to use generics without relying on empty classes/interface or is that the best way to use generics in my case?
Update1 :
After @RobertHarvey 's answer, I am adding this information. Generics usage is useful to me because I am using Dependency Injection and thus I can have this one-liner in Startup.cs
:
services.AddTransient(typeof(IAutocompleteRepository<>), typeof(AutocompleteRepository<>));
I can then add many other autocomplete types without the need to register them individually in the Startup. Also because of DI usage, I am not sure how I can inject an enum value into the constructor.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)