Skip to content

Can't inject IRepository<XXXXX, int>(but RepositoryFactory and ConfigurationBasedRepository works fine) #235

Description

@jhuerta

Hi,

My first post here and I just discovered SharpRepository and trying to use it in our projects.

Sorry for the lengthy post, I am trying to provide as much details as possible on all the information I've gathered.

I'm using .Net Core 2.2 and I have followed the example of SharpRepository.Samples.CoreMvc. I have changed the .Net version of that code and I made it use 2.2 (it is using 2.1 when download from GitHub). In that project, using .Net Core 2.2 it is possible to inject properly ConfigurationBasedRepository and IRepository<XXXX, int>.

My issue is that I'm having some problems to inject into my services a repository of type "IRepository<AppUser, int>". However a ConfigurationBasedRepository works fine.

If I inject a UserRepository, the injector works well:

	public class UserRepository : ConfigurationBasedRepository<AppUser, int> {
	public UserRepository(ISharpRepositoryConfiguration configuration, string repositoryName = null) : base(configuration, repositoryName){}
	}
	public UserService(ApplicationDbContext context, ILogger<UserService> logger){
	           _userRepository = userRepository;
	}

Also, when I call directly the RepositoryFactory, I'm able to build a repository of the type I'm interested. The code below works fine as well:

public UserService(ApplicationDbContext context, ILogger<UserService> logger)
{
    _context = context;
    _logger = logger;

    var dbContext = _context;
    var config = new SharpRepositoryConfiguration();
    var coreRepoconfig = new EfCoreRepositoryConfiguration("default", dbContext);
    coreRepoconfig.Attributes.Add("dbContextType", "Base.DataAccessLayer.Identity.ApplicationDbContext, Base.DataAccessLayer");
    config.AddRepository(coreRepoconfig);
    var repos = RepositoryFactory.GetInstance<AppUser, int>(config);
}

HOWEVER, if I want to inject the Repository, it crashes and it throws an exception:

private IRepository<AppUser, int> _userRepository;

    public UserService(ApplicationDbContext context, ILogger<UserService> logger, IRepository<AppUser, int> userRepository)
    {
        _userRepository = userRepository;
        _context = context;
        _logger = logger;
    }
2019-05-31 15:46:57.500 +02:00 [{ IpAddress: "0.0.0.1" }] [Error] [] Connection id ""0HLN5PPF1NBND"", Request id ""0HLN5PPF1NBND:00000003"": An unhandled exception was thrown by the application.
System.InvalidOperationException: Unable to resolve service for type 'SharpRepository.Repository.IRepository`2[Base.DataAccessLayer.Models.AppUser,System.Int32]' while attempting to activate 'Base.BusinessLayer.UserService.UserService'.
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Type serviceType, Type implementationType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.CreateServiceAccessor(Type serviceType)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   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.<CreateActivator>b__0(ControllerContext controllerContext)
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.<CreateControllerFactory>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.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Base.WebServices.Middlewares.JwtTokenMiddleware.Invoke(HttpContext context) in E:\SampleCode\Base.Services\Middlewares\JwtTokenMiddleware.cs:line 41
   at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.InvokeCore(HttpContext context)
   at Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

This is the code in my startup.cs:

      public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            // Add framework services.
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(Configuration["ConnectionString"],
                    sqlOptions =>
                    {
                        sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name);
                        //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency 
                        sqlOptions.EnableRetryOnFailure(15, TimeSpan.FromSeconds(30), null);
                        sqlOptions.MigrationsAssembly("Base.DataAccessLayer");
                    }), ServiceLifetime.Transient);

            services.AddIdentity<AppUser, AppRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();

            // configure DI for application services
            services.AddScoped<IUserService, UserService>();

            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();


            services.AddTransient<UserRepository>(
            r => new UserRepository(
            	RepositoryFactory.BuildSharpRepositoryConfiguation(Configuration.GetSection("sharpRepository")), "efCore"
            ));

            // Adding Sharp Repository
            services.UseSharpRepository(Configuration.GetSection("sharpRepository"), "efCore"); // for Ef Core

            }

And finally, this is my appsettings.json:

  "sharpRepository": {
    "repositories": {
      "default": "efCore",
      "efCore": {
        "factory": "SharpRepository.EfCoreRepository.EfCoreConfigRepositoryFactory, SharpRepository.EfCoreRepository",
        "dbContextType": "Base.DataAccessLayer.Identity.ApplicationDbContext, Base.DataAccessLayer",
        "cachingStrategy": "none",
        "cachingProvider": "noCachingProvider"
      }
    },
    "cachingProviders": {
      "default": "inMemoryProvider",
      "inMemoryProvider": {
        "factory": "SharpRepository.Repository.Caching.InMemoryConfigCachingProviderFactory, SharpRepository.Repository"
      },
      "noCachingProvider": {
        "factory": "SharpRepository.Repository.Caching.NoCachingConfigCachingProviderFactory, SharpRepository.Repository"
      }
    },
    "cachingStrategies": {
      "default": "standard",
      "standard": {
        "factory": "SharpRepository.Repository.Caching.StandardConfigCachingStrategyFactory, SharpRepository.Repository",
        "generational": "true",
        "writeThrough": "false"
      },
      "timeout": {
        "factory": "SharpRepository.Repository.Caching.TimeoutConfigCachingStrategyFactory, SharpRepository.Repository",
        "timeout": "200"
      },
      "none": {
        "factory": "SharpRepository.Repository.Caching.NoCachingConfigCachingStrategyFactory, SharpRepository.Repository"
      }
    }
  }

Any advice on how to debug/fix this issue?

Thanks,

Juan

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions