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.IBasicRepository
1Proxy_52' to type 'AbxFileManagers.IFileRepository
1[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 IFileEntity
entities 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<>).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)
-
0
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.
They will only be loaded when first used to get better performance.
-
0
Thank you for the input. I will keep this in mind.