簡體   English   中英

如何設置使用通用存儲庫的 .net 核心服務

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM