I am working with .net core API and resolving my dependency using autofac. However somehow I am not able to resolve dependency for my Generic Repository.
Can someone guide what I have done wrong.
startup.cs
var builder = new ContainerBuilder();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>()
.InstancePerLifetimeScope();
builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>()
.InstancePerLifetimeScope();
//This is the place which is not working for me
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(typeof(SizeRepository).Assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(typeof(UserService).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
builder.Populate(services);
var container = builder.Build();
//Create the IServiceProvider based on the container.
return new AutofacServiceProvider(container);
UnitOfWork.cs
using System.Threading.Tasks;
namespace MakeTalk.Data.Infrastructure
{
public class UnitOfWork : IUnitOfWork
{
#region Local variable
private readonly IDatabaseFactory databaseFactory;
private MakeTalkEntities dataContext;
#endregion
#region Constructor
public UnitOfWork(IDatabaseFactory databaseFactory)
{
this.databaseFactory = databaseFactory;
}
#endregion
#region Property
protected MakeTalkEntities DataContext => dataContext ?? (dataContext = databaseFactory.Get());
#endregion
#region Methods
/// <summary>
/// Commit changes
/// </summary>
/// <history>Created : 01-04-2018</history>
public void Commit()
{
DataContext.SaveChanges();
}
/// <summary>
/// Commit Async changes
/// </summary>
/// <returns></returns>
/// <history>Created : 01-04-2018</history>
public async Task<int> CommitAsync()
{
return await DataContext.SaveChangesAsync();
}
#endregion
}
}
Repository.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace MakeTalk.Data.Infrastructure
{
public class Repository<T> : IRepository<T> where T : class
{
#region Variable / Properties
private MakeTalkEntities dataContext;
private readonly DbSet<T> dbSet;
protected MakeTalkEntities DataContext => dataContext ?? (dataContext = DatabaseFactory.Get());
protected IDatabaseFactory DatabaseFactory
{
get;
private set;
}
#endregion
#region Constructor
protected Repository(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
dbSet = DataContext.Set<T>();
}
#endregion
#region Sync Methods
// all methods ...
#endregion
}
}
DatabaseFactory.cs
using Microsoft.EntityFrameworkCore;
namespace MakeTalk.Data.Infrastructure
{
public class DatabaseFactory : Disposable, IDatabaseFactory
{
private MakeTalkEntities dataContext;
public MakeTalkEntities Get()
{
return dataContext ?? (dataContext = new MakeTalkEntities(new DbContextOptions<MakeTalkEntities>()));
}
protected override void DisposeCore()
{
dataContext?.Dispose();
}
}
}
MakeTalkEntities.cs
using Microsoft.EntityFrameworkCore;
using MakeTalk.Data.Configuration;
using MakeTalk.Model;
namespace MakeTalk.Data
{
public class MakeTalkEntities : DbContext
{
#region Constructor
public MakeTalkEntities(DbContextOptions options)
{
}
#endregion
#region DB Properties
// db sets
#endregion
#region Methods
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// ReSharper disable once AssignNullToNotNullAttribute
optionsBuilder.UseSqlServer("Some-Connection");
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// all configutaion
base.OnModelCreating(modelBuilder);
}
#endregion
}
}
Is there anything wrong with code? I am able to resolver my other repository & services just facing issue with Generic Repository builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).InstancePerLifetimeScope();
At time of using this generic repository I gets following error
Autofac.Core.DependencyResolutionException: An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = CommonService (ReflectionActivator), Services = [MakeTalk.Service.ICommonService], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = Shared, Ownership = OwnedByLifetimeScope ---> An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = Repository
1 (ReflectionActivator), Services = [MakeTalk.Data.Infrastructure.IRepository
1[[MakeTalk.Model.ExhibitionRequestStatus, MakeTalk.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = Shared, Ownership = OwnedByLifetimeScope ---> No constructors on type 'MakeTalk.Data.Infrastructure.Repository1[MakeTalk.Model.ExhibitionRequestStatus]' can be found with the constructor finder 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'. (See inner exception for details.) (See inner exception for details.) ---> Autofac.Core.DependencyResolutionException: An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = Repository
1 (ReflectionActivator), Services = [MakeTalk.Data.Infrastructure.IRepository1[[MakeTalk.Model.ExhibitionRequestStatus, MakeTalk.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = Shared, Ownership = OwnedByLifetimeScope ---> No constructors on type 'MakeTalk.Data.Infrastructure.Repository
1[MakeTalk.Model.ExhibitionRequestStatus]' can be found with the constructor finder 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'. (See inner exception for details.) ---> Autofac.Core.DependencyResolutionException: No constructors on type 'MakeTalk.Data.Infrastructure.Repository1[MakeTalk.Model.ExhibitionRequestStatus]' can be found with the constructor finder 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'. at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable
1 parameters) at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable1 parameters) --- End of inner exception stack trace --- at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable
1 parameters) at Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(Guid id, Func1 creator) at Autofac.Core.Resolving.InstanceLookup.Execute() at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable
1 parameters) at Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate() at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable1 parameters) at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable
1 parameters) --- End of inner exception stack trace --- at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable1 parameters) at Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(Guid id, Func
1 creator) at Autofac.Core.Resolving.InstanceLookup.Execute() at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable1 parameters) at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable
1 parameters) at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable1 parameters, Object& instance) at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable
1 parameters) at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired) at lambda_method(Closure , IServiceProvider , Object[] ) at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass4_0.b__0(ControllerContext controllerContext) at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.g__CreateController|0(ControllerContext controllerContext) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync() at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter() at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync() at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync() at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext) at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
If you look at the error message you can see this
No constructors on type
MakeTalk.Data.Infrastructure.Repository1[MakeTalk.Model.ExhibitionRequestStatus]
can be found with the constructor finderAutofac.Core.Activators.Reflection.DefaultConstructorFinder
.
it means that Autofac can't find a constructor on type Repository<T>
. If you look at this type the constructor is marked as protected
which means Autofac doesn't have access to it.
To fix this error you have to change the constructor to public