title: How to properly implement Repository Pattern and Unit of Work by separated class library in ASP.NET Core 2?
body: <p>I am creating project using ASP.NET Core API 2 I want to implement properly Repository Pattern and Unit of Work in separated class library. Somehow I get confuse with the implementation I only familiarize with the implementation using ASP.NET MVC 5. Please, I would like to know some suggestion also if is possible to this in ASP.NET Core 2?</p>
  
  <p>Project.API</p>
  
  <p>appsettings.json</p>
  
  <pre><code>{
    "ConnectionStrings": {
      "DbConnectionString": "Server=HOST; Database=DB_NAME; User Id=sa; Password=Password;"
    },
    "Logging": {
      "IncludeScopes": false,
      "Debug": {
        "LogLevel": {
          "Default": "Warning"
        }
      },
      "Console": {
        "LogLevel": {
          "Default": "Warning"
        }
      }
    }
  }
  </code></pre>
  
  <p>Startup.cs</p>
  
  <pre><code>public class Startup
      {
          public Startup(IConfiguration configuration)
          {
              Configuration = configuration;
          }
  
          public IConfiguration Configuration { get; }
  
          public void ConfigureServices(IServiceCollection services)
          {
              services.AddDbContext&lt;DatninContext&gt;(options =&gt;
                  options.UseSqlServer(Configuration.GetConnectionString("DbConnectionString")));
  
              services
                  .AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
          }
  
          public void Configure(IApplicationBuilder applicationBuilder, IHostingEnvironment hostingEnvironment)
          {
              if (hostingEnvironment.IsDevelopment()) applicationBuilder.UseDeveloperExceptionPage();
  
              applicationBuilder.UseCors(AllRequests);
              applicationBuilder.UseStaticFiles();
              applicationBuilder.UseMvc();
          }
      }
  </code></pre>
  
  <p>Project.Persistence</p>
  
  <p>EntityConfigurations Folder</p>
  
  <pre><code>public class EmployeeConfiguration : IEntityTypeConfiguration&lt;Employee&gt;
      {
          public void Configure(EntityTypeBuilder&lt;Employee&gt; builder)
          {
              throw new NotImplementedException();
          }
      }
  </code></pre>
  
  <p>Repositories Implementation</p>
  
  <pre><code>public class EmployeeRepository : BaseRepository&lt;Employee&gt;, IEmployeeRepository
      {
          public AnimeRepository(ProjectDbContext context) : base(context)
          {
          }
  
          public ProjectDbContext ProjectDbContext =&gt; Context as ProjectDbContext;
  
          public async Task&lt;IEnumerable&lt;Employee&gt;&gt; GetEmployeesAsync()
          {
              var employees = await ProjectDbContext.Employees.ToListAsync();
  
              return employees;
          }
  
          public async Task&lt;Employee&gt; GetEmployeeWithIdAsync(Guid id)
          {
              var employee = await DatninContext.Employees.SingleOrDefaultAsync(a =&gt; a.Id == id);
  
              return employee;
          }
      }
  </code></pre>
  
  <p>Base Repository Implementation</p>
  
  <pre><code>public class BaseRepository&lt;TEntity&gt; : IBaseRepository&lt;TEntity&gt; where TEntity : class
      {
          protected readonly DbContext Context;
  
          public BaseRepository(DbContext context)
          {
              Context = context;
          }
  
          public async Task&lt;TEntity&gt; GetAsync(int id)
          {
              return await Context.Set&lt;TEntity&gt;().FindAsync(id);
          }
  
          public async Task&lt;IEnumerable&lt;TEntity&gt;&gt; GetAllAsync()
          {
              return await Context.Set&lt;TEntity&gt;().ToListAsync();
          }
  
          public async Task&lt;TEntity&gt; SingleOrDefaultAsync(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate)
          {
              return await Context.Set&lt;TEntity&gt;().SingleOrDefaultAsync(predicate);
          }
  
          public async Task&lt;IEnumerable&lt;TEntity&gt;&gt; FindAsync(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate)
          {
              return await Context.Set&lt;TEntity&gt;().Where(predicate).ToListAsync();
          }
  
          public async Task AddAsync(TEntity entity)
          {
              await Context.Set&lt;TEntity&gt;().AddAsync(entity);
          }
  
          public async Task AddRangeAsync(IEnumerable&lt;TEntity&gt; entities)
          {
              await Context.Set&lt;TEntity&gt;().AddRangeAsync(entities);
          }
  
          public void Remove(TEntity entity)
          {
              Context.Set&lt;TEntity&gt;().Remove(entity);
          }
  
          public void RemoveRange(IEnumerable&lt;TEntity&gt; entities)
          {
              Context.Set&lt;TEntity&gt;().RemoveRange(entities);
          }
      }
  </code></pre>
  
  <p>ProjectDbContext.cs</p>
  
  <pre><code>public class ProjectDbContext : DbContext
      {
          public ProjectDbContext(DbContextOptions&lt;ProjectDbContext&gt; options) : base(options)
          {
          }
  
          public virtual DbSet&lt;Employee&gt; Employees { get; set; }
  
          protected override void OnModelCreating(ModelBuilder builder)
          {
              base.OnModelCreating(builder);
  
          builder.ApplyConfiguration(new EmployeeConfiguration());
  
          }
      }
  </code></pre>
  
  <p>Unit of Work Implementation</p>
  
  <pre><code>public class UnitOfWork : IUnitOfWork
      {
          private readonly ProjectDbContext _context;
  
          public UnitOfWork(ProjectDbContext context)
          {
              _context = context;
              Employees = new EmployeeRepository(_context);
          }
  
          public IEmployeeRepository Employees { get; }
  
          public int Complete()
          {
              return _context.SaveChanges();
          }
  
          public void Dispose()
          {
              _context.Dispose();
          }
      }
  </code></pre>
  
  <p>Propject.Core</p>
  
  <p>Entities</p>
  
  <p>Employee.cs</p>
  
  <pre><code>public class Employee 
      {
  public int Id { get; set; }
          public string Name { get; set; }
          public string Position { get; set; }
          public string Department { get; set; }
  public string Salary { get; set; }
      }
  </code></pre>
  
  <p>IBaseRepository.cs</p>
  
  <pre><code>public interface IBaseRepository&lt;TEntity&gt; where TEntity : class
      {
          Task&lt;TEntity&gt; GetAsync(int id);
          Task&lt;IEnumerable&lt;TEntity&gt;&gt; GetAllAsync();
          Task&lt;TEntity&gt; SingleOrDefaultAsync(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate);
          Task&lt;IEnumerable&lt;TEntity&gt;&gt; FindAsync(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate);
          Task AddAsync(TEntity entity);
          Task AddRangeAsync(IEnumerable&lt;TEntity&gt; entities);
          void Remove(TEntity entity);
          void RemoveRange(IEnumerable&lt;TEntity&gt; entities);
      }
  </code></pre>
  
  <p>IEmployeeRepository.cs</p>
  
  <pre><code>public interface IEmployeeRepository : IBaseRepository&lt;Employee&gt;
      {
          Task&lt;IEnumerable&lt;Employee&gt;&gt; GetEmployeesAsync();
          Task&lt;Anime&gt; GetEmployeeWithIdAsync(Guid id);
      }
  </code></pre>
  
  <p>IUnitOfWork.cs</p>
  
  <pre><code> public interface IUnitOfWork : IDisposable
      {
          IEmployeeRepository Employees { get; }
          int Complete();
      }`
  </code></pre>