[英]How to set up .net core service that uses a generic repository
我正在使用 .netcore 3.0 構建一個通用數據存儲庫。 與 EF 核心。 如何在不必提供實際實體名稱的情況下設置服務,例如:
services.AddScoped<RepositoryBase<Feature>>();
有沒有辦法配置所有我都可以這樣做的選項?
這些主要是 CRUD 操作。
通用存儲庫基礎
namespace CoreAPI1.Data.Services
{
public class RepositoryBase<TEntity> where TEntity : class
{
private readonly DbContext _context;
private readonly DbSet<TEntity> _dbSet;
public RepositoryBase(DbContext context)
{
_context = context;
if (_context == null)
throw new ArgumentNullException();
_dbSet = context.Set<TEntity>();
}
public async Task<IEnumerable<TEntity>> GetAll()
{
return _dbSet.AsNoTracking().ToList();
}
}
}
服務
public static void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<TruckContext>(ServiceLifetime.Scoped);
services.AddScoped<IFileService, FileService>();
services.AddScoped<IImageRepository, ImageRepository>();
services.AddScoped<RepositoryBase<Feature>>();
services.AddControllers();
// services.AddAutoMapper(typeof(Truck));
services.AddMvc(_x=>_x.EnableEndpointRouting =
false).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
}
調用 controller
namespace CoreAPI1.Data.Controllers
{
[Route("api/features")]
[ApiController]
public class FeaturesController :ControllerBase
{
private RepositoryBase<Data.Entities.Feature> _repository;
private IMapper _mapper;
public FeaturesController(RepositoryBase<Data.Entities.Feature> repository, IMapper mapper)
{
_repository = repository ?? throw new ArgumentNullException(nameof(_repository));
_mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
}
[HttpGet]
public async Task<IEnumerable<Domain.Models.Feature>> GetFeatures()
{
var _features = await _repository.GetAllAsync();
List<Domain.Models.Feature> _returnedFeatures = new List<Domain.Models.Feature>();
try
{
foreach (var f in _features)
{
var _returnedFeature = _mapper.Map<Domain.Models.Feature>(f);
_returnedFeatures.Add(_returnedFeature);
}
return _returnedFeatures;
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
}
}
}
如果這就是您所說的,您可以一般地注冊類型:
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
例如,這將為IRespository<Foo>
注入Repository<Foo>
。
實現包裝 DbContext 並創建存儲庫的工作單元 class。
這是我用於 MongoDB 的內容。
IDataRepository.cs
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace MyApp.Repositories
{
public interface IDataRepository<TEntity, in TKey> where TEntity : IEntity<TKey>
{
Task<TEntity> GetByIdAsync(TKey id);
Task<TEntity> SaveAsync(TEntity entity);
Task DeleteAsync(TKey id);
Task DeleteAllAsync(Expression<Func<TEntity, bool>> where);
Task<ICollection<TEntity>> FindAllAsync(Expression<Func<TEntity, bool>> where);
bool OneExists(Expression<Func<TEntity, bool>> where);
}
}
MongoRepository.cs(這是您可以使用任何您想要的數據庫的地方)
using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace MyApp.Repositories
{
public class MongoRepository<TEntity> : IDataRepository<TEntity, string> where TEntity : IEntity
{
private readonly IMongoCollection<TEntity> Collection;
public MongoRepository(IDataContext dataContext)
{
if (dataContext == null)
throw new ArgumentNullException(nameof(dataContext));
Collection = dataContext.MongoDatabase.GetCollection<TEntity>(typeof(TEntity).Name);
}
public virtual async Task<TEntity> GetByIdAsync(string id)
{
if (string.IsNullOrWhiteSpace(id))
throw new ArgumentNullException(nameof(id));
return await Collection.Find(x => x.Id.Equals(id)).FirstOrDefaultAsync();
}
public virtual TEntity GetById(string id)
{
if (string.IsNullOrWhiteSpace(id))
throw new ArgumentNullException(nameof(id));
return Collection.Find(x => x.Id.Equals(id)).FirstOrDefault();
}
public virtual async Task<TEntity> SaveAsync(TEntity entity)
{
if (entity == null)
throw new ArgumentNullException(nameof(entity));
if (string.IsNullOrWhiteSpace(entity.Id))
{
entity.Id = ObjectId.GenerateNewId().ToString();
}
await Collection.ReplaceOneAsync(
x => x.Id.Equals(entity.Id),
entity,
new UpdateOptions
{
IsUpsert = true
});
return entity;
}
public virtual async Task DeleteAsync(string id)
{
if (string.IsNullOrWhiteSpace(id))
throw new ArgumentNullException(nameof(id));
await Collection.DeleteOneAsync(x => x.Id.Equals(id));
}
public virtual async Task DeleteAllAsync(Expression<Func<TEntity, bool>> where)
{
if (where == null)
throw new ArgumentNullException(nameof(where));
await Collection.DeleteManyAsync(where);
}
public virtual async Task<ICollection<TEntity>> FindAllAsync(
Expression<Func<TEntity, bool>> where)
{
if (where == null)
throw new ArgumentNullException(nameof(where));
return await Collection.Find(where).ToListAsync();
}
public bool OneExists(Expression<Func<TEntity, bool>> where)
{
if (where == null) throw new ArgumentNullException(nameof(where));
return Collection.Find(where).Limit(1).Any();
}
}
}
IEntity.cs
namespace MyApp.Models.Assets
{
public interface IEntity<TKeys>
{
TKeys Id { get; set; }
}
public interface IEntity : IEntity<string>
{
}
}
示例 class:
public abstract class MyClass : IEntity
{
public string Id { get; set; }
public string Field1 { get; set; }
public string Field2 { get; set; }
...
}
}
}
啟動.cs
…
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<IDataContext, MongoDataContext>();
services.AddSingleton<IDataRepository<MyClass, string>, MongoRepository<Asset>>();
...
}
注意:我的 id 字段是字符串,所以如果你的是 integer 那么你需要將上面的定義更改為 integer (
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.