Open SPEMoorthy opened 6 years ago
Notes from triage: It's not unreasonable to attempt to resolve these from D.I., so putting it in the backlog for consideration as a future enhancement.
@SPEmoorthy You posted and then deleted a workaround--was there a reason for deleting the workaround that you posted?
@ajcvickers I was trying to Resolve the sevice from DBContext objet. The Service collection returned from DBContext is internel to DBContext's DI Container. I realised that later :-(. So Deleted that workaround. Actuly I am trying to get the Id generated from outside of the application. Id's are maintained in Separate DB. That DB is consumed by Many application. Current project requires to get the generated number from that db. I just tried to get the ID from Custom ValueGenerator. Right Now Managing without DI.
public override int Next(EntityEntry entry)
{
if (entry == null)
{
throw new ArgumentNullException(nameof(entry));
}
//_repository = entry.Context.GetInfrastructure().GetService<ISeqDefinitionRepository>() //Not Working
_repository = new SeqDefinitionRepository((MyDbContext)entry.Context); //Managed Without DI. Now in same db
return _repository .NextValue(1);
}
I hope The Id Generation is not always happening in DB. It May happen in Outside of the application scope. (Docoumt number in Enterprises is globally unique in nature, Separate application is handling that part). If we can tieup the applcation services in ValueGenerator, will be an added advantage.
@SPEmoorthy Thanks for the additional info.
It would be nice to have that feature in EF Core. I got some problem with persisting dates based on the user timezone which is a scoped service. Really need some DI for ValueGenerator
and ValueConverter
.
Another use case for this feature is getting a value of currently logged in user based on e.g. IHttpContextAccessor
FYI, I've been able to access a service registered for scope using
var userProvider = entry.Context.GetService<ITeamTunerUserProvider>();
It worked for me the same way @taconaut was proposing. You can't include the repository in the constructor of your custom value generator since the injectable type is not listed in the registered services for the service provider. Below are the classes I used to make it work.
UserGenerator.txt IUserProvider.txt TestDbContext.txt Program.txt
My code
services.TryAddSingleton<IMyLongIDGenerator, MyLongIDGenerator>();
public class MylongValueGenerator : ValueGenerator<long>
{
//......
public override long Next([NotNull] EntityEntry entry)
{
if (entry == null)
{
throw new ArgumentNullException(nameof(entry));
}
var gen = entry.Context.GetService<IMyLongIDGenerator>();
return gen.NextValue();
}
}
// for some single DbContext ID generator
services.AddDbContext<DBContext>(options =>{
options.ReplaceService<IValueGeneratorSelector, MyValueGeneratorSelector>();
};
//Or for global
//services.TryAddSingleton<IValueGeneratorSelector, MyValueGeneratorSelector>();
public class MyValueGeneratorSelector : ValueGeneratorSelector
{
//......
public override ValueGenerator Create(IProperty property, IEntityType entityType)
{
//......
if (property.ValueGenerated != ValueGenerated.Never)
{
if (propertyType == typeof(long))
{
return new MylongValueGenerator(false);
}
//......
}
}
}
it work for EF Core version: 3.0/3.0.1
Hi, I am trying to implement a Custom Value generator. Whchi is getting number from other DB.
My code is as follows.
I am getting following Error
Cannot create instance of value generator type 'MyValueGenerator'. Ensure that the type is instantiable and has a parameterless constructor, or use the overload of HasValueGenerator that accepts a delegate. No parameterless constructor defined for this object.
Requesting to guide met to get the instance of the service in custom ValueGenerator Class.
Further technical details
EF Core version: 2.0 Database Provider: Microsoft.EntityFrameworkCore.SqlServer Operating system: Visual Studio 2017
Thanks & Regards, Easwar