I am building an ASP.NET Core WebAPI application, it is working perfectly fine with the below setup
public void ConfigureServices(IServiceCollection services)
{
var settings = Configuration.Get<Settings>();
CosmosClient client = new CosmosClient(settings.CosmosDB.EndpointUrl, settings.CosmosDB.PrimaryKey);
CosmosDbContainerFactory cosmosDbClientFactory = new CosmosDbContainerFactory(client, settings.CosmosDB.DatabaseName, settings.CosmosDB.Containers);
services.AddSingleton<ICosmosDbContainerFactory>(cosmosDbClientFactory);
services.AddTransient<IFamilyService, FamilyService>();
services.AddTransient<IFamilyRepository, FamilyRepository>();
services.AddControllers();
}
But while trying to replace the manual service registration with Scrutor Scan, like mentioned below
public void ConfigureServices(IServiceCollection services)
{
var settings = Configuration.Get<Settings>();
CosmosClient client = new CosmosClient(settings.CosmosDB.EndpointUrl, settings.CosmosDB.PrimaryKey);
CosmosDbContainerFactory cosmosDbClientFactory = new CosmosDbContainerFactory(client, settings.CosmosDB.DatabaseName, settings.CosmosDB.Containers);
services.AddSingleton<ICosmosDbContainerFactory>(cosmosDbClientFactory);
services.Scan(s => s
.FromAssembliesOf(typeof(IApiAssemblyMarker))
.AddClasses(false)
.UsingRegistrationStrategy(RegistrationStrategy.Append)
.AsImplementedInterfaces()
.WithTransientLifetime()
);
services.AddControllers();
}
I am getting the following error
Error while validating the service descriptor 'ServiceType: FBAuthDemoAPI.Services.Contract.IFamilyService Lifetime: Transient ImplementationType: FBAuthDemoAPI.Services.Implementation.FamilyService': Unable to resolve service for type 'Microsoft.Azure.Cosmos.CosmosClient' while attempting to activate 'FBAuthDemoAPI.CosmosDBFactory.CosmosDbContainerFactory'.
public interface IFamilyService
{
}
public class FamilyService : IFamilyService
{
private readonly IFamilyRepository _familyRepository;
public FamilyService(IFamilyRepository familyRepository)
{
this._familyRepository = familyRepository;
}
}
public interface IGenericRepository<T> where T : class
{
}
public abstract class GenericRepository<T> : IGenericRepository<T> where T : Entity
{
private readonly Container _container;
private readonly ICosmosDbContainerFactory _cosmosDbContainerFactory;
public abstract string DatabaseName { get; }
public abstract string ContainerName { get; }
protected GenericRepository(ICosmosDbContainerFactory cosmosDbContainerFactory)
{
this._cosmosDbContainerFactory = cosmosDbContainerFactory ?? throw new ArgumentNullException(nameof(ICosmosDbContainerFactory));
this._container = this._cosmosDbContainerFactory.GetContainer(ContainerName)._container;
}
}
public interface IFamilyRepository : IGenericRepository<Family>
{
}
public class FamilyRepository : GenericRepository<Family>, IFamilyRepository
{
public override string DatabaseName => "FamilyDB";
public override string ContainerName => "Family";
public FamilyRepository(ICosmosDbContainerFactory factory) :
base(factory)
{
}
}
What is the issue and How do I fix this?
Update:: Having registered the classes shown below, it started working, but I'm not understanding why it failed when registering with the Single instance like mentioned above, Is it due to the limitation of Scrutor library?
var cosmosDBSettings = new CosmosDBSettings();
configration.Bind(CosmosDBSettings.SectionName, cosmosDBSettings);
services.AddSingleton(Microsoft.Extensions.Options.Options.Create(cosmosDBSettings));
services.Scan(scan => scan
.FromAssembliesOf(typeof(IApiAssemblyMarker))
.AddClasses(classes => classes.AssignableTo<ICosmosDbContainerFactory>()) // Filter classes
.AsSelfWithInterfaces()
.WithSingletonLifetime()
.AddClasses(x => x.AssignableTo(typeof(IGenericRepository<>))) // Can close generic types
.AsMatchingInterface()
.WithScopedLifetime()
.AddClasses(x => x.AssignableTo(typeof(IFamilyService))) // Can close generic types
.AsMatchingInterface()
.WithScopedLifetime());