I'm trying to use Simple Injector to create my repository and use it in the Business logic layer ( also i want to use PerWebRequest method ) .
In the DAL layer i have :
public interface IRepository<T> where T : class
{
void Add(T entity);
void Delete(T entity);
void Delete(int id);
void Update(T entity);
T GetById(int Id);
IQueryable<T> All();
IEnumerable<T> Find(Func<T, bool> predicate);
}
and :
public class EFRepository<T> : IRepository<T>, IDisposable where T : class
{
#region Members
protected DbContext Context { get; set; }
protected DbSet<T> DbSet { get; set; }
#endregion
#region Constructors
public EFRepository(DbContext dbContext)
{
if (dbContext == null)
throw new ArgumentNullException("dbContext");
Context = dbContext;
DbSet = Context.Set<T>();
}
and my context :
public class PASContext : DbContext, IDbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<User> Users { get; set; }
public PASContext()
: base("PostAndSell")
{ }
}
As you can see EFRepository has only one constructor that takes one argument - this is because i want to use Simple Injector to create an instance of the context and pass it to the repository while it is created .
In the BLL i have a class ProductBLL and i want to get all products in that class (with some GetAll method) from the database and pass it, lets say to HomeController .
I really need someone to talk me through this .
I started by installing the right packages from the nuger (Simple Injector and Simple Injector ASP.NET Integration)
also in my global.asax.cs file, under Application_Start() function I`ve added :
var container = new SimpleInjector.Container();
container.RegisterPerWebRequest<IRepository<Product>, EFRepository<Product>>();
but where do i create the Context instance ? and how can i access it in the business layer ?
Since you will probably have many IReposotory<T> implementations (for Product, Customer, Employee, etc), it's better make a single open generic registration for IRepository<T> like this:
container.Register(typeof(IRepository<>), typeof(EFRepository<>), Lifestyle.Scoped);
Where the scoped lifestyle is defined as:
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
This registration ensures that Simple Injector will return a EFRepository<Product>, every time a IRepository<Product> is requested, an EFRepository<Customer> for IRepository<Customer>, and so on, and so on.
Since you want the same DbContext instance to be used over all repositories within the same request, you should also register the DbContext with the scoped Lifestyle:
container.Register<DbContext, PASContext>(Lifestyle.Scoped);
In the BLL i have a class ProductBLL and i want to get all products
from the database and pass it to, lets say HomeController
In that scenario, this ProductBLL seems like a useless abstraction to me. If all it does is passing data through, you can as easily let your HomeController depend on IRepository<Product> directly.
Related
I was a long time user of Autofac that recently switched to Simple Injector for my DI container needs. When I used Autofac, I was able to do something I'm still not able to do with Simple Injector, maybe because I do not yet perfectly understand the API.
Let's say I have the service IEntityRepository of TEntity and TDbContext. It's implementation looks like that:
public class EntityRepository<TEntity, TDbContext> : IEntityRepository<TEntity, TDbContext>
where TDbContext : IEntityDbContext where TEntity : class
{
public EntityRepository(TDbContext dbContext)
{
}
}
With Autofac, I was able to register the open generic implementation EntityRepository as the open generic interface IEntityRepository, so when I would inject say, IEntityRepository of Product and IProductsDbContext, the DI container would automatically guess that I inject through the constructor an instance of ProductsDbContext.
Is this possible with Simple Injector? I tries these, but it still fails:
container.Register(typeof(IEntityRepository<,>), typeof(EntityRepository<,>).Assembly);
container.Register(typeof(IEntityRepository<,>), typeof(EntityRepository<,>));
Thanks in advance for you help!
EDIT:
So here's a full exemple with Autofac as requested by Steven. Create a new .NET Core Console Application. You'll need to install the NuGet Package Autofac.
Program.cs:
internal class Program
{
private static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<ProductsDbContext>().AsImplementedInterfaces();
builder.RegisterGeneric(typeof(EntityRepository<,>)).As(typeof(IEntityRepository<,>));
var container = builder.Build();
using (var scope = container.BeginLifetimeScope())
{
var productsRepository = scope.Resolve<IEntityRepository<Product, IProductsDbContext>>();
Console.WriteLine($"Resolved IEntityRepository is of type: {productsRepository.GetType()}");
}
}
}
ProductsDbContext.cs
public class ProductsDbContext : IProductsDbContext
{
public void Dispose()
{
// Demo, do nothing.
}
public int SaveChanges()
{
throw new System.NotImplementedException();
}
}
Product.cs
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
EntityRepository.cs
public class EntityRepository<TEntity, TDbContext> : IEntityRepository<TEntity, TDbContext>
where TDbContext : IEntityDbContext where TEntity : class
{
private readonly TDbContext _dbContext;
public EntityRepository(TDbContext dbContext)
{
_dbContext = dbContext;
Console.WriteLine($"Database context is of type {dbContext.GetType()}.");
}
public IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> whereClause)
{
throw new NotImplementedException();
}
}
IEntityDbContext.cs
public interface IEntityDbContext : IDisposable
{
int SaveChanges();
}
IProductsDbContext.cs
public interface IProductsDbContext : IEntityDbContext
{
}
IEntityRepository.cs
public interface IEntityRepository<TEntity, TDbContext> where TDbContext : IEntityDbContext where TEntity : class
{
IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> whereClause);
}
The final console output should ressemble to:
Database context is of type
GenericTypeDiTester.DbContexts.ProductsDbContext. Resolved
IEntityRepository is of type:
GenericTypeDiTester.Repositories.EntityRepository`2[GenericTypeDiTester.Models.Product,GenericTypeDiTester.Interfaces.DbContexts.IProductsDbContext]
You can download the full example there: https://drive.google.com/file/d/1UkIYxLsY6YGwo5jOB5TyyncXc6yho8X5/view?usp=sharing
EDIT 2:
The problem wasn't with the Simple Injector library at the end. It seems that mixing the usage of Microsoft.DependencyInjection and SimpleInjector isn't really a good thing. As suggested by Steven, you should exclusively use SI to register the majority of your services and in rare case, MS.DI (by example for using AddDbContext).
As for my part, I have in my project MediatR, a library that implements the Mediator pattern. This library offers a NuGet package with an extension method AddMediatR for the IServiceCollection of MS.DI, which is supposed to register all handlers properly, but it wasn't the case for me. So I ended up registering the module all by myself using SI.
At the end it everything worked perfectly. You really need to call these lines at the end of the registering process: EnableSimpleInjectorCrossWiring and UseSimpleInjectorAspNetRequestScoping. Nothing else must be registered using the IServiceCollection afterwards. That way, the cross wiring of both DI framework ends up to work beautifully.
The way to register this in Simple Injector is:
container.Register(typeof(IEntityRepository<,>), typeof(EntityRepository<,>));
container.Register<IProductsDbContext, ProductsDbContext>();
There is no AsImplementedInterfaces equivalent in Simple Injector, although there are several ways to achieve rhe same. In the case that ProductsDbContext has multiple interfaces that need to be registered, the most obvious way is to register each interface explicitly:
container.Register<IProductsDbContext, ProductsDbContext>();
container.Register<IUsersDbContext, ProductsDbContext>();
container.Register<ICustomersDbContext, ProductsDbContext>();
I am working on a project with Entity Framework where i have implemented Repository pattern and DI (Microsoft Unity), now to maintain the database transactions i want to implement the UnitOfWork pattern, but i am totally confused about how shall i implement it in my current project, i google around few posts, but could not find anything doable with my existing project.
Below is the EF and Repository structure along with DI (Microsoft Unity).
Entities:
public class GenericDo
{
public DateTime CreatedDate {get;set;}
public string CreatedBy {get;set;}
}
public class UsersDo : GenericDo
{
public int UserId {get;set;}
public string Username {get;set;}
....
}
public class UserProfileDo : GenericDo
{
public int Id {get;set}
public int UserId {get;set;}
public string Address {get;set;}
....
}
Interface:
public interface IGenericDao : IGenericDao<GenericDo> {}
public interface IGenericDao<T>
{
void Add(T entity);
T Get(object Id);
....
}
public interface IUsersDao : IUsersDao<UsersDo> {}
public interface IUserProfileDao : IUserProfileDao<UserProfileDo>{}
Interface Implementation:
public class GenericDao<T> : IGenericDao<T> where T : class
{
private readonly DataContext context;
public GenericDao(DataContext _context)
{
this.context = _context;
}
public void Add(T entity)
{
context.Set<T>().Add(entity);
}
public T Get(object Id)
{
return context.Set<T>().Find(Id);
}
}
public class UsersDao : GenericDao<UsersDo>, IUsersDao
{
public UsersDao(DataContext context) : base (context){}
}
public class UserPorfileDao : GenericDao<UserProfileDo>, IUserProfileDao
{
public UserPorfileDao(DataContext context) : base (context){}
}
Dependency Injection Setup in Global.asax.
var container = this.AddUnity();
container.RegisterType<IUsersDao, UsersDao>();
container.RegisterType<IUserProfileDao, UserProfileDao>();
Now in my main webpage(ASP.Net)
public partial class Default : System.Web.UI.Page
{
private readonly IUsersDao usersDao;
private readonly IUserProfileDao userProfileDao;
public Default(IUsersDao _userDao, IUserProfileDao _userProfileDao)
{
this.usersDao = _userDao;
this.userProfileDao = _userProfileDao;
}
// Now for testing purpose, i update record.
protected void Page_Load(object sender, EventArgs e)
{
UsersDo user = usersDao.Get(1);
user.Username = "new system";
UserProfileDo userProfile = userProfileDao.Get(1);
userProfile.Address = "new address";
// Now here i am confused about setting up common Save method to update database with transaction.
}
}
EntityFramework's DbContext already implements Unit of Work, so it is not necessary to add yet another layer of abstraction to implement this.
One could even doubt if creating a Repository pattern is actually helpful if you're using Entity Framework. Instead of using a layered architecture and using a Repository, you could investigate whether it is not better to use a more sliced architecture and use the DbContext directly.
Also, what is the benefit of having a 'Generic Dao' that just delegates calls to Entity Frameworks DbContext ? It's just yet another level of abstraction which adds extra complexity but doesn't give you any added value.
Unit of work ecapsulates the database operations in a single object and keeps track of them. In Entity Framework DbContext implements this behaviour and DbSet<> implements the repository. The reason why people create their own wrappers around is to be able to swap Entity Framework for another ORM, if needed or to mock Entity Framework for testing,.
UnitOfWork pattern is used with Entity Framework.
The repository and unit of work patterns are intended to create an abstraction layer between the data access layer and the business logic layer of an application. Implementing these patterns can help insulate your application from changes in the data store and can facilitate automated unit testing or test-driven development (TDD).
First step is to create repositories. Repository is a class which exposes methods to business layer
Second step: You can create UnitOfWork implementation as shown below. There are properties corresponding to every repository. Then you inject Unit of Work in your business layer to use the repository methods.
public class UnitOfWork : IDisposable
{
private SchoolContext context = new SchoolContext();
private GenericRepository<Department> departmentRepository;
private GenericRepository<Course> courseRepository;
public GenericRepository<Department> DepartmentRepository
{
get
{
if (this.departmentRepository == null)
{
this.departmentRepository = new GenericRepository<Department>(context);
}
return departmentRepository;
}
}
}
refer documentation at: https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
I'm having some problems with getting unity to provide dependencies for my MVC controllers.
I want my ApplicationUser data and my business data in the same database and I am using code-first migrations with Entity Framework. To that end my DbContext inherits from IdentityDbContext and then implements an interface which represents my business data:
public class DealFinderDb : IdentityDbContext<ApplicationUser>, IDealFinderDb
{
public DealFinderDb() : base("name=DealFinderConnectionString", false)
{
}
public IDbSet<Deal> Deals { get; set; }
public IDbSet<Category> Categories { get; set; }
public IDbSet<SavedSearch> SavedSearches { get; set; }
public static DealFinderDb Create()
{
return new DealFinderDb();
}
}
public interface IDealFinderDb : IDisposable
{
IDbSet<Deal> Deals { get; set; }
IDbSet<Category> Categories { get; set; }
IDbSet<SavedSearch> SavedSearches { get; set; }
int SaveChanges();
DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity)
where TEntity : class;
}
In my controller I need to be able to get the current user which means my controller has a dependency, not only on a IDealFinderDb but also on a UserManager. I understand that the best way to test this is to mock an IUserStore and pass that into the constructor of my controller. I have written the tests that mock both the IUserStore and the controller's HttpContext and these tests work as expected. This means my controller looks like this:
public class SavedSearchesController : Controller
{
private readonly IDealFinderDb dealFinderDb;
private readonly UserManager<ApplicationUser> userManager;
public SavedSearchesController(IDealFinderDb dealFinderDb, IUserStore<ApplicationUser> userStore)
{
this.dealFinderDb = dealFinderDb;
this.userManager = new UserManager<ApplicationUser>(userStore);
}
public ActionResult Index()
{
var user = this.userManager.FindById(this.User.Identity.GetUserId());
var usersSavedSearches = this.dealFinderDb.SavedSearches.Where(s => s.User.Id == user.Id);
return this.View(usersSavedSearches);
}
// Snip unrelated action methods.
protected override void Dispose(bool disposing)
{
if (disposing)
{
this.dealFinderDb.Dispose();
}
base.Dispose(disposing);
}
}
This seems fine but I am using Unity to provide implementations for these interfaces at run-time and this is where I'm stuck. My first attempt at my UnityConfig looks like this:
container.RegisterType<IDealFinderDb, DealFinderDb>();
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(
new InjectionConstructor(typeof(DealFinderDb)));
...but the problem with that is I end up with a DbContext being instantiated twice leading to an error of "System.InvalidOperationException: 'An entity object cannot be referenced by multiple instances of IEntityChangeTracker.'" when I call Add() on any of my IDBSets in my DbContext I guess this is because unity is instantiating my DbContext twice.
So my next attempt was to ensure that only a single instance of DealFinderDb is created and that looks like this in my UnityConfig:
container.RegisterType<DealFinderDb, DealFinderDb>(new ContainerControlledLifetimeManager());
container.RegisterType<IDealFinderDb, DealFinderDb>();
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(
new InjectionConstructor(typeof(DealFinderDb)));
...but when this.userManager.FindById() is called in my controller I get the error "System.InvalidOperationException: 'The operation cannot be completed because the DbContext has been disposed.'". Obviously I could avoiding calling Dispose on my Context but this is bad as I assume means I am actually using the same DBContext instance for the entire life-cycle of my application.
What should I put in my UnityConfig to ensure that both the IDealFinderDb and IUserStore dependencies are satisfied and that only a single context is instantiated each time my controller is instantiated?
Thanks
What should I put in my UnityConfig to ensure that both the
IDealFinderDb and IUserStore dependencies are satisfied and that only
a single context is instantiated each my controller is instantiated?
You should use per-graph lifetime manager which is called PerResolveLifetimeManager in Unity:
container.RegisterType<IDealFinderDb, DealFinderDb>(new PerResolveLifetimeManager());
According to best practice to software design pattern, you should always follow Singleton Pattern while creating database context and logger context and many other things as per business requirement if you feel there is a need for singleton object go for that and while using singleton pattern do take care of thread safety singleton if you are implementing threads.its so easy and for help, you can refer MSDN, it has an implementation of the singleton.
https://msdn.microsoft.com/en-us/library/ff647854.aspx
Hope this helps.
I am trying to use autofac with a repository and I am trying to add a little generics to try reducing the amount of duplicate code I am writing.However I am going round in circles trying to get autofac to work for me
So I created a domainservice and interface that handles our the standard crud operations
public class DomainService<T>:IDomainService<T>
{
protected readonly IDomainService<T> Repository;
public DomainService(IDomainService<T> repository)
{
Repository = repository;
}
public IQueryable<T> GetQueryable()
{
return Repository.GetQueryable();
}
public virtual Task<T> Add(T entity)
{
return Repository.Add(entity);
}
Interface:
public interface IDomainService<T>
{
IQueryable<T> GetQueryable();
Task<T> Add(T entity);
Task<bool> Delete(T entity);
Task<T> Update(T entity);
Task<T> GetById(int id);
Task<T> GetByUID(Guid id);
}
I am using my repo is nothing special
public class SkillRepository : DomainService<Skill>, ISkill
{
private DataContext _db = new DataContext();
private readonly ILogger _log = null;
public SkillRepository(IDomainService<Skill> repository, ILogger log) : base(repository)
{
_log = log;
}
}
Finally where I wire up autofac:
var builder = new ContainerBuilder();
// Register the Web API controllers.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
// Register other dependencies.
builder.Register(c => new Logger()).As<ILogger>().InstancePerApiRequest();
builder.RegisterType<SkillRepository>()
.As<IDomainService<Skill>>()
.As<ISkill>()
.InstancePerRequest();
// Build the container.
var container = builder.Build();
// Create the depenedency resolver.
var resolver = new AutofacWebApiDependencyResolver(container);
// Configure Web API with the dependency resolver.
GlobalConfiguration.Configuration.DependencyResolver = resolver;
My web api controller looks like
public class SkillsController : BaseController<Skill>
{
private readonly ISkill _skillRepository;
public SkillsController(SkillRepository skillRepository) : base(skillRepository)
{
_skillRepository = skillRepository;
}
}
BaseController
public abstract class BaseController<TEntity> : ApiController
where TEntity : new()
{
protected readonly IDomainService<TEntity> DomainService;
protected BaseController(IDomainService<TEntity> domainService)
{
DomainService = domainService;
}
I get an exception:
"None of the constructors found with
'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type
'Api.EndPoints.Skills.SkillsController' can be invoked with the
available services and parameters:\ \ Cannot resolve parameter
'Domain.Repository.SkillRepository skillRepository' of constructor
'Void .ctor(Domain.Repository.SkillRepository)'."
Is there something obvious that I am doing wrong?
It cannot resolve the dependency because it's looking for the concrete type but you never registered SkillsRepository as that. Now you could change the registration to register the concrete type but that wouldn't be the best approach.
A better approach is to register SkillsRepository as its interfaces:
builder.RegisterType<SkillRepository>()
.As<ISkillsRepository>()
.InstancePerRequest();
And define ISkillsRepository to inherit all the other interfaces like ISkill that you want.
public interface ISkillsRepository : ISkill, IDomainService<Skill> { }
Don't register objects as concrete types and don't depend on concrete types in constructors.
public SkillsController(ISkillRepository skillRepository) :
base(skillRepository) ...
If you use concrete types as dependencies you create classes that cannot be tested using mocking frameworks.
Your use of SkillRepository : DomainService<Skill>, ISkill is perplexing too. Why is it both a skill and a domain service for skills? Doesn't make much sense.
Exception clearly states:
Cannot resolve parameter 'Domain.Interfaces.ISkill skillRepository' of constructor 'Void .ctor(Domain.IDomainService`1[Model.Skill], Domain.Interfaces.ISkill)'.
You have only IDomainService registered. But no ISkill (the line is commented).
Also why does the ctor require 2 parameters? SkillRepository implements both IDomainService<Skill> and ISkill so you should be able to pass it along:
public SkillsController(SkillRepository skillRepository) : base(skillRepository)
P.S.
I'd name it this way:
public class SkillRepository : ISkillRepository, IDomainService<Skill>
And I prefer everything to be either plural (SkillsControllers, SkillsRepository) or everything singular (SkillController, SkillRepository).
In my opinion you should first sort out names for your classes which is making it hard to understand the code itself. secondly your repository is implementing domain service interface and ISkill and things like that is adding more confusion. i am pretty sure if you organise your classes properly then you will find solution to your problem.
For instance ApiController should use domain service, domain service should use repository and repository should deal with enties.
public class SkillsDomainService:ISkillsDomainService
{
public void AddSkill(string name){}
public void DeleteSkillById(int id){}
..... etc
}
public class Repository:IRepository
{
public T Get(int id){}
public IEnumerable<T>GetAll(){}
}
Then you need to bind your interfaces to concrete classed in ioc. things should work that way i am pretty sure.
I am trying to use autofac with a repository and I am trying to add a little generics to try reducing the amount of duplicate code I am writing.However I am going round in circles trying to get autofac to work for me
So I created a domainservice and interface that handles our the standard crud operations
public class DomainService<T>:IDomainService<T>
{
protected readonly IDomainService<T> Repository;
public DomainService(IDomainService<T> repository)
{
Repository = repository;
}
public IQueryable<T> GetQueryable()
{
return Repository.GetQueryable();
}
public virtual Task<T> Add(T entity)
{
return Repository.Add(entity);
}
Interface:
public interface IDomainService<T>
{
IQueryable<T> GetQueryable();
Task<T> Add(T entity);
Task<bool> Delete(T entity);
Task<T> Update(T entity);
Task<T> GetById(int id);
Task<T> GetByUID(Guid id);
}
I am using my repo is nothing special
public class SkillRepository : DomainService<Skill>, ISkill
{
private DataContext _db = new DataContext();
private readonly ILogger _log = null;
public SkillRepository(IDomainService<Skill> repository, ILogger log) : base(repository)
{
_log = log;
}
}
Finally where I wire up autofac:
var builder = new ContainerBuilder();
// Register the Web API controllers.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
// Register other dependencies.
builder.Register(c => new Logger()).As<ILogger>().InstancePerApiRequest();
builder.RegisterType<SkillRepository>()
.As<IDomainService<Skill>>()
.As<ISkill>()
.InstancePerRequest();
// Build the container.
var container = builder.Build();
// Create the depenedency resolver.
var resolver = new AutofacWebApiDependencyResolver(container);
// Configure Web API with the dependency resolver.
GlobalConfiguration.Configuration.DependencyResolver = resolver;
My web api controller looks like
public class SkillsController : BaseController<Skill>
{
private readonly ISkill _skillRepository;
public SkillsController(SkillRepository skillRepository) : base(skillRepository)
{
_skillRepository = skillRepository;
}
}
BaseController
public abstract class BaseController<TEntity> : ApiController
where TEntity : new()
{
protected readonly IDomainService<TEntity> DomainService;
protected BaseController(IDomainService<TEntity> domainService)
{
DomainService = domainService;
}
I get an exception:
"None of the constructors found with
'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type
'Api.EndPoints.Skills.SkillsController' can be invoked with the
available services and parameters:\ \ Cannot resolve parameter
'Domain.Repository.SkillRepository skillRepository' of constructor
'Void .ctor(Domain.Repository.SkillRepository)'."
Is there something obvious that I am doing wrong?
It cannot resolve the dependency because it's looking for the concrete type but you never registered SkillsRepository as that. Now you could change the registration to register the concrete type but that wouldn't be the best approach.
A better approach is to register SkillsRepository as its interfaces:
builder.RegisterType<SkillRepository>()
.As<ISkillsRepository>()
.InstancePerRequest();
And define ISkillsRepository to inherit all the other interfaces like ISkill that you want.
public interface ISkillsRepository : ISkill, IDomainService<Skill> { }
Don't register objects as concrete types and don't depend on concrete types in constructors.
public SkillsController(ISkillRepository skillRepository) :
base(skillRepository) ...
If you use concrete types as dependencies you create classes that cannot be tested using mocking frameworks.
Your use of SkillRepository : DomainService<Skill>, ISkill is perplexing too. Why is it both a skill and a domain service for skills? Doesn't make much sense.
Exception clearly states:
Cannot resolve parameter 'Domain.Interfaces.ISkill skillRepository' of constructor 'Void .ctor(Domain.IDomainService`1[Model.Skill], Domain.Interfaces.ISkill)'.
You have only IDomainService registered. But no ISkill (the line is commented).
Also why does the ctor require 2 parameters? SkillRepository implements both IDomainService<Skill> and ISkill so you should be able to pass it along:
public SkillsController(SkillRepository skillRepository) : base(skillRepository)
P.S.
I'd name it this way:
public class SkillRepository : ISkillRepository, IDomainService<Skill>
And I prefer everything to be either plural (SkillsControllers, SkillsRepository) or everything singular (SkillController, SkillRepository).
In my opinion you should first sort out names for your classes which is making it hard to understand the code itself. secondly your repository is implementing domain service interface and ISkill and things like that is adding more confusion. i am pretty sure if you organise your classes properly then you will find solution to your problem.
For instance ApiController should use domain service, domain service should use repository and repository should deal with enties.
public class SkillsDomainService:ISkillsDomainService
{
public void AddSkill(string name){}
public void DeleteSkillById(int id){}
..... etc
}
public class Repository:IRepository
{
public T Get(int id){}
public IEnumerable<T>GetAll(){}
}
Then you need to bind your interfaces to concrete classed in ioc. things should work that way i am pretty sure.