Open Closed

Cannot retrieve a repository from DI service collection (proxy is wrapped) #9090


User avatar
0
alexander.nikonov created

I am trying to retrieve repository using a primitive factory. And getting a proxy wrapper class instead:

Unable to cast object of type 'Castle.Proxies.IBasicRepository1Proxy_52' to type 'AbxFileManagers.IFileRepository1[AbxFileManagers.IFileEntity]'.

I do not want to inject all the repositories into class constructor, because there are too many of them. Also I saw the recommendation to disable audit logging for my entities - that would allegedly eliminate proxy creation. I do not want it either, I do want to keep audit logging things.

Interface:

public interface IFileRepository<TFile> : IRepository<TFile, Guid> where TFile : class, IFileEntity

Implementation:

[ExposeServices(typeof(IFileRepository<>))]
public class EfCoreFileRepository<TFile> : EfCoreRepository<CoreDbContext, TFile, Guid>, IFileRepository<TFile> where TFile : class, IFileEntity

Factory:

public class FileRepositoryFactory : IScopedDependency
{
    private readonly IServiceProvider _serviceProvider;

    public FileRepositoryFactory(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public IFileRepository<TFile> GetRepository<TFile>(...) where TFile : class, IFileEntity
    {
        ...

        var repositoryType = typeof(IFileRepository<>).MakeGenericType(entityType);

        return (IFileRepository<TFile>)_serviceProvider.GetRequiredService(repositoryType);
    }
}

One of the classes:

public class FixCharacterLargeObject : FixCharacterLargeObjectEntity, IFileEntity

Its interface:

public interface IFileEntity : IEntity<Guid>, IMayHaveCreatorName, IMayHaveLastModifierName, IHasCreationTime, IHasModificationTime

I use a single generic class EfCoreFileRepository, because all the IFileEntityentities share the same methods, I did not want to duplicate the code. I also tried to make EfCoreFileRepository abstract and inherit from it, but the error is the same.

If this is the best way to accomplish the goal - please let me know (and return the point - I will close the ticket):

    public dynamic GetRepository(AbxFileLocation location, AbxFileType type)
    {
        var repositoryType = typeof(IFileRepository&lt;&gt;).MakeGenericType(AbxFileEntityFactory.GetEntityType(location, type));
    
        var repository = _serviceProvider.GetRequiredService(repositoryType);
    
        if (repository is Castle.DynamicProxy.IProxyTargetAccessor proxyAccessor)
        {
            return proxyAccessor.DynProxyGetTarget(); // Return the real repository implementation
        }
    
        return repository;
    }

2 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    This is the expected behavior, because ABP uses proxies to create interceptors for things like units of work, auditing log.

    Instead, I recommend you use lazy injection.

    See: https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ApplicationService.cs#L57

    They will only be loaded when first used to get better performance.

  • User Avatar
    0
    alexander.nikonov created

    Thank you for the input. I will keep this in mind.

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
Do you need assistance from an ABP expert?
Schedule a Meeting
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v9.3.0-preview. Updated on April 16, 2025, 12:13