Reputation: 629
I would like to use Value Conversions. https://learn.microsoft.com/en-us/ef/core/modeling/value-conversions
When using it, I would like to add some config value. Sample usage is like this. (Unfortunately, this code does not run, but I want to write the code like this)
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<Rider>()
.Property(e => e.Mount)
.HasConversion(
v => SomeFunction.Encrypt(v, IOptional<SomeConfig> config),
v => SomeFunction.Decrypt(v, IOptional<SomeConfig> config));
}
More specifically, I would like to pass encrypt/decrypt key to the Converter functions. Is there any way to use DI config value in Value Conversions?
Upvotes: 3
Views: 693
Reputation: 2282
I know this is a late answer but for those with the same question. You may use injection, and retrieve the injected object using DatabaseFacade
which implements IInfrastructure<IServiceProvider>
. In your scenario, declare an interface for your Encryption/Decryption operations:
public interface ICryptoProvider
{
string Encrypt(string plainText, string key, string iv);
string DesDecrypt(string plainText, string key, string iv);
}
Implement it:
public interface CryptoProvider: ICryptoProvider
{
public string Encrypt(string plainText, string key, string iv){...}
public string DesDecrypt(string plainText, string key, string iv){...}
}
Add to the IserviceCollection:
services.AddSingleton<ICryptoProvider, CryptoProvider>();
Fetch and use that encryption mechanism In the model builder:
protected override void OnModelCreating(Microsoft.EntityFrameworkCore.ModelBuilder builder)
{
var cryptoProvider = Database.GetService<ICryptoProvider>();
var config = Database.GetService<IOptional<SomeConfig>>().Value;
modelBuilder
.Entity<Rider>()
.Property(e => e.Mount)
.HasConversion(
v => cryptoProvider.Encrypt(v, config),
v => cryptoProvider.Decrypt(v, config));
}
Or you can pass it into the IEntityTypeConfiguration<>
:
protected override void OnModelCreating(Microsoft.EntityFrameworkCore.ModelBuilder builder)
{
var cryptoProvider = Database.GetService<ICryptoProvider>();
var config = Database.GetService<IOptional<SomeConfig>>().Value;
// You cannot pass an argument using ApplyConfigurationsFromAssembly().
// Hence, manually declare those who need injection (without default parameterless construstor).
builder.ApplyConfiguration(new RiderModelBuilder(cryptoProvider, config));
}
public class RiderModelBuilder : IEntityTypeConfiguration<Rider>
{
private readonly ICryptoProvider cryptoProvider;
SomeConfig config;
public RiderModelBuilder(ICryptoProvider cryptoProvider, SomeConfig config)
{
this.cryptoProvider = cryptoProvider;
this.config = config;
}
public void Configure(EntityTypeBuilder<User> builder)
{
builder
.Property(e => e.Mount)
.HasConversion(
v => cryptoProvider.Encrypt(v, config),
v => cryptoProvider.Decrypt(v, config));
}
}
Upvotes: 0